From c29ae3897499bc54b01935fc3bfef6e274de1c9b Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 19 Apr 2022 22:35:26 +0200 Subject: erts: Fix bug in erts_factory_proc_prealloc_init causing erts_factory_undo() to leave garbage in already existing heap fragment. --- erts/emulator/beam/erl_message.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam/erl_message.c') diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 9068ee65ad..5fcc0d8ba6 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -1187,6 +1187,10 @@ void erts_factory_proc_init(ErtsHeapFactory* factory, Process* p) heap as that completely destroys the DEBUG emulators performance. */ ErlHeapFragment *bp = p->mbuf; + + factory->heap_frags_saved = bp; + factory->heap_frags_saved_used = bp ? bp->used_size : 0; + factory->mode = FACTORY_HALLOC; factory->p = p; factory->hp_start = HEAP_TOP(p); @@ -1196,8 +1200,6 @@ void erts_factory_proc_init(ErtsHeapFactory* factory, Process* p) factory->message = NULL; factory->off_heap_saved.first = p->off_heap.first; factory->off_heap_saved.overhead = p->off_heap.overhead; - factory->heap_frags_saved = bp; - factory->heap_frags_saved_used = bp ? bp->used_size : 0; factory->heap_frags = NULL; /* not used */ factory->alloc_type = 0; /* not used */ @@ -1209,6 +1211,13 @@ void erts_factory_proc_prealloc_init(ErtsHeapFactory* factory, Sint size) { ErlHeapFragment *bp = p->mbuf; + + /* `bp->used_size` must be set _BEFORE_ we call `HAlloc`, as that will + * update the used size and prevent us from undoing the changes later + * on. */ + factory->heap_frags_saved = bp; + factory->heap_frags_saved_used = bp ? bp->used_size : 0; + factory->mode = FACTORY_HALLOC; factory->p = p; factory->hp_start = HAlloc(p, size); @@ -1218,8 +1227,6 @@ void erts_factory_proc_prealloc_init(ErtsHeapFactory* factory, factory->message = NULL; factory->off_heap_saved.first = p->off_heap.first; factory->off_heap_saved.overhead = p->off_heap.overhead; - factory->heap_frags_saved = bp; - factory->heap_frags_saved_used = bp ? bp->used_size : 0; factory->heap_frags = NULL; /* not used */ factory->alloc_type = 0; /* not used */ } -- cgit v1.2.1 From 7b6ec401d49195ab4453820388afbbecaca2a032 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 19 Apr 2022 22:43:08 +0200 Subject: erts: Make erts_factory_undo leave empty heap fragment if it was empty when we started. --- erts/emulator/beam/erl_message.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'erts/emulator/beam/erl_message.c') diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 5fcc0d8ba6..75b7656b90 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -1624,13 +1624,7 @@ void erts_factory_undo(ErtsHeapFactory* factory) /* Fix last heap frag */ if (factory->heap_frags_saved) { ASSERT(factory->heap_frags_saved == factory->p->mbuf); - if (factory->hp_start != factory->heap_frags_saved->mem) - factory->heap_frags_saved->used_size = factory->heap_frags_saved_used; - else { - factory->p->mbuf = factory->p->mbuf->next; - ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG, factory->heap_frags_saved, - ERTS_HEAP_FRAG_SIZE(factory->heap_frags_saved->alloc_size)); - } + factory->heap_frags_saved->used_size = factory->heap_frags_saved_used; } if (factory->message) { ASSERT(factory->message->data.attached != ERTS_MSG_COMBINED_HFRAG); -- cgit v1.2.1