Age | Commit message (Collapse) | Author |
|
* bjorn/compiler/fix-compiler-crash/OTP-11119:
compiler: Correct liveness optimization for wait/1
|
|
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).
|
|
The clause was formerly commented-out because at this point in the code,
no bs_put_string instruction has been generated yet when compiling from
Erlang.
If an Erlang module is compiled to BEAM assembly and the result contains
a bs_put_string instruction, the output can't be compiled to binary
anymore and the compiler crashes with the following error:
$ erlc prs.S
Function: compress/1
prs.S:none: internal error in beam_block;
crash reason: {{case_clause,
{'EXIT',
{function_clause,
[{beam_utils,live_opt,
[[{bs_put_string,1,{string,[0]}},
{bs_init,
{f,0},
{bs_append,0,8,{field_flags,[]}},
0,
[{integer,8},{x,0}],
{x,1}},
{label,2}],
2,
{1,{1,1,nil,nil}},
[{block,
[{'%live',2},
{set,[{x,0}],[{x,1}],move},
{'%live',1}]},
return]],
[{file,"beam_utils.erl"},{line,639}]},
{beam_utils,live_opt,1,
[{file,"beam_utils.erl"},{line,205}]},
{beam_block,function,2,
[{file,"beam_block.erl"},{line,38}]},
{lists,mapfoldl,3,
[{file,"lists.erl"},{line,1329}]},
{beam_block,module,2,
[{file,"beam_block.erl"},{line,29}]},
{compile,'-select_passes/2-anonymous-2-',2,
[{file,"compile.erl"},{line,476}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,276}]},
{compile,fold_comp,3,
[{file,"compile.erl"},{line,294}]}]}}},
[{compile,'-select_passes/2-anonymous-2-',2,
[{file,"compile.erl"},{line,476}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,276}]},
{compile,fold_comp,3,[{file,"compile.erl"},{line,294}]},
{compile,internal_comp,4,[{file,"compile.erl"},{line,278}]},
{compile,'-do_compile/2-anonymous-0-',2,
[{file,"compile.erl"},{line,152}]}]}
|
|
Since both the STDLIB and compiler applications turn warnings
into errors, we must stop using the old deprecated crypto functions.
While we are at it, generalize the format of the key tuple returned
by beam_lib:make_crypto_key/2 to facilitate introducing new crypto
methods in the future. Change the format to:
{Type,Key,IV,BlockSize}
where Type, Key, and IV are the first three arguments for either
crypto:block_encrypt4/ or crypto:block_decrypt/4, and BlockSize
is the block size for the crypto algorithm (it is needed to properly
pad the plaintext blocks before encryption).
|
|
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.
|
|
|
|
* nox/fix-bc-optim/OTP-11005:
Add a new option +clint0 to the compiler
Fix optimization of some binary comprehensions
|
|
This option makes the compiler run the Core Erlang linting pass before
any optimization pass, which can crash if the given code has unbound
variables, something that is detected by core_lint.
|
|
If a variable bound in a generator is used as the size of a segment
in the comprehension body, v3_core uses this variable in the code
generated to compute the initial size given to the `bs_init_writable`
primop before the variable is actually bound, as in:
<< <<0:S>> || S <- Slist >>
Reported-By: Peer Stritzinger
|
|
beam_utils:is_not_used_at/3 could be very slow for complex guards,
because the cached result for previously encountered labels were
neither used nor updated within blocks.
Reported-by: Magnus Müller
|
|
|
|
|
|
|
|
Added: binary_to_integer/1,2, integer_to_binary/1,2
|
|
Commits 53bd4974a101 and 726f6e4c7afe simplified the handling of
match_fail (used to generated exceptions such as 'function_clause')
by first rewriting them to a call to erlang/error{1,2} and later
rewriting them to specialized BEAM instructions (to reduce the
code size).
There was one flaw, though, which only was exposed when more
aggressive optimizations were added in c3b60f86c622. Here is an
example to explain it:
t(V) ->
fun(get) -> V end.
The following BEAM code will be initially generated for the fun:
{function, '-t/1-fun-0-', 2, 5}.
{label,1}.
{line,[{location,"t.erl",5}]}.
{func_info,{atom,t},{atom,'-t/1-fun-0-'},2}.
{label,2}.
{test,is_eq_exact,{f,2},[{x,0},{atom,get}]}.
{move,{x,1},{x,0}}.
return.
{label,2}.
{test_heap,2,1}.
{put_list,{x,0},nil,{x,1}}.
{move,{atom,function_clause},{x,0}}.
{line,[{location,"t.erl",5}]}.
{call_ext_only,2,{extfunc,erlang,error,2}}.
Translating back to Erlang code, that would be roughly:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, _) -> erlang:error(function_clause, [Arg1]).
Note that the second argument (the free variable V) is not included
in the call to erlang:error/2.
The beam_except pass will simplify the code to:
{function, '-t/1-fun-0-', 2, 8}.
{label,1}.
{line,[{location,"t.erl",5}]}.
{func_info,{atom,t},{atom,'-t/1-fun-0-'},2}.
{label,2}.
{test,is_eq_exact,{f,1},[{x,0},{atom,get}]}.
{move,{x,1},{x,0}}.
return.
The code has been shortened by jumping to the func_info/3 instruction.
Translating back to Erlang:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, Arg2) -> erlang:error(function_clause, [Arg1,Arg2]).
it is clear that both arguments are now included in the
'function_clause' exception, even though the initially generated
code only included the first argument.
That is no problem in this particular case, but for some more complex
funs, optimizing the first version based on variable usage could make
the second version unsafe.
I rejected the following potential solutions:
- Including the free arguments in the call to erlang:error/2:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, Arg2) -> erlang:error(function_clause, [Arg1,Arg2]).
Unfortunately, that is tricky. The free variables are only known
after the second pass in v3_kernel when variable usage has been
calculated. We would need to add a third pass (only for funs) that
would the free arguments to the second argument for erlang:error/2
*and* update the variable usage information.
- Calling beam_except earlier, from within beam_block before any
optimizations based on variable usages are done. But means that the
problem could reappear in some other form in the future when other
updates are done to the code generator and/or optimization passes.
The solution I have chosen is to modify beam_except to only replace
a call to erlang:error(function_class, Args) if the length of Args
is the same as the arity in the func_info/3 instruction. The code
will be slightly larger. Also, the free variables for funs and list
comprehensions will no longer be included in the function_clause
exception (that could be less confusing, but it also means less
information during debugging).
|
|
* bjorn/compiler/dialyzer-warnings:
compile: Eliminate warnings for unmatched return values
beam_receive: Eliminate dialyzer warning for unmatched return
beam_validator: Eliminate dialyzer warnings for unmatched returns
|
|
* nox/fix-seq-opt/OTP-10818:
Add two tests for unused multiple values in effect context
Forbid multiple values in Core Erlang sequence arguments
|
|
|
|
|
|
The assert_fls/2 and assert_type/3 functions both return the
Vst passed to them, but all callers ignore the return value.
Given the name of the functions, they are not expected to return
anything. Make it so by changing the return value to 'ok'.
There are two calls to bsm_get_context/2 used only to validate
that the match context is valid. Call bsm_validate_context/2
instead.
In bsm_validate_context/2, explicitly match the return value of
bsm_get_context/2 to '_' to make it clear that it is not used.
|
|
|
|
* bjorn/compiler/crash/OTP-10794:
Test setelement(1, not_a_tuple, NewValue)
Fix crash in the compiler when compiling element(2, not_a_tuple)
|
|
It does not make sense to return multiple values from a sequence
argument and the Kernel Erlang passes can't cope with it.
The linting pass now knows how to detect this kind of defunct code and
the Core code folding pass is changed to not generate code like that
when optimizing away multiple-valued lets in effect mode.
Reported-by: José Valim
|
|
In code such as:
X / 2
the following code would be output from beam_type for the division:
{fconv,{x,0},{fr,0}}.
{fconv,{integer,2},{fr,1}}.
fclearerror.
{bif,fdiv,{f,0},[{fr,0},{fr,1}],{fr,0}}.
That is, the integer 2 would be converted to the float 2.0 at
run-time by "{fconv,{integer,2},{fr,1}}". Make sure that we do
the conversion at compile time.
Noticed-by: Richard O'Keefe
|
|
The BEAM loader will put floating point constants into the
literal pools for the module, but it will not check for duplicates.
We can do much better by having the compiler use the literal
pool for floating point constants.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* bjorn/warnings-zero-tolerance:
Turn warnings to errors on selected applications
runtime_tools_sup: Eliminate warning
inet_parse: Eliminate a compiler warning
|
|
This reverts commit 750ecdea08fa5fa7e32b7f3019eed96c1699427e, reversing
changes made to 2cfa0466c3b3c7bd5e3621aff0f3e2ca30addb68.
|
|
|
|
* bjorn/compiler/binary-syntax-bug/OTP-10724:
compiler: Eliminate internal consistency failure in binary matching
|
|
The following code:
check(<<"string">>, a1) ->
one;
check(_, a2) ->
two;
check(undefined, a3) ->
three.
produces an internal consistency failure:
check: function check/2+17:
Internal consistency check failed - please report this bug.
Instruction: {test,is_eq_exact,{f,7},[{x,0},{atom,undefined}]}
Error: {match_context,{x,0}}:
Actually, in the current implementation of the run-time system,
comparing a match context to an atom is safe, so I briefly considered
updating the beam_validator to let this code pass through. I
abandoned that approach because not all terms would be safe to
compare to a match context, and the implementation might change
in the future.
Therefore, fix this problem by not allowing any matching of non-variables
(in the argument position for binary being matched) following binary
matching. That solution is simple and safe, and since this kind of
code seems to be rare in practice, there is no need to pursue any
more compilicated solution.
Reported-by: Viktor Sovietov
|
|
* nox/enable-silent-rules/OTP-10726:
Implement ./otp_build configure --enable-silent-rules
|
|
* bjorn/remove-parameterized-modules/OTP-10616:
Remove support for parameterized modules
xref_SUITE: Don't test parameterized modules
shell_SUITE: Don't test parameterized modules
erl_expand_records_SUITE: Don't test parameterized modules
erl_eval: Don't test parameterized modules
|
|
|
|
|
|
* nox/rm-reverse-eta-conversion/OTP-10682:
Don't use fun references in cprof_SUITE
Make trace_local_SUITE work without the reverse eta conversion
Remove the reverse eta-conversion from v3_kernel
|
|
* nox/promote-inline_list_funcs/OTP-10690:
Raise a function_clause error with the right arguments when inlining
Properly guard against badly-typed arguments when inlining
Make inlined list functions fail with function_clause
Document compiler option 'inline_list_funcs'
Silence some wrong warnings triggered by inline_list_funcs
|
|
|
|
Local fun variables are disallowed in both Erlang and Core Erlang guards
but core_lint doesn't detect this kind of error, making the compilation
fail later in the BEAM assembly generation. A guard is added to only
allow #c_var{} terms where the name is an atom or an integer, which is
the type used by the inliner when introducing new variables.
|
|
The inlined lists functions raised an error with only the list instead
of all their given arguments.
|
|
The inlining code for inline_list_funcs silenced the function_clause
error that should occur when calling lists:map(3.5, []).
|
|
The function_clause errors produced by inline_list_funcs should properly
be annotated with their function names to avoid kernel_v3 making them
into case_clauses errors. See v3_kernel:translate_match_fail_1/4.
|
|
|
|
With silent rules, the output of make is less verbose and compilation
warnings are easier to spot. Silent rules are disabled by default and
can be disabled or enabled at will by make V=0 and make V=1.
|
|
|