File 3541-stdlib-optimise-gen_statem-by-caching-callback-funct.patch of Package erlang
From 9617355c346e263a715ce082860ba2e4c15a6c53 Mon Sep 17 00:00:00 2001
From: Nelson Vides <videsnelson@gmail.com>
Date: Mon, 19 Jun 2023 17:46:47 +0200
Subject: [PATCH 1/2] stdlib: optimise gen_statem by caching callback function
Inspired by f0874ffb4af5af284fa3f139b2421b4ee93a5659, we want to cache
`Mod:handle_event/4` when such is the configured callback mode, to make calling
this function faster for state machines.
---
lib/stdlib/src/gen_statem.erl | 39 +++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 849bf45561..e1181aae04 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -127,6 +127,13 @@
-type callback_mode_result() ::
callback_mode() | [callback_mode() | state_enter()].
+
+-type handle_event_enter_fun() :: fun(('enter', OldState :: state(), CurrentState, data()) ->
+ state_enter_result(CurrentState)).
+-type handle_event_event_fun() :: fun((event_type(), event_content(), state(), data()) ->
+ event_handler_result(state())).
+-type handle_event_fun() :: handle_event_enter_fun() | handle_event_event_fun().
+-type callback_mode_internal() :: 'state_functions' | {'handle_event_function', handle_event_fun()}.
-type callback_mode() :: 'state_functions' | 'handle_event_function'.
-type state_enter() :: 'state_enter'.
@@ -415,13 +422,13 @@
%% - return true if the value is of the type, false otherwise
-compile(
{inline,
- [callback_mode/1, state_enter/1,
+ [callback_mode_internal/2, state_enter/1,
event_type/1, from/1, timeout_event_type/1]}).
%%
-callback_mode(CallbackMode) ->
+callback_mode_internal(CallbackMode, CallbackModule) ->
case CallbackMode of
- state_functions -> true;
- handle_event_function -> true;
+ state_functions -> {true, state_functions};
+ handle_event_function -> {true, {handle_event_function, fun CallbackModule:handle_event/4}};
_ -> false
end.
%%
@@ -492,7 +499,7 @@ event_type(Type) ->
end).
-record(params,
- {callback_mode = state_functions :: callback_mode(),
+ {callback_mode = state_functions :: callback_mode_internal(),
state_enter = false :: boolean(),
parent :: pid(),
modules = [?MODULE] :: nonempty_list(module()),
@@ -1375,8 +1382,8 @@ loop_state_callback(
case CallbackMode of
state_functions ->
Module:State(Type, Content, Data);
- handle_event_function ->
- Module:handle_event(Type, Content, State, Data)
+ {handle_event_function, HandleEvent} ->
+ HandleEvent(Type, Content, State, Data)
end
of
Result ->
@@ -2471,19 +2478,19 @@ callback_mode_result(P, Modules, CallbackModeResult) ->
listify(CallbackModeResult), undefined, false).
%%
callback_mode_result(
- P, Modules, CallbackModeResult,
- [H|T], CallbackMode, StateEnter) ->
- case callback_mode(H) of
- true ->
+ P, [Module | _] = Modules, CallbackModeResult,
+ [H|T], CurrentCallbackMode, StateEnter) ->
+ case callback_mode_internal(H, Module) of
+ {true, InternalCallbackMode} ->
callback_mode_result(
P, Modules, CallbackModeResult,
- T, H, StateEnter);
+ T, InternalCallbackMode, StateEnter);
false ->
case state_enter(H) of
true ->
callback_mode_result(
P, Modules, CallbackModeResult,
- T, CallbackMode, true);
+ T, CurrentCallbackMode, true);
false ->
{error,
{bad_return_from_callback_mode, CallbackModeResult},
@@ -2492,16 +2499,16 @@ callback_mode_result(
end;
callback_mode_result(
P, Modules, CallbackModeResult,
- [], CallbackMode, StateEnter) ->
+ [], CurrentCallbackMode, StateEnter) ->
if
- CallbackMode =:= undefined ->
+ CurrentCallbackMode =:= undefined ->
{error,
{bad_return_from_callback_mode, CallbackModeResult},
?STACKTRACE()};
true ->
P#params{
modules = Modules,
- callback_mode = CallbackMode,
+ callback_mode = CurrentCallbackMode,
state_enter = StateEnter}
end.
--
2.35.3