Age | Commit message (Collapse) | Author |
|
* bjorn/line-numbers/OTP-9468:
beam_type: Improve FP optimizations in the presence of line numbers
|
|
* bjorn/fun-improvements/OTP-9667:
sys_pre_expand: Remove incorrect comment
compiler: Eliminate use of deprecated erlang:hash/2
beam_asm: Fix broken NewIndex in fun entries
beam_asm: Strenghten the calculation of Uniq for funs
|
|
sys_pre_expand does not keep track of used or new variables (and have
not done since about the time Core Erlang was introduced).
|
|
Now that beam_asm computes the Index and Uniq values for funs, there
is no need to compute those values in the sys_pre_expand and v3_kernel
modules, thus eliminating the calls to the deprecated erlang:hash/2
function.
It would be tempting to stop generating the name for the fun in
sys_pre_expand so that we did not have to add the Info field to a tuple.
But:
* The debugger depends on the name being there. (Simple solution:
Let the debugger generate the name itself.)
* When a fun has been inlined into another function, the fun name in
'id' annotation will be used to notice the inlining and change the
final clause of the top-level case from generating a 'function_clause'
exception to a case_clause exception. (Possible workaround: Have the
inliner set an inlined attribute on functions that have been inlined, or
have the inliner rewrite 'function_clause' exceptions itself.)
|
|
The calculation of the NewIndex field in fun entries is broken: the
sys_pre_expand and v3_kernel modules keep separate index counters
starting at zero; thus there is no guarantee that each fun within a
module will have its own unique NewIndex.
We don't really need the NewIndex any more (see below), but since
we do need the NewUniq field, we should fix NewIndex for cleanliness
sake. The simplest way is to assign NewIndex as late as possible,
namely in beam_asm, and to set it to the same value as Index.
Historical Note: Why NewIndex Was Introduced
There was once an idea that the debugger should be able to interpret
only a single function in a module (for speed). To make sure that
interpreted funs could be called from BEAM code and vice versa,
the fun identification must be visible in the abstract code.
Therefore a NewIndex field was introduced in each fun in the abstract
code.
However, it turned out that interpreting single functions does not
play well with aggressive code optimization. For example, in this
code:
f() ->
X = 1,
fun() -> X+2 end.
the variable X will seem to be free in the fun, but an aggressive
optimizer will replace X with 1 in the fun; thus the fun will no
longer have any free variables. Therefore, the debugger will always
interpret entire modules.
|
|
Funs are identified by a triple, <Module,Uniq,Index>, where Module is
the module name, Uniq is a 27 bit hash value of some intermediate
representation of the code for the fun, and index is a small integer.
When a fun is loaded, the triple for the fun will be compared to
previously loaded funs. If all elements in the triple in the newly
loaded fun are the same, the newly loaded fun will replace the previous
fun. The idea is that if Uniq are the same, the code for the fun is also
the same.
The problem is that Uniq is only based on the intermediate representation
of the fun itself. If the fun calls local functions in the same module,
Uniq may remain the same even if the behavior of the fun has been changed.
See
http://erlang.org/pipermail/erlang-bugs/2007-June/000368.htlm
for an example.
As a long-term plan to fix this problem, the NewIndex and NewUniq
fields was added to each fun in the R8 release (where NewUniq is the
MD5 of the BEAM code for the module). Unfortunately, it turns
out that the compiler does not assign unique value to NewIndex (if it
isn't tested, it doesn't work), so we cannot use the
<Module,NewUniq,NewIndex> triple as identification.
It would be possible to use <Module,NewUniq,Index>, but that seems
ugly. Therefore, fix the problem by making Uniq more unique by
taking 27 bits from the MD5 for the BEAM code. That only requires
a change to the compiler.
Also update a test case for cover, which now fails because of the
stronger Uniq calculation. (The comment in test case about why the
Pid2 process survived is not correct.)
|
|
Currently, the external fun syntax "fun M:F/A" only supports
literals. That is, "fun lists:reverse/1" is allowed but not
"fun M:F/A".
In many real-life situations, some or all of M, F, A are
not known until run-time, and one is forced to either use
the undocumented erlang:make_fun/3 BIF or to use a
"tuple fun" (which is deprecated).
EEP-23 suggests that the parser (erl_parse) should immediately
transform "fun M:F/A" to "erlang:make_fun(M, F, A)". We have
not followed that approach in this implementation, because we
want the abstract code to mirror the source code as closely
as possible, and we also consider erlang:make_fun/3 to
be an implementation detail that we might want to remove in
the future.
Instead, we will change the abstract format for "fun M:F/A" (in a way
that is not backwards compatible), and while we are at it, we will
move the translation from "fun M:F/A" to "erlang:make_fun(M, F, A)"
from sys_pre_expand down to the v3_core pass. We will also update
the debugger and xref to use the new format.
We did consider making the abstract format backward compatible if
no variables were used in the fun, but decided against it. Keeping
it backward compatible would mean that there would be different
abstract formats for the no-variable and variable case, and tools
would have to handle both formats, probably forever.
Reference: http://www.erlang.org/eeps/eep-0023.html
|
|
Allow line/1 instructions to be part of a sequence of floating point
instructions to avoid outputting fclearerror / fcheckerror around
every floating point instruction.
|
|
'behaviour_info(callbacks)' is a special function that is defined in a module
which describes a behaviour and returns a list of its callbacks.
This function is now automatically generated using the '-callback' specs. An
error is returned by lint if user defines both '-callback' attributes and the
behaviour_info/1 function. If no type info is needed for a callback use a
generic spec for it.
|
|
Behaviours may define specs for their callbacks using the familiar spec syntax,
replacing the '-spec' keyword with '-callback'. Simple lint checks are performed
to ensure that no callbacks are defined twice and all types referred are
declared.
These attributes can be then used by tools to provide documentation to the
behaviour or find discrepancies in the callback definitions in the callback
module.
|
|
* dev:
Update copyright years
|
|
|
|
|
|
* hl/beam_disasm-no_attri_chunk:
beam_disasm: Handle stripped BEAM files
OTP-9571
|
|
beam_disasm:file/1 would crash if asked to disassemble a stripped
BEAM file without an "Attr" chunk.
|
|
* dev:
sys_pre_expand: Don't duplicate options given in the source code
|
|
* bjorn/compiler-options/OTP-9534:
sys_pre_expand: Don't duplicate options given in the source code
|
|
Any compiler options given with a -compile() attribute in source file
would be included both at the beginning and the end of the option list
for the compiler. Including the options twice is harmless during
compilation, but since the options will also be available in
Mod:module_info(compile), including them twice will waste memory.
Include the options from the source first in the list so that they
override options given on the command line.
|
|
Conflicts:
lib/asn1/doc/src/asn1ct.xml
|
|
|
|
|
|
|
|
Also update the r12 and r13 options so that they imply no_line_info.
|
|
In the location information tables in the run-time system, source
filenames that are the same as the module name plus ".erl" extension
are not stored explicitly, thus saving memory.
To take advantage of that optimization, avoid complicating the names of
files in the current working directory; specifically, make sure that
"./" is not prepended to the name.
|
|
|
|
|
|
Introduce the line/1 instruction in the compiler and the BEAM
virtual machine. It will not yet be generated by the compiler and
will not actually carry any information.
|
|
|
|
|
|
'eval_bits' is a common utility module used for evaluting binary
construction and matching. The functions that do matching
(match_bits/{6,7} and bin_gen/6) are supposed to treat the bindings as
an abstract data type, but they assume that the bindings have the same
representation as in the erl_eval module. That may cause binary
matching to fail in the debugger, because the debugger represents the
bindings as an unordered list of two-tuples, while the erl_eval
modules uses an ordered list of two-tuple (an ordset).
One way to fix the problem would be to let the debugger to use ordered
lists to represent the bindings. Unfortunately, that would also change
how the bindings are presented in the user interface. Currently, the
variable have most been recently assigned is shown first, which is
convenient.
Fix the matching problem by mending the leaky abstraction in
eval_bits. The matching functions needs to be passed two additional
operations: one for looking up a variable in the bindings and one for
adding a binding. Those operations could be passed as two more funs
(in addition to the evaluation and match fun already passed), but the
functions already have too many arguments. Therefore, change the
meaning of the match fun, so that the first argument is the operation
to perform ('match', 'binding', or 'add_binding') and second argument
is a tuple with arguments for the operation.
|
|
concat_binary/1 was deprecated in R13B04, but already in
the R10B-2 release, the documentation recommends using
list_to_binary/1 instead.
|
|
|
|
In warning_translate_label/2, gb_trees:lookup/2 is called
to translate from the entry label for a function to its name.
Since the gb_tree has an entry for all functions in the module,
there is no way that the lookup can fail unless there is a
serious bug.
Therefore, use gb_trees:get/2 so that an exception and an
internal compiler error will be generated if the lookup would
ever fail.
|
|
There is never any empty blocks when beam_dead is invoked.
Even if there were, they will be removed a little bit later in
forward/4.
|
|
In the optimization of binary matching, it seems that two clauses
cannot never be reached. Removing the clauses is safe, since that
would only mean that an opportunity for an optimization is lost
|
|
Because the code generator (v3_codegen) would not include the
same value more than once in a select_val/3 instruction and
because a label can only be referenced by one select_val/3
instruction, there is no way that the correct value could already
be in the gb_tree. (Even if it could happen, this change is
safe because only opportunity for an optimization would be missed;
incorrect code would not be generated.)
|
|
Since the optimizations in forward/4 already depends on some
assumptions on how code is generated anyway, document the
assumptions in a comment and remove the uncoverable code.
|
|
It is not needed because it can be trivially calculated using
gb_trees:size/1.
|
|
|
|
The compiler (sys_core_fold) tries to avoid constructing tuples
in case expressions. The following code:
c(A, B) ->
case {A,B} of
{ok,X} -> X;
{_,_} -> error
end.
will be rewritten so that no tuple is built. If a clause
requires a tuple to be built as in this code:
c(A, B) ->
case {A,B} of
{ok,X} -> X;
V -> V %The tuple will be built here
end.
the tuple will be built in the clause(s) in which it is needed.
If the value returned from the case is not used as in this code:
c(A, B) ->
case {A,B} of
V -> V %Warning: a term is constructed, but never used
end,
ok.
there will be an incorrect warning. Basically, what happens is
that the code is reduced to:
c(A, B) ->
{A,B}, %Warning: a term is constructed, but never used
ok.
and the optimizer sees that the {A,B} tuple can't possibly be used.
Eliminate the warning by adding a 'compiler_generated' annotation
to the tuple.
Reported-by: Kostis Sagonas
|
|
|
|
In the following code:
m(<<Sz:8,_:Sz/binary>>) ->
Sz = wrong.
the Sz variable is supposed to be bound in the function header and the
matching "Sz = wrong" should cause a badarg exception. But what
happens is that the Sz variables seems to be unbound and the matching
succeds and the m/1 function returns 'wrong'.
If the Sz variable is used directly (not matched), it will have
the expected value. Thus the following code:
m(<<Sz:8,_:Sz/binary>>) ->
Sz.
will correctly return the value of Sz that was matched out from
the binary.
Reported-by: Bernard Duggan
|
|
|
|
|
|
* bjorn/fix-dialyzer-warnings:
v3_kernel_pp: Eliminate dialyzer warning
inet6_tcp_dist: Eliminate dialyzer warning for "tuple fun"
|
|
* bjorn/compiler/refactor-source-options:
compile: Refactor handling of source options (e.g. 'from_core')
|
|
Use conditional compilation instead of a run-time test.
Will also improve the coverage of the code.
|
|
* jp/dependencies_makefile:
Add dependencies Makefile generation to erlc(1) and compile(3)
Conflicts:
lib/compiler/test/compile_SUITE.erl
OTP-9065
|
|
This is useful when a project is built with Makefiles and erlc(1)
instead of EMakefiles. Tracking dependencies by hand is error-prone and
it becomes painful when using external application headers like EUnit's
one.
A dependencies Makefile will look like this:
module.beam: module.erl \
/usr/local/lib/erlang/lib/eunit-2.1.4/include/eunit.hrl \
header.hrl
When included in the main Makefile, 'module' will be recompiled only
when needed.
GCC offers the same feature and new erlc(1) options are compatible with
it.
More informations at:
http://wiki.github.com/dumbbell/otp/dependencies-makefile
|
|
The options for compiling from Core Erlang, BEAM assembler files,
and BEAM files are handled in several places, making it difficult
to change or add more similar options. Refactor the option handling
so that each option only need to be handled in one place.
|