diff options
author | Sverker Eriksson <sverker@erlang.org> | 2022-04-27 19:04:39 +0200 |
---|---|---|
committer | Sverker Eriksson <sverker@erlang.org> | 2022-04-27 19:49:45 +0200 |
commit | 31fc39901c703131436feb5bf5541a54ea483ea5 (patch) | |
tree | 5bffa9ec02b33dc6427885c49106d061ef72f0e0 /erts/emulator/beam/erl_message.c | |
parent | 3ce345becdcbad8bb06b9c5e119b0787b9ba3913 (diff) | |
parent | 79c089adaa3a9017bafefd491eea49d68a8f727f (diff) | |
download | erlang-31fc39901c703131436feb5bf5541a54ea483ea5.tar.gz |
Merge branch 'sverker/24/erts/fix-factory-undo/OTP-18027' into maint
This merge commit contains a partial revert of
a96f282359cd5f9f035029e99b0a5db360651a94
as we merge an alternative fix to the same problem.
Diffstat (limited to 'erts/emulator/beam/erl_message.c')
-rw-r--r-- | erts/emulator/beam/erl_message.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 05d803168a..d183427165 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -1496,32 +1496,33 @@ void erts_factory_undo(ErtsHeapFactory* factory) } if (factory->mode == FACTORY_HALLOC) { - /* Reset all the heap fragments we've added. Note that we CANNOT - * free them, as someone else might have grabbed a reference to - * them (e.g. the callers of `erts_gc_after_bif_call_lhf`). - * - * The GC will get rid of these later on. Note that we leave - * `p->mbuf_sz` untouched to keep the memory pressure of these - * fragments. */ - for (bp = (factory->p)->mbuf; - bp != factory->heap_frags_saved; - bp = bp->next) { - ASSERT(bp->off_heap.first == NULL); - bp->used_size = 0; + /* Free heap frags + */ + bp = factory->p->mbuf; + if (bp != factory->heap_frags_saved) { + do { + ErlHeapFragment *next_bp = bp->next; + ASSERT(bp->off_heap.first == NULL); + ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG, (void *) bp, + ERTS_HEAP_FRAG_SIZE(bp->alloc_size)); + bp = next_bp; + } while (bp != factory->heap_frags_saved); + + factory->p->mbuf = bp; } - /* Roll back the size of the latest fragment not allocated by us, - * as we may have used a part of it. */ - if (bp != NULL) { - ASSERT(bp == factory->heap_frags_saved); - bp->used_size = factory->heap_frags_saved_used; - } + /* Rollback heap top + */ - /* Roll back heap top */ ASSERT(HEAP_START(factory->p) <= factory->original_htop); ASSERT(factory->original_htop <= HEAP_LIMIT(factory->p)); HEAP_TOP(factory->p) = factory->original_htop; + /* Fix last heap frag */ + if (factory->heap_frags_saved) { + ASSERT(factory->heap_frags_saved == factory->p->mbuf); + factory->heap_frags_saved->used_size = factory->heap_frags_saved_used; + } if (factory->message) { ASSERT(factory->message->data.attached != ERTS_MSG_COMBINED_HFRAG); ASSERT(!factory->message->data.heap_frag); |