aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/io.c
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2015-06-01 19:43:13 +0200
committerSverker Eriksson <[email protected]>2015-06-15 15:22:12 +0200
commit7c1ed37b4aa173181c4d45a2108f5eef4c36c41e (patch)
tree39591f16aaff0f9dd18c9a0424b6ef9e88a1f417 /erts/emulator/beam/io.c
parent02d0ce034598297565f2b35ecc3d1af121787f33 (diff)
downloadotp-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/io.c')
-rw-r--r--erts/emulator/beam/io.c31
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.