summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_message.c
diff options
context:
space:
mode:
authorSverker Eriksson <sverker@erlang.org>2022-04-27 19:04:39 +0200
committerSverker Eriksson <sverker@erlang.org>2022-04-27 19:49:45 +0200
commit31fc39901c703131436feb5bf5541a54ea483ea5 (patch)
tree5bffa9ec02b33dc6427885c49106d061ef72f0e0 /erts/emulator/beam/erl_message.c
parent3ce345becdcbad8bb06b9c5e119b0787b9ba3913 (diff)
parent79c089adaa3a9017bafefd491eea49d68a8f727f (diff)
downloaderlang-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.c39
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);