Age | Commit message (Collapse) | Author |
|
Cost per string byte,
but we still don't yield mid-string.
|
|
by patching list length when we reach end of list.
And remove unnecessary traversals in is_string and is_external_string
beyond the max length for STRING_EXT.
|
|
|
|
|
|
* Make connection_id part of the distribution handle as {ConnId, DistEntry}
in order for BIFs to verify correct connection.
* Make distribution handle opaque to net_kernel.
* Remove some unsafe lockless reads of DistEntry.flags
* Change state ERTS_DE_STATE_EXITING to be more of an internal state that
prevents erts from enqueue, encode or schedule new data to be sent. Otherwise
it should behave like ERTS_DE_STATE_CONNECTED.
|
|
|
|
|
|
|
|
Just to simplify and get 4 distinctive states
IDLE, PENDING, CONNECTED and EXITING.
The old possible flag combos were:
0
PENDING
CONNECTED
CONNECTED|EXITING
EXITING
The two EXITING states did not serve any purpose
other then as a slight optimization in monitor_node(_,false,_)
to shortcut EXITING when there can be no monitors.
|
|
to only transcode if output buffer actually contains
unsupported BIT_BINARY_EXT or EXPORT_EXT.
|
|
|
|
|
|
by suppressing DOP_MONITOR_P, DOP_MONITOR_P_EXIT and DOP_DEMONITOR_P
if not supported by the remote node.
In 17e198d6ee60f7dec9abfed272cf4226aea44535
I changed the behavior of erlang:monitor
to not raise badarg for c-nodes but instead create
a monitor to only supervise the connection.
But I forgot to prevent DOP_MONITOR_P and friends from being
sent to the node that does not expect them.
Note: We test both DFLAG_DIST_MONITOR and DFLAG_DIST_MONITOR_NAME
for the node to support process monitoring. This is because
erl_interface is buggy as it sets DFLAG_DIST_MONITOR without
really supporting it.
ToDo: Should erl_interface stop setting DFLAG_DIST_MONITOR
or should we change the meaning of these flags?
|
|
When finalizing outgoing distribution messages
we transcode them into using tuple fallbacks if the
receiver does not support bitstrings and export-funs.
This can only happen if the message was first encoded toward
a pending connection when the receiver was unknown.
It's an optimistic approach optmimized for modern beam nodes,
that expect real bitstrings and funs (since <R13).
Only erl_interface/jinterface lack this support.
|
|
even when reds <= 1
Removed micro optimization for first fun variable
to make things simpler.
|
|
to avoid tuple fallbacks for export funs and bitstrings.
ToDo: Re-encode if receiver turn out to be erl_interface/jinterface.
|
|
|
|
|
|
Break out from 'flags' into new dedicated 'connection_id'
just for simplicity.
Also changed flags to low bits
and that affected enif_binary_to_term.
|
|
and remove ugly encoding fallback as {fun, ...}
DFLAGS_NEW_FUN_TAGS has been supported by vm/erl_interface/jinterface
since R13 or even older.
Renamed test case obsolete_funs to term2bin_tuple_fallbacks
and removed test for {fun,...} fallback
and added missing test for bitstring fallback {Binary, Bits}.
|
|
Distribution flag DFLAG_UTF8_ATOMS is supported since R16
and mandatory since 20.0.
|
|
Add 'used' option for binary_to_term/2
|
|
|
|
Reduce number of arguments to binary_to_term_int
and use the context struct instead.
|
|
For a long time, there has been the two macros IS_SSMALL() and
MY_IS_SSMALL() that do exactly the same thing.
There should only be one, and it should be called IS_SSMALL().
However, we must decide which implementation to use. When
MY_IS_SSMALL() was introduced a long time ago, it was the most
efficient. In a modern C compiler, there might not be any
difference.
To find out, I used the following small C program to examine
the code generation:
#include <stdio.h>
typedef unsigned int Uint32;
typedef unsigned long Uint64;
typedef long Sint;
#define SWORD_CONSTANT(Const) Const##L
#define SMALL_BITS (64-4)
#define MAX_SMALL ((SWORD_CONSTANT(1) << (SMALL_BITS-1))-1)
#define MIN_SMALL (-(SWORD_CONSTANT(1) << (SMALL_BITS-1)))
#define MY_IS_SSMALL32(x) (((Uint32) ((((x)) >> (SMALL_BITS-1)) + 1)) < 2)
#define MY_IS_SSMALL64(x) (((Uint64) ((((x)) >> (SMALL_BITS-1)) + 1)) < 2)
#define MY_IS_SSMALL(x) (sizeof(x) == sizeof(Uint32) ? MY_IS_SSMALL32(x) : MY_IS_SSMALL64(x))
#define IS_SSMALL(x) (((x) >= MIN_SMALL) && ((x) <= MAX_SMALL))
void original(Sint n)
{
if (IS_SSMALL(n)) {
printf("yes\n");
}
}
void enhanced(Sint n)
{
if (MY_IS_SSMALL(n)) {
printf("yes\n");
}
}
gcc 7.2 produced the following code for the original() function:
.LC0:
.string "yes"
original(long):
movabs rax, 576460752303423488
add rdi, rax
movabs rax, 1152921504606846975
cmp rdi, rax
jbe .L4
rep ret
.L4:
mov edi, OFFSET FLAT:.LC0
jmp puts
clang 5.0.0 produced the following code which is slightly better:
original(long):
movabs rax, 576460752303423488
add rax, rdi
shr rax, 60
jne .LBB0_1
mov edi, .Lstr
jmp puts # TAILCALL
.LBB0_1:
ret
.Lstr:
.asciz "yes"
However, in the context of beam_emu.c, clang could produce
similar to what gcc produced.
gcc 7.2 produced the following code when MY_IS_SSMALL() was used:
.LC0:
.string "yes"
enhanced(long):
sar rdi, 59
add rdi, 1
cmp rdi, 1
jbe .L4
rep ret
.L4:
mov edi, OFFSET FLAT:.LC0
jmp puts
clang produced similar code.
This code seems to be the cheapest. There are four instructions, and
there is no loading of huge integer constants.
|
|
Conflicts:
erts/emulator/sys/unix/sys.c
|
|
|
|
Conflicts:
erts/emulator/beam/bif.c
erts/emulator/beam/dist.c
erts/emulator/beam/dist.h
erts/emulator/beam/erl_bif_info.c
erts/emulator/beam/erl_node_tables.c
erts/emulator/beam/erl_node_tables.h
erts/emulator/beam/external.c
|
|
|
|
|
|
|
|
|
|
|
|
This reverts commit 65b04e233e09e3cc2e0fda3c28e155b95c5a4baf.
|
|
|
|
* sverker/refactor:
erts: Introduce struct binary_internals
erts: Introduce erts_bin_release
erts: Init refc=1 in erts_bin_drv_alloc*
erts: Init refc=1 in erts_bin_nrml_alloc
erts: Remove deliberate leak of hipe fun entries
erts: Remove hipe_bifs:remove_refs_from/1
Refactor hipe specific code to use ErtsCodeInfo
erts: Refactor ErtsCodeInfo.native
|
|
to replace macro ERTS_INTERNAL_BINARY_FIELDS
as header in Binary and friends.
|
|
Only term_to_binary needed some extra attention
as it used to initialize refc as 0 instead of 1.
|
|
term_to_binary will always generate utf8 atoms
ATOM_UTF8_EXT and SMALL_ATOM_UTF8_EXT.
Old latin1 atoms, ATOM_EXT and SMALL_ATOM_EXT, are still decoded.
|
|
when a recursive call to dec_term() has already done erts_factory_undo
and set factory->hp to NULL.
|
|
A magic destructor can return 0 and thereby take control
and prolong the lifetime of a magic binary.
|
|
|
|
|
|
Magic references are *intentionally* indistinguishable from ordinary
references for the Erlang software. Magic references do not change
the language, and are intended as a pure runtime internal optimization.
An ordinary reference is typically used as a key in some table. A
magic reference has a direct pointer to a reference counted magic
binary. This makes it possible to implement various things without
having to do lookups in a table, but instead access the data directly.
Besides very fast lookups this can also improve scalability by
removing a potentially contended table. A couple of examples of
planned future usage of magic references are ETS table identifiers,
and BIF timer identifiers.
Besides future optimizations using magic references it should also
be possible to replace the exposed magic binary cludge with magic
references. That is, magic binaries that are exposed as empty
binaries to the Erlang software.
|
|
* maint:
Atomic reference count of binaries also in non-SMP
Conflicts:
erts/emulator/beam/erl_fun.c
|
|
OTP-14202
* rickard/binary-refc:
Atomic reference count of binaries also in non-SMP
Conflicts:
erts/emulator/beam/beam_bp.c
|
|
NIF resources was not handled in a thread-safe manner in the runtime
system without SMP support.
As a consequence of this fix, the following driver functions are now
thread-safe also in the runtime system without SMP support:
- driver_free_binary()
- driver_realloc_binary()
- driver_binary_get_refc()
- driver_binary_inc_refc()
- driver_binary_dec_refc()
|
|
|
|
* sverker/bin2term-zlib-bug/ERL-340/OTP-14159:
erts: Fix binary_to_term for compressed and zlib >= v1.2.9
|
|
Problem: z_stream was incorrectly copied with memcpy
which just happened to work with zlib < v1.2.9.
Solution: Avoid copying z_stream.
|