Age | Commit message (Collapse) | Author |
|
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.
|
|
* john/erts/assert-dirty-aux-work:
Abort when aux work runs on a dirty scheduler
|
|
|
|
* lukas/erts/fix-msacc-gc-states/OTP-15450:
erts: Fix msacc GC states on dirty scheds
|
|
While the system will keep working, the aux work will never run
and the affected scheduler never goes to sleep. OTP-15446 is a
good example of this.
As this error easily flies under the radar it's best to make it
immediately visible. The assertions we had in debug builds were
clearly not enough to catch all sources of this problem.
|
|
* maint:
erts: fix attempt to start timer when executing on dirty scheduler
|
|
erts: fix attempt to start timer when executing on dirty scheduler
OTP-15446
|
|
Since OTP R20, there is a possibility for MAJOR garbage collection to
run on dirty scheduler. So DistEntry destructor is being called on
dirty scheduler as well. This, in turn, leads to an attempt to schedule
timer on a dirty scheduler too, which is impossible (and will assert
on debug build, but does succeed for release build, creating an
infinite busy loop, since aux work wakes scheduler up, but dirty
scheduler cannot execute aus work).
There is a similar method in erl_hl_timer, see erts_start_timer_callback.
|
|
|
|
* sverker/erts/atomics-counters/OTP-13468:
erts: Fix bug in counters
erts: Refactor erl_bif_counters.c
|
|
Wow, that could have been embarrassing.
|
|
with more consistent naming.
|
|
* maint:
Allow disabling retpoline in interpreter loop
Add a ./configure flag for spectre mitigation
|
|
into maint
* john/erts/spectre-configure-flag-otp_20/OTP-15430/ERIERL-237:
Allow disabling retpoline in interpreter loop
Add a ./configure flag for spectre mitigation
|
|
|
|
AGAIN
* sverker/erts/atomics-counters/OTP-13468:
erts: Add counters:put/3
|
|
|
|
john/erts/spectre-configure-flag-otp_20/OTP-15430/ERIERL-237
* john/erts/spectre-configure-flag/OTP-15430/ERIERL-237:
Allow disabling retpoline in interpreter loop
Add a ./configure flag for spectre mitigation
|
|
We only do this when the user has explicitly told us it's okay to
partially disable mitigation (spectre-mitigation=incomplete). The
macro is inert if it isn't.
|
|
|
|
Also fix erts_debug:get_internal_status(node_and_dist_references)
for catree to also search route node keys for offheap stuff.
|
|
with some code moving and removed obsolete comments.
|
|
* john/erts/plusplus-trapping/OTP-15427:
Don't use too many reductions in lists:reverse/2
Make '++'/2 trapping
|
|
* maint:
Fix broken assertion on monitor release
Avoid closing files in gc/monitor callbacks
|
|
* john/erts/defer-orphan-file-close/OTP-15421/ERIERL-261:
Fix broken assertion on monitor release
Avoid closing files in gc/monitor callbacks
|
|
|
|
* sverker/erts/atomics-counters/OTP-13468:
erts: Add new module 'counters'
erts: Add new module 'atomics'
|
|
|
|
|
|
We sometimes bump the refc without messing with the table, which
means that we sometimes decrement it while in the table, causing
the old assertion to fail.
The property we want to check is that neither end of the monitor is
present in the table when the monitor is deleted.
|
|
|
|
|
|
* maint:
Remove --/2 from dirty BIF tests
|
|
Now that it traps, --/2 would hang forever when building under
--enable-dirty-schedulers-test.
|
|
* sverker/erts/ordered_set-select-improvements/OTP-15325:
erts: Tidy some ordered_set iteration code
erts: Fix bug for catree iteration
|
|
* maint:
Implement a tab for persistent terms in crashdump viewer
Add tests of persistent terms for crashdump_viewer
Add a persistent term storage
Refactor releasing of literals
Extend the sharing-preserving routines to optionally copy literals
Conflicts:
erts/emulator/Makefile.in
erts/emulator/beam/erl_process_dump.c
erts/preloaded/ebin/erts_internal.beam
erts/preloaded/ebin/init.beam
lib/sasl/src/systools_make.erl
|
|
* bjorn/erts/persistent_terms/OTP-14669:
Implement a tab for persistent terms in crashdump viewer
Add tests of persistent terms for crashdump_viewer
Add a persistent term storage
Refactor releasing of literals
Extend the sharing-preserving routines to optionally copy literals
|
|
Persistent terms are useful for storing Erlang terms that are never
or infrequently updated. They have the following advantages:
* Constant time access. A persistent term is not copied when it is
looked up. The constant factor is lower than for ETS, and no locks
are taken when looking up a term.
* Persistent terms are not copied in garbage collections.
* There is only ever one copy of a persistent term (until it is
deleted). That makes them useful for storing configuration data
that needs to be easily accessible by all processes.
Persistent terms have the following drawbacks:
* Updates are expensive. The hash table holding the keys for the
persistent terms are updated whenever a persistent term is added,
updated or deleted.
* Updating or deleting a persistent term triggers a "global GC", which
will schedule a heap scan of all processes to search the heap of all
processes for the deleted term. If a process still holds a reference
to the deleted term, the process will be garbage collected and the
term copied to the heap of the process. This global GC can make the
system less responsive for some time.
Three BIFs (implemented in C in the emulator) is the entire
interface to the persistent term functionality:
* put(Key, Value) to store a persistent term.
* get(Key) to look up a persistent term.
* erase(Key) to delete a persistent term.
There are also two additional BIFs to obtain information about
persistent terms:
* info() to return a map with information about persistent terms.
* get() to return a list of a {Key,Value} tuples for all persistent
terms. (The values are not copied.)
|
|
A dirty scheduler is an un-managed thread so we need to
lock the msacc state on those.
|
|
* maint:
Optimize operator '--' and yield on large inputs
Inline erts_cmp
Clarify a magical allocation size
Fix trapping in lists:reverse/2
|
|
* john/erts/minusminus_trapping/OTP-15371:
Optimize operator '--' and yield on large inputs
Inline erts_cmp
Clarify a magical allocation size
Fix trapping in lists:reverse/2
|
|
* sverker/enif-cancel-select/OTP-15095:
erts: Bump erl_nif minor version and ERL_NIF_MIN_ERTS_VERSION
|
|
with ticket syntax.
|
|
with variable name changes, some comments
and moved catree_find_prev_from_pb_key_root after its twin.
|
|
with keys containing off-heap terms.
The passed key may actually be the one already saved
(if nodes have been joined), in which case we do nothing.
Calling destroy_route_key() may destroy off-heap data.
|
|
* maint:
Fix erts_internal_ref_number_cmp()
|
|
* rickard/internal_ref_cmp/OTP-15399/ERL-751:
Fix erts_internal_ref_number_cmp()
|
|
Even more scalable ETS ordered_set with write_concurrency
|
|
|
|
Introudce erts_queue_release_literals() to queue a literal area to be
released.
|