Age | Commit message (Collapse) | Author |
|
0a4750f91c83 optimized unpacking by removing a mask operation
when unpacking three packed operands. Unfortunately, that optimization
is only safe on 64-bit architectures.
Here is what happens on 32-bit architectures.
The operands to be packed are 10-bit register numbers that have been
turned into byte offsets:
aaaaaaaaaa00
bbbbbbbbbb00
cccccccccc00
They can be packed into a single word like this:
30 20 10 0
| | | |
aa aaaaaaaabb bbbbbbbbcc cccccccc00
If we call the packed word P, the original operands can be
extracted like this:
C = P band 2#111111111100
B = (P bsr 10) band 2#111111111100
A = (P bsr 20) band 2#111111111100
The bug was that A was extracted without the masking:
A = P bsr 20
That would give A the value:
aaaaaaaaaaaabb
That would only be safe if the two most significant bits in B
were zeroes.
|
|
There is a '#ifdef ARCH_64' beam_opcodes.h, which might make you
think that files generated by beam_makeops will work for both
32-bit and 64-bit architectures. They will not. beam_makeops will
generate different code depending on its -wordsize option.
|
|
|
|
* egil/erts/opt-list_append/OTP-13487:
erts: Optimize '++' operator
|
|
It's not just ok to throw badarg, it MUST throw badarg.
|
|
|
|
* henrik/update-copyrightyear:
update copyright-year
|
|
|
|
|
|
* msantos/erts/cli-abort-on-alloc-fail/PR-948/OTP-13486:
erts/common: check for OOM on Windows
|
|
* egil/erts-lib/modernize-tests:
Replace test_server:os_type/0 with os:type/0
Eliminate use of doc and suite clauses
Replace use of test_server:format/2 with io:format/2
Eliminate use of test_server:fail/0,1
Eliminate use of ?config() macro
Modernize use of timetraps
Remove ?line macros
|
|
* bjorn/raise:
Remove unreachable code after 'raise' instructions
Simplify the raise instruction to reduce code size
|
|
This also optimizes the BIF lists:append/2
Use one pass to check for properness and copying LHS list.
If LHS turns out not being a proper list, bail and reset htop.
If we run out of heap, allocate a heap-fragment and calculate
the remaining length as normal, thus checking for properness,
and then continue copying.
Measurements shows this being ~50% faster.
|
|
|
|
* egil/erts/fix-process_info-spec/ERL-123/OTP-13485:
Update preloaded erlang.beam
erts: Fix process_info/2 result spec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The raise/2 instruction is almost always used like this:
raise x(2) x(1)
Therefore, we can translate it to an internal i_raise/0
instruction that uses x(2) x(1) as its implicit operands.
We will also remove the backward compatibility with R10-0. It is
unlikely that anyone still is using BEAM files compiled with the R10-0
compiler, especially since most of those modules cannot be loaded. The
loader will refuse to load any module that uses the old non-GCIng
arithmetic instructions or the non-GCing versions of length/1 or
size/1.
Doing these changes will reduce both the size of the loaded BEAM
code and size of the code in process_main().
|
|
to let future nodes know that we can handle
NEW_PID_EXT, NEW_PORT_EXT and NEWER_REFERENCE_EXT.
|
|
|
|
from future nodes.
|
|
Instead of INTERNAL_CREATION (255), use empty atom for node name
to mean the local node (regardless of node name or creation).
The purpose is to get rid of special value 255, for future expansion
of creation to 32-bit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* bjorn/erts/huge-file-fix/OTP-13461:
Handle multi-giga byte writes to files
|
|
* bjorn/erts/beam_load:
Eliminate unnecessary renaming of bs_put_utf16/3
Don't let the loader do the compiler's job
Remove unused variables after code generation
Avoid rebuilding unchanged instructions
Introduce a 'rename' instruction
Simplify window management for the transformation engine
Eliminate allocation of variables in transform_engine()
Refactor calls to transform_engine()
ops.tab: Remove useless transformation
|
|
There is no reason to rename bs_put_utf16/3.
(We rename instructions if we'll need to change the operands or
if we will need to avoid an endless transformation loop. Neither
of these reasons apply to bs_put_utf16/3.)
|
|
Optimizations that are possible to do by the compiler should be
done by the compiler and not by the loader.
If the compiler has done its job correctly, attempting to do the two
transformations only wastes time.
|
|
The removal of instructions on the left side of a transformation
is done while generating the code for the left side.
Postpone removal of unused variables to a later, separate passes to
allow more variables to be eliminated after the optimizations
passes introduced in the previous commits.
|
|
In transformations such as:
move S X0=x==0 | line Loc | call_ext Ar Func => \
line Loc | move S X0 | call_ext Ar Func
we can avoid rebuilding the last instruction in the sequence
by introducing a 'keep' instruction.
Currently, there are only 13 transformations that are hit by
this optimization, but most of them are frequently used.
|
|
Introduce a 'rename' instruction that can be used to optimize
simple renaming with unchanged operands such as:
get_tuple_element Reg P Dst => i_get_tuple_element Reg P Dst
By allowing it to lower the arity of instruction, transformations
such as the following can be handled:
trim N Remaining => i_trim N
All in all, currently 67 transformations can be optimized in this
way, including some commonly used ones.
|
|
Generic instructions have a min_window field. Its purpose is to
avoid calling transform_engine() when there are too few instructions
in the current "transformation window" for a transformation to
succeed.
Currently it does not do much good since the window size will be
decremented by one before being used. The reason for the subtraction
is probably that in some circumstances in the past, the loader could
read past the end of the BEAM module while attempting to fetch
instructions to increase the window size. Therefore, it would not
be safe to just remove the subtraction by one.
The simplest and safest solution seems to always ensure that there
are always at least TWO instructions when calling transform_engine().
That will be safe, as long as a BEAM module is always finished with
an int_code_end/0 that is not involved in any transformation.
|
|
When an instruction with a variable number operands (such as
select_val) is seen of the left side of a transformation, the
'next_arg' instruction will allocate a buffer to fit all variables and
all operands will be copied into the buffer. Very often, the 'commit'
instruction will never be reached because of a test or predicate
failing or because of a short window; in that case, the variable
buffer will be deallocated.
Note that originally there were only few instructions with a variable
number of operands, but now common operations such as tuple building
also have a variable number of operands.
To avoid those frequent allocations and deallocations, modify the
'next_arg' instruction to only save a pointer to the first of the
"rest" arguments. Also move the deallocation of the instructions
on the left side from the 'commit' instruction to the 'end'
instruction to ensure that 'store_rest_args' will still work.
|
|
This is an optimization for reducing the number of heap fragments
allocated when sending a message where the majority of the
message payload is on the sending process' heap.
|
|
* egil/erts/tracing-beam-lttng/OTP-10282:
erts: Don't use ratio in carrier lttng tracepoints
Add lttng testcases
erts: Extend erlang:system_info/1 with lttng
Refactor and fix dtrace define in erl_message
erts: Add lttng tracepoints for async pool queue
erts: Add lttng tracepoints for drivers
erts: Add lttng tracepoints for scheduler events
erts: Add lttng tracepoints for memory carriers
erts: Update lttng-wrapper with mfa conversion
erts: Teach lttng to configure and build system
|
|
|
|
|
|
Let erlang:system_info(dynamic_trace) be able to return 'lttng' if enabled.
|
|
|
|
* aio_pool_get
* aio_pool_add
|
|
* driver_event
* driver_flush
* driver_finish
* driver_init
* driver_output
* driver_outputv
* driver_process_exit
* driver_ready_async
* driver_ready_input
* driver_ready_output
* driver_start
* driver_stop
* driver_stop_select
* driver_timeout
|