Age | Commit message (Collapse) | Author |
|
Setting the hole marker in debug on the entire heap is very slow
so instead we do it in erts_produce_heap.
|
|
This reverts commit ea0e763e953f9c7d1fa9c142f24cb95f56119c56.
|
|
* maint:
Add -ztma option for enabling tuple calls
Reinstate tuple calls support in the beam emulator
|
|
|
|
The guard BIF `length/1` would calculate the length of the list in one
go without yielding, even if the list was were long. To make it even
worse, the call to `length/1` would only cost a single reduction.
This commit reimplements `length/1` so that it eats a number of
reductions proportional to the length of the list, and yields if the
available reductions run out.
|
|
Summary: This commit simplifies the implementation of the "GC BIFs" so
that they no longer need to do a garbage collection, removing duplicate
code for all GC BIFs in the runtime system, as well as potentially
reducing the size of the loaded BEAM code by using shorter
instructions calling those BIFs.
A GC BIF is a guard BIF that will do a garbage
collection if it needs to build anything on the heap.
For example, `abs/1` is a GC BIF because it might need to
allocate space on the heap (if the result is a floating point
number or the resulting integer is a bignum).
Before R12, a guard BIF (such as `abs/1`) that need to allocate
heap space would allocate outside of process's main heap, in
a heap fragment.
GC BIFs were introduced in R12B to support literals. During garbage
collection it become necessary to quickly test whether a term was
a literal. To make the check simple, guards BIFs were no longer
allowed to create heap fragments. Instead GC BIFs were introduced.
In OTP 19, the implementation of literals was changed to support
storing messages in heap fragments outside of the main heap for a
process. That change again made it allowed for guard BIFs to create
heap fragments when they need to build terms on the heap.
It would even be possible for the guard BIFs to build directly
on the main heap if there is room there, because the compiler
assumes that a new `test_heap/2` instruction must be emitted
when building anything after calling a GC BIF. (We don't do that
in this commit; see below.)
This commit simplifies the implementation of the GC BIFs in
the runtime system.
Each GC BIF had a dual implementation: one that was used when the GC
BIF was called directly and one used when it was called via
`apply/3`. For example, `abs/1` was implemented in `abs_1()` and
`erts_gc_abs_1()`. This commit removes the GC version of each BIF. The
other version that allocates heap space using `HAlloc()` is updated to
use the new `HeapFragOnlyAlloc()` macro that will allocate heap
space in a heap fragment outside of the main heap.
Because the BIFs will allocate outside of the main heap, the same
`bif` instructions used by nonbuilding BIFs can be used for the
(former) GC BIFs. Those instructions don't use the macros that save
and restore the heap and stack pointers (SWAPOUT/SWAPIN). If the
former GC BIFs would build on the main heap, either new instructions
would be needed, or SWAPOUT/SWAPIN instructions would need to be added
to the `bif` instructions.
Instructions that call the former GC BIFs don't need the operand
that specifies the number of live X registers. Therefore, the
instructions that call the BIFs are usually one word shorter.
|
|
|
|
|
|
On a 64-bit machine, we only need 32 bits to store a pointer to
the C code that implements a BEAM instruction. Refactor the code
to only use the lower 32 bits of each instruction word, and take
care to preserve the high 32 bits.
|
|
* bjorn/erts/improve-beam-ops:
Move out variables from the head of combined instructions
Change operand from 'P' to 'Q' for i_apply_last and i_apply_fun_last
Add CHECK_ALIGNED() for testing storage destinations
instrs.tab: Add missing -no_next directives
beam_load.c: Generalize the 'P' operator in the packing engine
Break out most of the initialization from process_main()
Eliminate the OpCode() macro
Eliminate unnecessary and inconsistent casts
Refactor macros for accessing Beam instructions
beam_emu: Make order of macros consistent
beam_SUITE: Strengthen test of packed registers
|
|
|
|
|
|
The BeamOp() macro in erl_vm.h is clumsy to use. All users
cast the return value to BeamInstr.
Define new macros that are easier to use. In the future,
we might want to pack an operand into the same word as
the pointer to the instruction, so we will define two macros.
BeamIsOpCode() is used to rewrite code like this:
if (Instr == (BeamInstr) BeamOp(op_i_func_info_IaaI) {
...
}
to:
if (BeamIsOpCode(Instr, op_i_func_info_IaaI)) {
...
}
BeamOpCodeAddr(op_apply_bif) is used when we need the address
for an instruction.
Also elimiminate the global variables em_* in beam_emu.c.
They are not really needed. Use the BeamOpCodeAddr() macro
instead.
|
|
|
|
* lukas/erts/HRelease-assert:
erts: Add HRelease endp assert
|
|
|
|
This assert makes sure that endp is correct and that
no other HAlloc has been done inbetween HAlloc and HRelease.
|
|
|
|
* maint:
Use a hole-marker that cannot be mistaken for a valid term on the heap
|
|
|
|
|
|
This commit adds two new structs to be used to represent
erlang code in erts.
ErtsCodeInfo is used to describe the i_func_info header
that is part of all Export entries and the prelude of
each function. This replaces all the BeamInstr * that
were previously used to point to these locations.
After this change the code should never use BeamInstr *
with offsets to figure out different parts of the
func_info header.
ErtsCodeMFA is a struct that is used to descripe a
MFA in code. It is used within ErtsCodeInfo and also
in Process->current.
All function that previously took Eterm * or BeamInstr *
to identify a MFA now use the ErtsCodeMFA or ErtsCodeInfo
where appropriate.
The code has been tested to work when adding a new field to the
ErtsCodeInfo struct, but some updates are needed in ops.tab to
make it work.
|
|
Before:
$ size bin/x86_64-unknown-linux-gnu/beam.smp
text data bss dec hex filename
3080982 188369 158472 3427823 344def bin/x86_64-unknown-linux-gnu/beam.smp
After:
$ size bin/x86_64-unknown-linux-gnu/beam.smp
text data bss dec hex filename
3164694 104657 158472 3427823 344def bin/x86_64-unknown-linux-gnu/beam.smp
|
|
The counters are only used in the special 'icount' emulator.
We will save some memory by including the counters in the
OpEntry. It will also make it possible to make opc 'const'.
|
|
The max_heap_size process flag can be used to limit the
growth of a process heap by killing it before it becomes
too large to handle. It is possible to set the maximum
using the `erl +hmax` option, `system_flag(max_heap_size, ...)`,
`spawn_opt(Fun, [{max_heap_size, ...}])` and
`process_flag(max_heap_size, ...)`.
It is possible to configure the behaviour of the process
when the maximum heap size is reached. The process may be
sent an untrappable exit signal with reason kill and/or
send an error_logger message with details on the process
state. A new trace event called gc_max_heap_size is
also triggered for the garbage_collection trace flag
when the heap grows larger than the configured size.
If kill and error_logger are disabled, it is still
possible to see that the maximum has been reached by
doing garbage collection tracing on the process.
The heap size is defined as the sum of the heap memory
that the process is currently using. This includes
all generational heaps, the stack, any messages that
are considered to be part of the heap and any extra
memory the garbage collector may need during collection.
In the current implementation this means that when a process
is set using on_heap message queue data mode, the messages
that are in the internal message queue are counted towards
this value. For off_heap, only matched messages count towards
the size of the heap. For mixed, it depends on race conditions
within the VM whether a message is part of the heap or not.
Below is an example run of the new behaviour:
Eshell V8.0 (abort with ^G)
1> f(P),P = spawn_opt(fun() -> receive ok -> ok end end, [{max_heap_size, 512}]).
<0.60.0>
2> erlang:trace(P, true, [garbage_collection, procs]).
1
3> [P ! lists:duplicate(M,M) || M <- lists:seq(1,15)],ok.
ok
4>
=ERROR REPORT==== 26-Apr-2016::16:25:10 ===
Process: <0.60.0>
Context: maximum heap size reached
Max heap size: 512
Total heap size: 723
Kill: true
Error Logger: true
GC Info: [{old_heap_block_size,0},
{heap_block_size,609},
{mbuf_size,145},
{recent_size,0},
{stack_size,9},
{old_heap_size,0},
{heap_size,211},
{bin_vheap_size,0},
{bin_vheap_block_size,46422},
{bin_old_vheap_size,0},
{bin_old_vheap_block_size,46422}]
flush().
Shell got {trace,<0.60.0>,gc_start,
[{old_heap_block_size,0},
{heap_block_size,233},
{mbuf_size,145},
{recent_size,0},
{stack_size,9},
{old_heap_size,0},
{heap_size,211},
{bin_vheap_size,0},
{bin_vheap_block_size,46422},
{bin_old_vheap_size,0},
{bin_old_vheap_block_size,46422}]}
Shell got {trace,<0.60.0>,gc_max_heap_size,
[{old_heap_block_size,0},
{heap_block_size,609},
{mbuf_size,145},
{recent_size,0},
{stack_size,9},
{old_heap_size,0},
{heap_size,211},
{bin_vheap_size,0},
{bin_vheap_block_size,46422},
{bin_old_vheap_size,0},
{bin_old_vheap_block_size,46422}]}
Shell got {trace,<0.60.0>,exit,killed}
|
|
* henrik/update-copyrightyear:
update copyright-year
|
|
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.
|
|
|
|
The 'r' type is now mandatory. That means in order to handle
both of the following instructions:
move x(0) y(7)
move x(1) y(7)
we would need to define two specific operations in ops.tab:
move r y
move x y
We want to make 'r' operands optional. That is, if we have
only this specific instruction:
move x y
it will match both of the following instructions:
move x(0) y(7)
move x(1) y(7)
Make 'r' optional allows us to save code space when we don't
want to make handling of x(0) a special case, but we can still
use 'r' to optimize commonly used instructions.
|
|
|
|
|
|
|
|
Conflicts:
erts/emulator/Makefile.in
erts/emulator/beam/bif.tab
erts/emulator/beam/erl_gc.c
erts/emulator/beam/erl_gc.h
erts/emulator/beam/erl_printf_term.c
erts/emulator/beam/erl_term.c
erts/emulator/beam/erl_term.h
|
|
* egil/process_dictionary-initial-size/OTP-12535:
erts: Document option 'hpds'
erts: Enable command line argument for initial pd size
|
|
Use '+hpds size' to set initial process dictionary size for spawned processes.
|
|
Cleanup macro code.
|
|
for the temporary conversion from float to big.
Preparation for coming bugfix of 'big_buf' array size.
|
|
* Coalescing and trimming of free segments in supercarrier
* Management of super aligned and super unaligned areas in
supercarrier
* Management of reservation of physical memory
* erts_mseg usage of erts_mmap
|
|
|
|
|
|
The hybrid heap emulator was last working in the non-SMP R11B
run-time system. When the constant pools were introduced in R12B,
the hybrid heap emulator was not updated to handle them.
At this point, the harm from reduced readability of the code is
greater than any potential usefulness of keeping the code.
|
|
* rickard/thr-progress-block/OTP-9631:
Replace system block with thread progress block
|
|
The ERTS internal system block functionality has been replaced by
new functionality for blocking the system. The old system block
functionality had contention issues and complexity issues. The
new functionality piggy-backs on thread progress tracking functionality
needed by newly introduced lock-free synchronization in the runtime
system. When the functionality for blocking the system isn't used
there is more or less no overhead at all. This since the functionality
for tracking thread progress is there and needed anyway.
|
|
|
|
For floating point values which are greater than 9007199254740990.0 or
smaller than -9007199254740990.0, the floating point numbers are now
converted to integers during comparison with an integer. This makes
number comparisons transitive for large floating point numbers.
|
|
* sverker/ets_halfword_highmem/OTP-8941:
HALFWORD ETS Fix copyright year in some source files
Fix vm crash in kernel test case seq_trace_SUITE:call
remove NIF compile warning: no previous prototype for ‘nif_init’
Refuse to load NIF library on wrong VM variant (halfword/fullword)
HALFWORD ETS match spec heap fragment optimization
HALFWORD ETS removed eheap and improved test case t_match_spec_run
HALFWORD ETS Further match spec optimization to minimize copying and garbage
HALFWORD ETS db_prog_match optimization
HALFWORD ETS Fix segv for match spec with several function and guards
HALFWORD Make system_info mseg_alloc report both low/high mem
HALFWORD Fix segv caused by erlang:halt
HALFWORD Make more allocators use high mem (binary, fixed and driver)
HALFWORD ETS 32-bit arch fixes and other cleanups
HALFWORD ETS nicer update_element
HALFWORD ETS Real matching on relative terms
HALFWORD first stab at high mem alloc
HALFWORD ETS relative terms
Conflicts:
erts/emulator/test/driver_SUITE.erl
|
|
Introduce HAllocX to allocate heap fragments with a larger capacity
than requested and by that reduce the number of fragments allocated.
|
|
Historically, for no good reason, a function is allowed to have
from 0 to 256 arguments. Thus, the number of arguments *almost*
fits into a byte.
HiPE only supports up to 255 arguments (because it assumes that
the function arity fits into a single byte), and fixing that limitation
would require ugly special-case handling. In Dialyzer, the arity
type is defined to be a byte (i.e. 0..255).
Since no-one uses functions with 256 arguments anyway, lower the
limit to 255.
|
|
The compressed format is using a slighty modified variant of the extern format
(term_to_binary). To not worsen key lookup's too much, the top tuple itself
and the key element are not compressed. Table objects with only immediate
non-key elements will therefor not gain anything (but actually consume one
extra word for "alloc_size").
|
|
New NIF features:
Send messages from a NIF, or from thread created by NIF, to any local
process (enif_send)
Store terms between NIF calls (enif_alloc_env, enif_make_copy)
Create binary terms with user defined memory management
(enif_make_resource_binary)
|