From b794e4663505a98d728943cb21edc735cd7d174b Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 16 May 2025 22:01:55 +0200 Subject: [PATCH] mmc: Grow the heap if collection fails to find space for large alloc For a pending large allocation, we will try to page out blocks from the nofl space. However sometimes we are not able to do so, especially if evacuation is unavailable, as in a heap-conservative configuration. In that case, if the heap is growable, grow the heap after GC if there are still bytes pending to page out. --- src/mmc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/mmc.c b/src/mmc.c index 375548701..79e6a709a 100644 --- a/src/mmc.c +++ b/src/mmc.c @@ -531,6 +531,23 @@ compute_progress(struct gc_heap *heap, uintptr_t allocation_since_last_gc) { return allocation_since_last_gc > nofl_space_fragmentation(nofl); } +static void +grow_heap_for_large_allocation_if_necessary(struct gc_heap *heap, + enum gc_collection_kind gc_kind, + int progress) +{ + if (progress || heap->sizer.policy == GC_HEAP_SIZE_FIXED) + return; + + struct nofl_space *nofl = heap_nofl_space(heap); + if (nofl_space_shrink (nofl, 0)) + return; + + ssize_t pending = nofl_space_request_release_memory(nofl, 0); + GC_ASSERT (pending > 0); + resize_heap(heap, heap->size + pending); +} + static int compute_success(struct gc_heap *heap, enum gc_collection_kind gc_kind, int progress) { @@ -833,6 +850,7 @@ collect(struct gc_mutator *mut, enum gc_collection_kind requested_kind) { DEBUG("--- total live bytes estimate: %zu\n", live_bytes_estimate); gc_heap_sizer_on_gc(heap->sizer, heap->size, live_bytes_estimate, pause_ns, resize_heap); + grow_heap_for_large_allocation_if_necessary(heap, gc_kind, progress); heap->size_at_last_gc = heap->size; HEAP_EVENT(heap, restarting_mutators); allow_mutators_to_continue(heap);