aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_utils.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-11-28 07:28:25 +0100
committerBjörn Gustavsson <[email protected]>2018-01-22 14:23:52 +0100
commit9b0122b65bdcafbae2a3cfd3299903da0948acab (patch)
tree59405671dad4d8240978faaf4ea8e3dcdff289b5 /lib/compiler/src/beam_utils.erl
parentb7ff9c0d76372f16d14ecaac04c6fbbbadaf9435 (diff)
downloadotp-9b0122b65bdcafbae2a3cfd3299903da0948acab.tar.gz
otp-9b0122b65bdcafbae2a3cfd3299903da0948acab.tar.bz2
otp-9b0122b65bdcafbae2a3cfd3299903da0948acab.zip
Don't build a stacktrace if it's only passed to erlang:raise/3
Consider the following function: function({function,Name,Arity,CLabel,Is0}, Lc0) -> try %% Optimize the code for the function. catch Class:Error:Stack -> io:format("Function: ~w/~w\n", [Name,Arity]), erlang:raise(Class, Error, Stack) end. The stacktrace is retrieved, but it is only used in the call to erlang:raise/3. There is no need to build a stacktrace in this function. We can avoid the building if we introduce an instruction called raw_raise/3 that works exactly like the erlang:raise/3 BIF except that its third argument must be a raw stacktrace.
Diffstat (limited to 'lib/compiler/src/beam_utils.erl')
-rw-r--r--lib/compiler/src/beam_utils.erl4
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 901588ee3b..5333925589 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -871,6 +871,8 @@ live_opt([{block,Bl0}|Is], Regs0, D, Acc) ->
live_opt(Is, Regs, D, [{block,[Live|Bl]}|Acc]);
live_opt([build_stacktrace=I|Is], _, D, Acc) ->
live_opt(Is, live_call(1), D, [I|Acc]);
+live_opt([raw_raise=I|Is], _, D, Acc) ->
+ live_opt(Is, live_call(3), D, [I|Acc]);
live_opt([{label,L}=I|Is], Regs, D0, Acc) ->
D = gb_trees:insert(L, Regs, D0),
live_opt(Is, Regs, D, [I|Acc]);
@@ -1142,6 +1144,8 @@ defs([{move,_,Dst}=I|Is], Regs0, D) ->
defs([{put_map,{f,Fail},_,_,Dst,_,_}=I|Is], Regs0, D) ->
Regs = def_regs([Dst], Regs0),
[I|defs(Is, Regs, update_regs(Fail, Regs0, D))];
+defs([raw_raise=I|Is], _Regs, D) ->
+ [I|defs(Is, 1, D)];
defs([return=I|Is], _Regs, D) ->
[I|defs_unreachable(Is, D)];
defs([{select,_,_Src,Fail,List}=I|Is], Regs, D0) ->