diff options
author | Rickard Green <[email protected]> | 2016-05-26 16:23:24 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2016-05-26 16:52:23 +0200 |
commit | 20383144c26512fe33e72f49dff52dc628666923 (patch) | |
tree | 0dc34f60c76f300f0343dc58e13c611b14920159 | |
parent | 8241eb36a733d6fee7c4a6f12c8bdfc206889795 (diff) | |
download | otp-20383144c26512fe33e72f49dff52dc628666923.tar.gz otp-20383144c26512fe33e72f49dff52dc628666923.tar.bz2 otp-20383144c26512fe33e72f49dff52dc628666923.zip |
Improve message allocation in enif_send()
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 606b73c7b5..2bbb8e3c91 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -623,10 +623,28 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid, } } else { Uint sz = size_object(msg); + ErlOffHeap *ohp; Eterm *hp; - mp = erts_alloc_message(sz, &hp); - msg = copy_struct(msg, sz, &hp, &mp->hfrag.off_heap); - ASSERT(hp == mp->hfrag.mem+mp->hfrag.used_size); + if (env && !env->tracee) { + flush_env(env); + mp = erts_alloc_message_heap(rp, &rp_locks, sz, &hp, &ohp); + cache_env(env); + } + else { + erts_aint_t state = erts_smp_atomic32_read_nob(&rp->state); + if (state & ERTS_PSFLG_OFF_HEAP_MSGQ) { + mp = erts_alloc_message(sz, &hp); + ohp = sz == 0 ? NULL : &mp->hfrag.off_heap; + } + else { + ErlHeapFragment *bp = new_message_buffer(sz); + mp = erts_alloc_message(0, NULL); + mp->data.heap_frag = bp; + hp = bp->mem; + ohp = &bp->off_heap; + } + } + msg = copy_struct(msg, sz, &hp, ohp); } ERL_MESSAGE_TERM(mp) = msg; |