Age | Commit message (Collapse) | Author |
|
This reverts commit bd8f6106d44a58c261920eef72842bb3bc5a4968.
PLUS a little change in epmd_srv.c:750 ("4" -> "replylen")
that was part of e2cf4a8a4b03b9f430ba228276c3b2629159e832
by mistake.
|
|
* sverker/enable-big-creation/OTP-15603:
epmd: Support 32-bit creation values in local node
erts: Robustify epmd reply function
erts: Reject decoded local refs with too large first word
erts: Fix bug in list_to_ref
erl_interface: Remove old encoding of pid,port,refs
erts: Remove old encoding of pids, ports and refs
erts: Make DFLAG_BIG_CREATION mandatory
|
|
* Increase distribution version from 5 to 6
* Introduce new ALIVE2_X_RESP with 32-bit creation
as reply to ALIVE2_REQ when sender dist version >= 6
* Still reply old ALIVE2_RESP with tiny creation 1..3
if sender dist version < 6.
|
|
First word must be less than (1 bsl 18) for local refs.
|
|
This commit suppresses the following warning in gcc 4.8.2:
In file included from beam/bif.c:33:0:
beam/bif.c: In function ‘iolist_size_1’:
beam/bif.h:332:14: warning: ‘state_mref’ may be used uninitialized in this function [-Wmaybe-uninitialized]
reg[0] = (A0); \
^
beam/bif.c:2464:11: note: ‘state_mref’ was declared here
Eterm state_mref;
|
|
BEAM currently does not call BIFs at the end of a function in a
tail-recursive way. That is, when calling a BIF at the end of a
function, the BIF is first called, and then the stack frame
is deallocated, and then control is transferred to the caller.
If there is no stack frame when a BIF is called in the tail position,
the loader will emit a sequence of three instructions: first an
instruction that allocates a stack frame and saves the continuation
pointer (`allocate`), then an instruction that calls the BIF
(`call_bif`), and lastly an instruction that deallocates the stack
frame and returns to the caller (`deallocate_return`).
The old compiler would essentially allocate a stack frame for each
clause in a function, so it would not be that common that a BIF was
called in the tail position when there was no stack frame, so the
three-instruction sequence was deemed acceptable.
The new compiler only allocates stack frames when truly needed, so
the three-instruction BIF call sequence has become much more common.
This commit introduces a new `call_bif_only` instruction so that only
one instruction will be needed when calling a BIF in the tail position
when there is no stack frame. This instruction is also used when there
is a stack frame to make it possible to deallocate the stack frame
**before** calling the BIF, which may make a subsequent garbage
collection at the end of the BIF call cheaper (copying less garbage).
The one downside of this change is that the function that called the
BIF will not be included in the stack backtrace (similar to how a
tail-recursive call to an Erlang function will not be included in the
backtrace).
That was the quick summary of the commit. Here comes a detailed look
at how BIF calls are translated by the loader. The first example is a
function that calls `setelement/3` in the tail position:
update_no_stackframe(X) ->
setelement(5, X, new_value).
Here is the BEAM code:
{function, update_no_stackframe, 1, 12}.
{label,11}.
{line,[...]}.
{func_info,{atom,t},{atom,update_no_stackframe},1}.
{label,12}.
{move,{x,0},{x,1}}.
{move,{atom,new_value},{x,2}}.
{move,{integer,5},{x,0}}.
{line,[...]}.
{call_ext_only,3,{extfunc,erlang,setelement,3}}.
Because there is no stack frame, the `call_ext_only` instruction will
be used to call `setelement/3`:
{call_ext_only,3,{extfunc,erlang,setelement,3}}.
The loader will transform this instruction to a three-instruction
sequence:
0000000020BD8130: allocate_tt 0 3
0000000020BD8138: call_bif_e erlang:setelement/3
0000000020BD8148: deallocate_return_Q 0
Using the `call_bif_only` instruction introduced in this commit,
only one instruction is needed:
000000005DC377F0: call_bif_only_e erlang:setelement/3
`call_bif_only` calls the BIF and returns to the caller.
Now let's look at a function that already has a stack frame when
`setelement/3` is called:
update_with_stackframe(X) ->
foobar(X),
setelement(5, X, new_value).
Here is the BEAM code:
{function, update_with_stackframe, 1, 14}.
{label,13}.
{line,[...]}.
{func_info,{atom,t},{atom,update_with_stackframe},1}.
{label,14}.
{allocate,1,1}.
{move,{x,0},{y,0}}.
{line,[...]}.
{call,1,{f,16}}.
{move,{y,0},{x,1}}.
{move,{atom,new_value},{x,2}}.
{move,{integer,5},{x,0}}.
{line,[...]}.
{call_ext_last,3,{extfunc,erlang,setelement,3},1}.
Since there is a stack frame, the `call_ext_last` instruction will be used
to deallocate the stack frame and call the function:
{call_ext_last,3,{extfunc,erlang,setelement,3},1}.
Before this commit, the loader would translate this instruction to:
0000000020BD81B8: call_bif_e erlang:setelement/3
0000000020BD81C8: deallocate_return_Q 1
That is, the BIF is called before deallocating the stack frame and returning
to the calling function.
After this commit, the loader will translate the `call_ext_last` like this:
000000005DC37868: deallocate_Q 1
000000005DC37870: call_bif_only_e erlang:setelement/3
There are still two instructions, but now the stack frame will be
deallocated before calling the BIF, which could make the potential
garbage collection after the BIF call slightly more efficient (copying
less garbage).
We could have introduced a `call_bif_last` instruction, but the code
for calling a BIF is relatively large and there does not seem be a
practical way to share the code between `call_bif` and `call_bif_only`
(since the difference is at the end, after the BIF call). Therefore,
we did not want to clone the BIF calling code yet another time to
make a `call_bif_last` instruction.
|
|
Make iolist_size/1 yield
OTP-15631
|
|
The iolist_size/1 function did not yield even if the input list was
very long and a call to the function did only consume a single
reduction. This commit fixes these problems.
|
|
|
|
This commit removed the general send context (which was used
very little anyways) and only uses the distributed send context.
This will make it easier to use the dist API at the cost of
a little bit more code for the local send.
|
|
OTP-15612
|
|
|
|
Conflicts:
erts/emulator/beam/bif.c
erts/preloaded/ebin/erlang.beam
erts/preloaded/ebin/erts_internal.beam
erts/preloaded/ebin/prim_file.beam
|
|
* lukas/erts/set_logger_process/OTP-15375:
Update preloaded modules
erts: Add erlang:system_flag(system_logger,_)
|
|
This flag allows logger and other components to set the
process which log messages from ERTS are to be sent.
|
|
* maint:
Fix passing large integers as base to integer_to_X/2
|
|
I noticed this seconds after merging... :(
|
|
* maint:
Implement integer_to_list/2 and integer_to_binary/2 as CIFs
Accept base in all integer-printing functions
Document cleanup semantics for atomics and counters
|
|
This makes them roughly as fast as integer_to_list/1 and
integer_to_binary/1.
|
|
|
|
Conflicts:
erts/preloaded/ebin/atomics.beam
erts/preloaded/ebin/counters.beam
erts/preloaded/ebin/erl_prim_loader.beam
erts/preloaded/ebin/erl_tracer.beam
erts/preloaded/ebin/erlang.beam
erts/preloaded/ebin/erts_code_purger.beam
erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
erts/preloaded/ebin/erts_internal.beam
erts/preloaded/ebin/erts_literal_area_collector.beam
erts/preloaded/ebin/init.beam
erts/preloaded/ebin/otp_ring0.beam
erts/preloaded/ebin/persistent_term.beam
erts/preloaded/ebin/prim_buffer.beam
erts/preloaded/ebin/prim_eval.beam
erts/preloaded/ebin/prim_file.beam
erts/preloaded/ebin/prim_inet.beam
erts/preloaded/ebin/prim_zip.beam
erts/preloaded/ebin/zlib.beam
|
|
* lukas/erts/fix-seq_trace-reset_trace/OTP-15490:
erts: Fix seq_trace:reset_trace dirty gc bug
erts: Use sys_memcpy in copy_one_frag
|
|
When seq_trace:reset_trace could be called while a
process was doing a dirty GC. This triggered a race
where all signals was moved to the internal signal
queue during the GC which in turn caused the a heap
overrun problem.
This fix makes it so that the main and msgq lock are
taken before the clear. This will make sure that we
are allowed to do the clear.
|
|
* maint:
beam_lib: Remove obsolete module() from the beam() type
hipe: Don't use beam_lib:info/1 with an atom as filename
Honor the max heap size when copying literals after purging
|
|
When a module has been purged from memory, any literals belonging
to that module will be copied to all processes that hold references
to them.
The max heap size limit would be ignored in the garbage collection
initiated when copying literals to a process. If the max heap size
was exceeded, the process would typically be terminated in the
following garbage collection.
Since the process would be killed anyway later, kill the process
before copying a literal that would make it exceed its max heap
size.
While at it, also fix a potential bug in `erlang:garbage_collect/0`.
If it was found that the max heap sized had been exceeded while
executing `erlang:garbage_collect/0`, the process would enter a
kind of zombie state instead of being properly terminated.
|
|
* richcarl/erts/erl_init-cleanup/OTP-15336:
sasl: Order systools_make:preloaded modules alphabetically
Update preloaded modules
Move calling on_load for preloaded modules to erl_init
Make erl_init.c pass the boot module to erl_init.beam
Remove obsolete comment text
Remove undocumented and unused -# display_items emulator option
Remove broken and undocumented boot function emulator option
Replace remaining references to otp_ring0 with erl_init
Drop otp_ring0, using erl_init instead
Update preloaded modules
Add erl_init module
Conflicts:
erts/emulator/beam/erl_init.c
erts/preloaded/ebin/erl_prim_loader.beam
erts/preloaded/ebin/erl_tracer.beam
erts/preloaded/ebin/erlang.beam
erts/preloaded/ebin/erts_code_purger.beam
erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
erts/preloaded/ebin/erts_internal.beam
erts/preloaded/ebin/erts_literal_area_collector.beam
erts/preloaded/ebin/init.beam
erts/preloaded/ebin/otp_ring0.beam
erts/preloaded/ebin/prim_buffer.beam
erts/preloaded/ebin/prim_eval.beam
erts/preloaded/ebin/prim_file.beam
erts/preloaded/ebin/prim_inet.beam
erts/preloaded/ebin/prim_zip.beam
erts/preloaded/ebin/zlib.beam
|
|
"(void)result" will silence warning about unused variable
and compiler will optimize away such unused variables.
|
|
* max-au/dist_msg_too_long:
Cleanup unused dist output buf immediately instead of at GC
Throw 'system_limit' when distribution message size exceed INT_MAX instead of crashing emulator with 'Absurdly large distribution data buffer'
|
|
A lot of erts internal messages used behind APIs to create
non-blocking calls, e.g. port_command, would cause the seq_trace
token to be cleared from the caller when it should not.
This commit fixes that and adds asserts that makes sure
that all messages sent have to correct token set.
Fixes: ERL-602
|
|
|
|
|
|
of crashing emulator with 'Absurdly large distribution data buffer'
Exception must be thrown when buffer has been created and it's size is known. The actual buffer size is not known until the message has been encoded in ERTS_DSIG_SEND_PHASE_FIN. It would have been nice to abort before allocating and encoding, but in order to do that in a safe way the size calculation would need improvements. It is good enough to abort in the ERTS_DSIG_SEND_PHASE_FIN while we wait for the "fragmented distribution message" feature.
|
|
It is allowed to set the backtrace depth to 0, but when
an exception is catched the stacktrace will still contain
one element:
1> erlang:system_flag(backtrace_depth, 0).
8
2> catch error(badarg).
{'EXIT',{badarg,[{shell,apply_fun,3,
[{file,"shell.erl"},{line,908}]}]}}
However, when an exception is raised using `erlang:raise/3`, there
will be no elements in the stacktrace:
3> catch erlang:raise(error, badarg, [{fake,name,[arg],[]}]).
{'EXIT',{badarg,[]}}
Since the `error_handler` module uses `erlang:raise/3` to
raise an exception when an undefined function is called,
there will not be any stacktrace when calling an undefined
function:
4> catch undef_module:undef_name(some_argument).
{'EXIT',{undef,[]}}
Fix this inconsistency by changing `erlang:raise/3` so that
it always includes one element in the stacktrace:
3> catch erlang:raise(error, badarg, [{fake,name,[arg],[]}]).
{'EXIT',{badarg,[{fake,name,[arg],[]}]}}
4> catch undef_module:undef_name(some_argument).
{'EXIT',{undef,[{undef_module,undef_name,[some_argument],[]}]}}
|
|
|
|
|
|
Communication between Erlang processes has conceptually always been
performed through asynchronous signaling. The runtime system
implementation has however previously preformed most operation
synchronously. In a system with only one true thread of execution, this
is not problematic (often the opposite). In a system with multiple threads
of execution (as current runtime system implementation with SMP support)
it becomes problematic. This since it often involves locking of structures
when updating them which in turn cause resource contention. Utilizing
true asynchronous communication often avoids these resource contention
issues.
The case that triggered this change was contention on the link lock due
to frequent updates of the monitor trees during communication with a
frequently used server. The signal order delivery guarantees of the
language makes it hard to change the implementation of only some signals
to use true asynchronous signaling. Therefore the implementations
of (almost) all signals have been changed.
Currently the following signals have been implemented as true
asynchronous signals:
- Message signals
- Exit signals
- Monitor signals
- Demonitor signals
- Monitor triggered signals (DOWN, CHANGE, etc)
- Link signals
- Unlink signals
- Group leader signals
All of the above already defined as asynchronous signals in the
language. The implementation of messages signals was quite
asynchronous to begin with, but had quite strict delivery constraints
due to the ordering guarantees of signals between a pair of processes.
The previously used message queue partitioned into two halves has been
replaced by a more general signal queue partitioned into three parts
that service all kinds of signals. More details regarding the signal
queue can be found in comments in the erl_proc_sig_queue.h file.
The monitor and link implementations have also been completely replaced
in order to fit the new asynchronous signaling implementation as good
as possible. More details regarding the new monitor and link
implementations can be found in the erl_monitor_link.h file.
|
|
* john/erts/tuple-arityval-fixes/OTP-14963/ERL-577:
Make doc entry for maximum tuple size reflect reality
Assert that sz <= MAX_ARITYVAL in make_arityval(sz)
|
|
* john/erts/assert-on-memcpy-memset-etc:
Always use sys_memcpy/cmp/etc instead of plain memcpy/cmp/etc
Check the arguments to sys_memcpy and friends
|
|
|
|
|
|
|
|
into 'sverker/master/alloc-n-migration/ERIERL-88'
|
|
into 'sverker/maint-20/alloc-n-migration/ERIERL-88'
OTP-14915
OTP-14916
OTP-14917
OTP-14918
|
|
to change sbct limit in runtime for chosen allocator type.
With great power comes great responsibility.
|
|
The reduction cost of sending messages is now constant and will no
longer scale according to the length of the receiving process'
message queue.
|
|
|
|
|
|
|
|
Don't need to be pointer-pointer
|
|
The least bad behavior I think:
* We cannot return 'noconnect' as caller might already have enqueued
monitor/link that never triggers.
* We cannot block waiting for connection as that can ruin latency
when 'noconnect' is used to avoid blocking auto-connect
(see gen_server and gen_statem).
But there might be users getting more cases of bad latency
waiting for a pendig connection, instead of a fast 'noconnect'.
|