1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-03 18:50:19 +02:00

mmc: Add "headroom" for growable heaps that cannot defragment

This commit is contained in:
Andy Wingo 2025-05-22 14:57:34 +02:00
parent eab463bd6c
commit 1d157a133d
2 changed files with 25 additions and 13 deletions

View file

@ -575,20 +575,24 @@ compute_progress(struct gc_heap *heap, uintptr_t allocation_since_last_gc) {
} }
static void static void
grow_heap_for_large_allocation_if_necessary(struct gc_heap *heap, grow_heap_if_necessary(struct gc_heap *heap,
enum gc_collection_kind gc_kind, enum gc_collection_kind gc_kind,
int progress) int progress)
{ {
if (progress || heap->sizer.policy == GC_HEAP_SIZE_FIXED) if (heap->sizer.policy == GC_HEAP_SIZE_FIXED)
return; return;
struct nofl_space *nofl = heap_nofl_space(heap); struct nofl_space *nofl = heap_nofl_space(heap);
if (nofl_space_shrink (nofl, 0)) size_t pending = nofl_space_shrink(nofl, 0);
return;
ssize_t pending = nofl_space_request_release_memory(nofl, 0); size_t needed_headroom =
GC_ASSERT (pending > 0); GC_CONSERVATIVE_TRACE
resize_heap(heap, heap->size + pending); ? nofl_active_block_count (nofl) * NOFL_BLOCK_SIZE / 16
: 0;
size_t headroom = nofl_empty_block_count(nofl) * NOFL_BLOCK_SIZE;
if (headroom < needed_headroom + pending)
resize_heap(heap, heap->size - headroom + needed_headroom + pending);
} }
static int static int
@ -893,7 +897,7 @@ collect(struct gc_mutator *mut, enum gc_collection_kind requested_kind) {
DEBUG("--- total live bytes estimate: %zu\n", live_bytes_estimate); DEBUG("--- total live bytes estimate: %zu\n", live_bytes_estimate);
gc_heap_sizer_on_gc(heap->sizer, heap->size, live_bytes_estimate, pause_ns, gc_heap_sizer_on_gc(heap->sizer, heap->size, live_bytes_estimate, pause_ns,
resize_heap); resize_heap);
grow_heap_for_large_allocation_if_necessary(heap, gc_kind, progress); grow_heap_if_necessary(heap, gc_kind, progress);
heap->size_at_last_gc = heap->size; heap->size_at_last_gc = heap->size;
HEAP_EVENT(heap, restarting_mutators); HEAP_EVENT(heap, restarting_mutators);
allow_mutators_to_continue(heap); allow_mutators_to_continue(heap);
@ -992,7 +996,7 @@ allocate_large(struct gc_mutator *mut, size_t size,
nofl_space_request_release_memory(nofl_space, nofl_space_request_release_memory(nofl_space,
npages << lospace->page_size_log2); npages << lospace->page_size_log2);
while (!nofl_space_shrink(nofl_space, 0)) { while (nofl_space_shrink(nofl_space, 0)) {
if (!trigger_collection(mut, GC_COLLECTION_COMPACTING)) if (!trigger_collection(mut, GC_COLLECTION_COMPACTING))
return heap->allocation_failure(heap, size); return heap->allocation_failure(heap, size);
} }

View file

@ -520,6 +520,14 @@ nofl_pop_unavailable_block(struct nofl_space *space,
return nofl_block_null(); return nofl_block_null();
} }
static size_t
nofl_empty_block_count(struct nofl_space *space) {
struct gc_lock lock = nofl_space_lock(space);
size_t ret = nofl_block_count(&space->empty.list);
gc_lock_release(&lock);
return ret;
}
static void static void
nofl_push_empty_block(struct nofl_space *space, nofl_push_empty_block(struct nofl_space *space,
struct nofl_block_ref block, struct nofl_block_ref block,
@ -1807,7 +1815,7 @@ nofl_space_add_slabs(struct nofl_space *space, struct nofl_slab *slabs,
space->slabs[space->nslabs++] = slabs++; space->slabs[space->nslabs++] = slabs++;
} }
static int static size_t
nofl_space_shrink(struct nofl_space *space, size_t bytes) { nofl_space_shrink(struct nofl_space *space, size_t bytes) {
ssize_t pending = nofl_space_request_release_memory(space, bytes); ssize_t pending = nofl_space_request_release_memory(space, bytes);
struct gc_lock lock = nofl_space_lock(space); struct gc_lock lock = nofl_space_lock(space);
@ -1847,7 +1855,7 @@ nofl_space_shrink(struct nofl_space *space, size_t bytes) {
// It still may be the case we need to page out more blocks. Only evacuation // It still may be the case we need to page out more blocks. Only evacuation
// can help us then! // can help us then!
return pending <= 0; return pending <= 0 ? 0 : pending;
} }
static void static void