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:
parent
eab463bd6c
commit
1d157a133d
2 changed files with 25 additions and 13 deletions
26
src/mmc.c
26
src/mmc.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue