Age | Commit message (Collapse) | Author |
|
There are two instructions that take string operands:
{bs_put_string,Fail,NumberOfBytes,{string,String}}
{bs_match_string,Fail,Register,NumberOfBits,{string,String}}
In the canonical BEAM code that is passed to beam_asm, string String
is currently represented as a list. (The string in bs_match_string is
a bitstring before the beam_z compiler pass.) That is wasteful,
because there will be unnecessary conversions between lists and
binaries.
Change the representation of String to be a binary.
Furthermore, bs_put_string is an optimization of a bs_put_binary
instruction with a literal binary operand. Currently, the
bs_put_string instruction is introduced in beam_bs. Delay the
introduction of bs_put_string to the beam_z pass. That will simplify
optimizations and allow us to do the optimization currently done
in beam_bs in a SSA pass in a future commit.
|
|
The new chunk stores atoms encoded in UTF-8.
beam_lib has also been modified to handle the new
'utf8_atoms' attribute while the 'atoms' attribute
may be a missing chunk from now on.
The binary_to_atom/2 BIF can now encode any utf8
binary with up to 255 characters.
The list_to_atom/1 BIF can now accept codepoints
higher than 255 with up to 255 characters (thanks
to Björn Gustavsson).
|
|
|
|
Since Index =:= OldIndex and OldUniq =:= 0, there is no need to
store OldIndex and OldUniq in the internal data structure for the
lambda table.
|
|
|
|
For huge modules with many funs (such as NBAP-PDU-Contents in the asn1
test suite), the call to length/1 in beam_dict:lambda/3 will dominate
the running time of the beam_asm pass.
|
|
|
|
|
|
|
|
|
|
The intention of the comparison is to avoid unnecessary updates of the
">=" instead of ">". With the ">" comparison, typically every line
instruction would cause the #asm{} record to be updated.
|
|
The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(),
set(), and tid() have been deprecated. They will be removed in OTP 18.0.
Instead the types array:array(), dict:dict(), digraph:graph(),
gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid()
can be used. (Note: it has always been necessary to use ets:tid().)
It is allowed in OTP 17.0 to locally re-define the types array(), dict(),
and so on.
New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2,
queue:queue/1, and sets:set/1 have been added.
|
|
|
|
This reverts commit 750ecdea08fa5fa7e32b7f3019eed96c1699427e, reversing
changes made to 2cfa0466c3b3c7bd5e3621aff0f3e2ca30addb68.
|
|
Local function references should be handled directly as a make_fun
internal BIF call instead of creating an extra lambda function every
time they are used.
|
|
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.)
|
|
|
|
It is not needed because it can be trivially calculated using
gb_trees:size/1.
|
|
|
|
|
|
The code for generating the string table (which is now
only used for bit syntax matching) in a BEAM file is quite
complicated and potentially expensive when compiling modules
with many thousands of clauses doing bit syntax matching.
Simplify and optimize the code using bit syntax and
binary:match/2 instead of the list operations in the
original code.
|
|
While at it, do some other minor clean-ups.
|
|
|