aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_message.c
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2015-12-03 15:34:14 +0100
committerSverker Eriksson <[email protected]>2015-12-07 18:02:52 +0100
commitce8279d6a48d41f9de577825844f499bb3084b96 (patch)
tree094be4e1fabf2eb19c9a747e687b49e79337f263 /erts/emulator/beam/erl_message.c
parent75ef9b7cae7533fb9be7953ac72f743b055d2a7a (diff)
downloadotp-ce8279d6a48d41f9de577825844f499bb3084b96.tar.gz
otp-ce8279d6a48d41f9de577825844f499bb3084b96.tar.bz2
otp-ce8279d6a48d41f9de577825844f499bb3084b96.zip
erts: Fix bug for remote control message containing fat maps
that could cause the static factory to overflow Fix: Introduce a new factory mode FACTORY_TMP
Diffstat (limited to 'erts/emulator/beam/erl_message.c')
-rw-r--r--erts/emulator/beam/erl_message.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 2a703fb102..fa6b2fc613 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -1174,6 +1174,9 @@ void erts_factory_message_init(ErtsHeapFactory* factory,
ASSERT(factory->hp >= factory->hp_start && factory->hp <= factory->hp_end);
}
+/* One static sized heap that must suffice.
+ No extra heap fragments will be allocated.
+*/
void erts_factory_static_init(ErtsHeapFactory* factory,
Eterm* hp,
Uint size,
@@ -1188,6 +1191,23 @@ void erts_factory_static_init(ErtsHeapFactory* factory,
factory->off_heap_saved.overhead = factory->off_heap->overhead;
}
+/* A temporary heap with default buffer allocated/freed by client.
+ * factory_close is same as factory_undo
+ */
+void erts_factory_tmp_init(ErtsHeapFactory* factory, Eterm* hp, Uint size,
+ Uint32 atype)
+{
+ factory->mode = FACTORY_TMP;
+ factory->hp_start = hp;
+ factory->hp = hp;
+ factory->hp_end = hp + size;
+ factory->heap_frags = NULL;
+ factory->off_heap_saved.first = NULL;
+ factory->off_heap_saved.overhead = 0;
+ factory->off_heap = &factory->off_heap_saved;
+ factory->alloc_type = atype;
+}
+
/* When we know the term is an immediate and need no heap.
*/
void erts_factory_dummy_init(ErtsHeapFactory* factory)
@@ -1231,6 +1251,7 @@ static void reserve_heap(ErtsHeapFactory* factory, Uint need, Uint xtra)
return;
case FACTORY_HEAP_FRAGS:
+ case FACTORY_TMP:
bp = factory->heap_frags;
if (bp) {
@@ -1280,6 +1301,9 @@ void erts_factory_close(ErtsHeapFactory* factory)
bp->used_size = factory->hp - bp->mem;
}
break;
+ case FACTORY_TMP:
+ erts_factory_undo(factory);
+ break;
case FACTORY_STATIC: break;
case FACTORY_CLOSED: break;
default:
@@ -1371,19 +1395,20 @@ void erts_factory_undo(ErtsHeapFactory* factory)
}
break;
+ case FACTORY_TMP:
case FACTORY_HEAP_FRAGS:
erts_cleanup_offheap(factory->off_heap);
factory->off_heap->first = NULL;
bp = factory->heap_frags;
- do {
+ while (bp != NULL) {
ErlHeapFragment* next_bp = bp->next;
ASSERT(bp->off_heap.first == NULL);
ERTS_HEAP_FREE(factory->alloc_type, (void *) bp,
ERTS_HEAP_FRAG_SIZE(bp->alloc_size));
bp = next_bp;
- }while (bp != NULL);
+ }
break;
case FACTORY_CLOSED: break;