diff options
author | Michał Muskała <[email protected]> | 2018-08-05 00:15:33 +0200 |
---|---|---|
committer | Michał Muskała <[email protected]> | 2018-08-05 00:15:33 +0200 |
commit | 44e3810be19f58f0348cd2c38de9bb1b2e9d4c6e (patch) | |
tree | 5e3dcd2702f4ffb400e4164bf377c42bd78789c7 /lib/compiler/src | |
parent | 40de8cc4452dfdc5d390c93860870d4bf4605eb9 (diff) | |
download | otp-44e3810be19f58f0348cd2c38de9bb1b2e9d4c6e.tar.gz otp-44e3810be19f58f0348cd2c38de9bb1b2e9d4c6e.tar.bz2 otp-44e3810be19f58f0348cd2c38de9bb1b2e9d4c6e.zip |
Rewrite erlang:get_stacktrace calls to primop when safe
This allows taking advantage of further optimisations, like the
raw_raise instruction for code that can't upgrade (yet) to the
new stacktrace syntax for compatibility reasons.
The rewrite is only done when it is safe - when the get_stacktrace
call is the very first thing the handler does.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 0aa58a46e4..f5f652a954 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -480,9 +480,21 @@ expr(#c_try{anno=A,arg=E0,vars=Vs0,body=B0,evars=Evs0,handler=H0}=Try, _, Sub0) false -> {Evs1,Sub2} = var_list(Evs0, Sub0), H1 = body(H0, value, Sub2), - Try#c_try{arg=E1,vars=Vs1,body=B1,evars=Evs1,handler=H1} + H2 = opt_try_handler(H1, lists:last(Evs1)), + Try#c_try{arg=E1,vars=Vs1,body=B1,evars=Evs1,handler=H2} end. +%% Attempts to convert old erlang:get_stacktrace/0 calls into the new +%% three-argument catch, with possibility of further optimisations. +opt_try_handler(#c_call{anno=A,module=#c_literal{val=erlang},name=#c_literal{val=get_stacktrace},args=[]}, Var) -> + #c_primop{anno=A,name=#c_literal{val=build_stacktrace},args=[Var]}; +opt_try_handler(#c_case{clauses=Cs0} = Case, Var) -> + Cs = [C#c_clause{body=opt_try_handler(B, Var)} || #c_clause{body=B} = C <- Cs0], + Case#c_case{clauses=Cs}; +opt_try_handler(#c_let{arg=Arg} = Let, Var) -> + Let#c_let{arg=opt_try_handler(Arg, Var)}; +opt_try_handler(X, _) -> X. + expr_list(Es, Ctxt, Sub) -> [expr(E, Ctxt, Sub) || E <- Es]. |