diff options
author | Sverker Eriksson <[email protected]> | 2015-06-01 19:43:13 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2015-06-15 15:22:12 +0200 |
commit | 7c1ed37b4aa173181c4d45a2108f5eef4c36c41e (patch) | |
tree | 39591f16aaff0f9dd18c9a0424b6ef9e88a1f417 /erts/emulator/beam | |
parent | 02d0ce034598297565f2b35ecc3d1af121787f33 (diff) | |
download | otp-7c1ed37b4aa173181c4d45a2108f5eef4c36c41e.tar.gz otp-7c1ed37b4aa173181c4d45a2108f5eef4c36c41e.tar.bz2 otp-7c1ed37b4aa173181c4d45a2108f5eef4c36c41e.zip |
erts: Optimize driver_deliver_term
Try write directly to process heap (as before)
if the term is guaranteed not to contain any
big maps that may break the initial size estimation.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/io.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 07a82b42d2..fb030d61f9 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -5108,12 +5108,16 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) ErlDrvTermData* ptr; ErlDrvTermData* ptr_end; DECLARE_ESTACK(stack); - Eterm mess = NIL; /* keeps compiler happy */ + Eterm mess; Process* rp = NULL; ErtsHeapFactory factory; ErtsProcLocks rp_locks = 0; struct b2t_states__ b2t; - int scheduler = 1; /* Silence erroneous warning... */ + int scheduler; + int is_heap_need_limited = 1; + + ERTS_UNDEF(mess,NIL); + ERTS_UNDEF(scheduler,1); factory.mode = FACTORY_CLOSED; init_b2t_states(&b2t); @@ -5286,6 +5290,9 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) need += hsz; ptr += 2; depth++; + if (size > MAP_SMALL_MAP_LIMIT*3) { /* may contain big map */ + is_heap_need_limited = 0; + } break; } case ERL_DRV_MAP: { /* int */ @@ -5293,6 +5300,7 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) if ((int) ptr[0] < 0) ERTS_DDT_FAIL; if (ptr[0] > MAP_SMALL_MAP_LIMIT) { need += HASHMAP_ESTIMATED_HEAP_SIZE(ptr[0]); + is_heap_need_limited = 0; } else { need += MAP_HEADER_FLATMAP_SZ + 1 + 2*ptr[0]; } @@ -5331,14 +5339,17 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) goto done; } - - /* We could try to copy directly to destination heap - * if we knew there is no big maps. - - erts_alloc_message_heap(need, &bp, &ohp, rp, &rp_locks); - */ - erts_factory_message_init(&factory, NULL, NULL, - new_message_buffer(need)); + /* Try copy directly to destination heap if we know there are no big maps */ + if (is_heap_need_limited) { + ErlOffHeap *ohp; + ErlHeapFragment* bp; + Eterm* hp = erts_alloc_message_heap(need, &bp, &ohp, rp, &rp_locks); + erts_factory_message_init(&factory, rp, hp, bp); + } + else { + erts_factory_message_init(&factory, NULL, NULL, + new_message_buffer(need)); + } /* * Interpret the instructions and build the term. |