Age | Commit message (Collapse) | Author |
|
The live optimization in beam_utils:live_opt/4 did not take into
account that the wait/1 instruction *never* falls through to
the next instruction (it has the same effect on the control flow
as the jump/1 instruction).
|
|
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.
|
|
|
|
Commit c4375a62cfaabfd8de757f59714623ba1a8cb915 added a parallel
group, but incorrectly, so no test cases at all were run in
receive_SUITE.
|
|
Run testcases in parallel will make the test suite run slightly
faster. Another reason for this change is that we want more testing
of parallel testcase support in common_test.
|
|
In 3d0f4a3085f11389e5b22d10f96f0cbf08c9337f (an update to conform
with common_test), in all test_lib:recompile(?MODULE) calls, ?MODULE
was changed to the actual name of the module. That would cause
test_lib:recompile/1 to compile the module with the incorrect
compiler options in cloned modules such as record_no_opt_SUITE,
causing worse coverage.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Moving of allocation instructions upwards in the instruction
stream (in order to enable further optimizations) in beam_block,
is implemented with the assumption that if a register {x,X}
contains a valid term, then all other x register with lower
numbers than X also contain valid terms. That assumption is
true after code generation.
The beam_utils:live_opt/1 optimization, however, may invalidate
that assumption. For instance, if a receive statement exports a
variable that is used, but the return value of the receive statement
is not used, then {x,1} but not {x,0} contains a valid term at the
end of the receive statement. If the receive statement is
followed by
{bif,self,{f,0},[],{x,0}}.
{test_heap,NumberOfWords,2}.
moving the allocation upwards will produce
{test_heap,NumberOfWords,2}.
{bif,self,{f,0},[],{x,0}}.
which will cause the beam_validator pass to scream loudly that
{x,0} is not live at the test_heap instruction.
Fix the problem by doing the optimizations in reverse order.
Reported-by: Jim Engquist
|
|
* bg/opt-receive:
Test that gen_server:call/2,3 are fast even with a huge message queue
erts: Add tests for the receive optimization
Update primary bootstrap
erts: Implement recv_mark/1 and recv_set/1 for real
compiler tests: Cover the error handling code in beam_receive
compiler test: Test optimization of receive statements
Optimize selective receives in the presence of a large message queue
Introduce the new recv_mark/1 and recv_mark/1 instructions
Compile tests that communicate with R12 nodes with the r12 option
Move p_run/2 to test_lib
gen: Inline wait_resp_mon/2 to help the compiler optimize
OTP-8623 bg/opt-receive
reveive statements that can only read out a newly created reference are now
specially optimized so that it will execute in constant time regardless of
the number of messages in the receive queue for the process. That
optimization will benefit calls to gen_server:call(). (See gen:do_call/4
for an example of a receive statement that will be optimized.)
|
|
We don't attempt to run the generated code, but use beam_disasm
and check for the presence or absence (as appropriate) of the
recv_mark/1 and recv_set/1 instructions.
|
|
|