diff options
author | Björn Gustavsson <[email protected]> | 2011-08-25 11:25:29 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-08-25 11:25:29 +0200 |
commit | 142700357d3c76aa4c916f0cd5f915a947cbf94c (patch) | |
tree | 3af82388a86d708b3185fc142013a459c0201652 /lib/compiler/src/beam_block.erl | |
parent | 756a93ca2064b9e0eba3d82a7bd37aeae0f39be1 (diff) | |
parent | 26cceb7a0718182e74083b4ad044985e8f624ee2 (diff) | |
download | otp-142700357d3c76aa4c916f0cd5f915a947cbf94c.tar.gz otp-142700357d3c76aa4c916f0cd5f915a947cbf94c.tar.bz2 otp-142700357d3c76aa4c916f0cd5f915a947cbf94c.zip |
Merge branch 'bjorn/line-numbers-in-exceptions/OTP-9468' into major
* bjorn/line-numbers-in-exceptions/OTP-9468: (51 commits)
debugger: By default, only save non-tail-recursive calls
debugger: Add line_number_SUITE
debugger: Include line numbers in exceptions
Update examples in the documentation to include line numbers
Update documentation for erlang:raise/3 and erlang:get_stacktrace/0
beam_lib: Retain the "Line" chunk when stripping BEAM files
erl: Add +L to suppress loading of line number information
compiler: Add no_line_info for suppressing line/1 instructions
exception_SUITE: Test line numbers in exceptions
common_test: Use line numbers in exceptions
common_test tests: Don't do detailed testing of the stack backtrace
test_server: Refactor init_per_testcase/3 into two functions
Implement process_info(Pid, current_{location,stacktrace})
beam_emu: Factor out saving of stack trace from save_stacktrace()
compiler: Don't create filenames starting with "./"
ops.tab: Remove line instructions before tail-recursive calls
Lookup and include filenames and line numbers in exceptions
Fix decrement of continuation pointers
Refactor building of the exception stacktrace
BEAM loader: Load the line table
...
Diffstat (limited to 'lib/compiler/src/beam_block.erl')
-rw-r--r-- | lib/compiler/src/beam_block.erl | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index c45874597a..432d1e7eea 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -36,13 +36,14 @@ function({function,Name,Arity,CLabel,Is0}, Lc0) -> %% Collect basic blocks and optimize them. Is2 = blockify(Is1), - Is3 = move_allocates(Is2), - Is4 = beam_utils:live_opt(Is3), - Is5 = opt_blocks(Is4), - Is6 = beam_utils:delete_live_annos(Is5), + Is3 = embed_lines(Is2), + Is4 = move_allocates(Is3), + Is5 = beam_utils:live_opt(Is4), + Is6 = opt_blocks(Is5), + Is7 = beam_utils:delete_live_annos(Is6), %% Optimize bit syntax. - {Is,Lc} = bsm_opt(Is6, Lc0), + {Is,Lc} = bsm_opt(Is7, Lc0), %% Done. {{function,Name,Arity,CLabel,Is},Lc} @@ -148,6 +149,24 @@ collect(remove_message) -> {set,[],[],remove_message}; collect({'catch',R,L}) -> {set,[R],[],{'catch',L}}; collect(_) -> error. +%% embed_lines([Instruction]) -> [Instruction] +%% Combine blocks that would be split by line/1 instructions. +%% Also move a line instruction before a block into the block, +%% but leave the line/1 instruction after a block outside. + +embed_lines(Is) -> + embed_lines(reverse(Is), []). + +embed_lines([{block,B2},{line,_}=Line,{block,B1}|T], Acc) -> + B = {block,B1++[{set,[],[],Line}]++B2}, + embed_lines([B|T], Acc); +embed_lines([{block,B1},{line,_}=Line|T], Acc) -> + B = {block,[{set,[],[],Line}|B1]}, + embed_lines([B|T], Acc); +embed_lines([I|Is], Acc) -> + embed_lines(Is, [I|Acc]); +embed_lines([], Acc) -> Acc. + opt_blocks([{block,Bl0}|Is]) -> %% The live annotation at the beginning is not useful. [{'%live',_}|Bl] = Bl0, @@ -225,10 +244,12 @@ opt([{set,[Dst],As,{bif,Bif,Fail}}=I1, RevBif -> [{set,[Dst],As,{bif,RevBif,Fail}}|opt(Is)] end; opt([{set,[X],[X],move}|Is]) -> opt(Is); -opt([{set,[D1],[{integer,Idx1},Reg],{bif,element,{f,0}}}=I1, +opt([{set,_,_,{line,_}}=Line1, + {set,[D1],[{integer,Idx1},Reg],{bif,element,{f,0}}}=I1, + {set,_,_,{line,_}}=Line2, {set,[D2],[{integer,Idx2},Reg],{bif,element,{f,0}}}=I2|Is]) when Idx1 < Idx2, D1 =/= D2, D1 =/= Reg, D2 =/= Reg -> - opt([I2,I1|Is]); + opt([Line2,I2,Line1,I1|Is]); opt([{set,Ds0,Ss,Op}|Is0]) -> {Ds,Is} = opt_moves(Ds0, Is0), [{set,Ds,Ss,Op}|opt(Is)]; |