aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/receive_SUITE_data
diff options
context:
space:
mode:
authorAnthony Ramine <[email protected]>2013-04-09 22:20:00 +0200
committerFredrik Gustafsson <[email protected]>2013-04-19 11:47:00 +0200
commit8aa46fd40d759de2d6a13fbafb5e88cdf1047220 (patch)
treefe67482bb0901c12b94f4db547afe20a846127ef /lib/compiler/test/receive_SUITE_data
parent4e220f07593c80ba20c6ce968ae608f5363ef75b (diff)
downloadotp-8aa46fd40d759de2d6a13fbafb5e88cdf1047220.tar.gz
otp-8aa46fd40d759de2d6a13fbafb5e88cdf1047220.tar.bz2
otp-8aa46fd40d759de2d6a13fbafb5e88cdf1047220.zip
Use a set to store ref registers in beam_receive
In some circumstances, as when inlining code, when some optimization passes are disabled or with hand-written but semantically correct Core Erlang or BEAM assembly, a fresh reference may be live in more than one register: ... {allocate_zero,2,2}. ... {call_ext,0,{extfunc,erlang,make_ref,0}}. % Ref in [x0] ... {move,{x,0},{y,0}}. % Ref in [x0,y0] {move,{y,1},{x,0}}. % Ref in [y0] ... {move,{y,0},{x,0}}. % Ref in [x0,y0] {move,{x,0},{y,1}}. % Ref in [x0,y0,y1] {label,5}. {loop_rec,{f,6},{x,0}}. % Ref in [y0,y1] ... {loop_rec_end,{f,5}}. {label,6}. {wait,{f,5}}. ... Pass beam_receive expects a single live register for the ref when it encounters the loop_rec instruction and crashes with the following reason: $ erlc t.S ... crash reason: {{case_clause, {'EXIT', {{case_clause,[{y,1},{y,0}]}, [{beam_receive,opt_recv,5, [{file,"beam_receive.erl"},{line,154}]}, ...]}}}, ...} This commit teaches beam_receive how to use a set of registers instead of a single one when tracking fresh references, thus avoiding the crash.
Diffstat (limited to 'lib/compiler/test/receive_SUITE_data')
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_14.S71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_14.S b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_14.S
new file mode 100644
index 0000000000..fd14228135
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_14.S
@@ -0,0 +1,71 @@
+{module, yes_14}. %% version = 0
+
+{exports, [{f,2},{module_info,0},{module_info,1},{yes_14,0}]}.
+
+{attributes, []}.
+
+{labels, 12}.
+
+
+{function, yes_14, 0, 2}.
+ {label,1}.
+ {func_info,{atom,yes_14},{atom,yes_14},0}.
+ {label,2}.
+ {move,{atom,ok},{x,0}}.
+ return.
+
+
+{function, f, 2, 4}.
+ {label,3}.
+ {func_info,{atom,yes_14},{atom,f},2}.
+ {label,4}.
+ {allocate_heap,2,3,2}.
+ {move,{x,0},{y,1}}.
+ {put_tuple,2,{y,0}}.
+ {put,{atom,data}}.
+ {put,{x,1}}.
+ {call_ext,0,{extfunc,erlang,make_ref,0}}. % Ref in [x0]
+ {test_heap,4,1}.
+ {put_tuple,3,{x,1}}.
+ {put,{atom,request}}.
+ {put,{x,0}}.
+ {put,{y,0}}.
+ {move,{x,0},{y,0}}. % Ref in [x0,y0]
+ {move,{y,1},{x,0}}. % Ref in [y0]
+ {kill,{y,1}}.
+ send.
+ {move,{y,0},{x,0}}. % Ref in [x0,y0]
+ {move,{x,0},{y,1}}. % Ref in [x0,y0,y1]
+ {label,5}.
+ {loop_rec,{f,7},{x,0}}. % Ref in [y0,y1]
+ {test,is_tuple,{f,6},[{x,0}]}.
+ {test,test_arity,{f,6},[{x,0},2]}.
+ {get_tuple_element,{x,0},0,{x,1}}.
+ {get_tuple_element,{x,0},1,{x,2}}.
+ {test,is_eq_exact,{f,6},[{x,1},{atom,reply}]}.
+ {test,is_eq_exact,{f,6},[{x,2},{y,1}]}.
+ remove_message.
+ {move,{atom,ok},{x,0}}.
+ {deallocate,2}.
+ return.
+ {label,6}.
+ {loop_rec_end,{f,5}}.
+ {label,7}.
+ {wait,{f,5}}.
+
+
+{function, module_info, 0, 9}.
+ {label,8}.
+ {func_info,{atom,yes_14},{atom,module_info},0}.
+ {label,9}.
+ {move,{atom,yes_14},{x,0}}.
+ {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
+
+
+{function, module_info, 1, 11}.
+ {label,10}.
+ {func_info,{atom,yes_14},{atom,module_info},1}.
+ {label,11}.
+ {move,{x,0},{x,1}}.
+ {move,{atom,yes_14},{x,0}}.
+ {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.