1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-02 02:10: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
grow_heap_for_large_allocation_if_necessary(struct gc_heap *heap,
enum gc_collection_kind gc_kind,
int progress)
grow_heap_if_necessary(struct gc_heap *heap,
enum gc_collection_kind gc_kind,
int progress)
{
if (progress || heap->sizer.policy == GC_HEAP_SIZE_FIXED)
if (heap->sizer.policy == GC_HEAP_SIZE_FIXED)
return;
struct nofl_space *nofl = heap_nofl_space(heap);
if (nofl_space_shrink (nofl, 0))
return;
size_t pending = nofl_space_shrink(nofl, 0);
ssize_t pending = nofl_space_request_release_memory(nofl, 0);
GC_ASSERT (pending > 0);
resize_heap(heap, heap->size + pending);
size_t needed_headroom =
GC_CONSERVATIVE_TRACE
? 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
@ -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);
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);
grow_heap_if_necessary(heap, gc_kind, progress);
heap->size_at_last_gc = heap->size;
HEAP_EVENT(heap, restarting_mutators);
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,
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))
return heap->allocation_failure(heap, size);
}

View file

@ -520,6 +520,14 @@ nofl_pop_unavailable_block(struct nofl_space *space,
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
nofl_push_empty_block(struct nofl_space *space,
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++;
}
static int
static size_t
nofl_space_shrink(struct nofl_space *space, size_t bytes) {
ssize_t pending = nofl_space_request_release_memory(space, bytes);
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
// can help us then!
return pending <= 0;
return pending <= 0 ? 0 : pending;
}
static void