1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-06 09:30:29 +02:00

mmc: If growable and moveable heap, ensure evacuation reserve

This commit is contained in:
Andy Wingo 2025-07-04 10:16:43 +02:00
parent 9ac3cf1350
commit 60d6b9dcbf
2 changed files with 20 additions and 5 deletions

View file

@ -622,6 +622,9 @@ grow_heap_if_necessary(struct gc_heap *heap,
: 0;
size_t headroom = nofl_empty_block_count(nofl) * NOFL_BLOCK_SIZE;
headroom += nofl_space_evacuation_reserve_bytes(nofl);
needed_headroom += nofl_space_evacuation_minimum_reserve_bytes(nofl);
if (headroom < needed_headroom + pending)
resize_heap(heap, heap->size - headroom + needed_headroom + pending);
}

View file

@ -561,11 +561,16 @@ nofl_active_block_count(struct nofl_space *space) {
return total - unavailable;
}
static size_t
nofl_evacuation_block_count(struct nofl_space *space) {
return nofl_block_count(&space->evacuation_targets);
}
static int
nofl_maybe_push_evacuation_target(struct nofl_space *space,
struct nofl_block_ref block,
double reserve) {
size_t targets = nofl_block_count(&space->evacuation_targets);
size_t targets = nofl_evacuation_block_count(space);
size_t active = nofl_active_block_count(space);
if (targets >= ceil(active * reserve))
return 0;
@ -1182,7 +1187,14 @@ nofl_space_estimate_live_bytes_after_gc(struct nofl_space *space,
static size_t
nofl_space_evacuation_reserve_bytes(struct nofl_space *space) {
return nofl_block_count(&space->evacuation_targets) * NOFL_BLOCK_SIZE;
return nofl_evacuation_block_count(space) * NOFL_BLOCK_SIZE;
}
static size_t
nofl_space_evacuation_minimum_reserve_bytes(struct nofl_space *space) {
return
ceil(space->evacuation_minimum_reserve * nofl_active_block_count(space))
* NOFL_BLOCK_SIZE;
}
static size_t
@ -1321,7 +1333,7 @@ nofl_space_finish_evacuation(struct nofl_space *space,
space->evacuating = 0;
size_t active = nofl_active_block_count(space);
size_t reserve = ceil(space->evacuation_minimum_reserve * active);
GC_ASSERT(nofl_block_count(&space->evacuation_targets) == 0);
GC_ASSERT(nofl_evacuation_block_count(space) == 0);
while (reserve--) {
struct nofl_block_ref block = nofl_pop_empty_block_with_lock(space, lock);
if (nofl_block_is_null(block)) break;
@ -1533,7 +1545,7 @@ nofl_space_finish_gc(struct nofl_space *space,
// for allocation by the mutator.
size_t active = nofl_active_block_count(space);
size_t target = ceil(space->evacuation_minimum_reserve * active);
size_t reserve = nofl_block_count(&space->evacuation_targets);
size_t reserve = nofl_evacuation_block_count(space);
while (reserve-- > target)
nofl_push_empty_block(space,
nofl_block_list_pop(&space->evacuation_targets),
@ -1995,7 +2007,7 @@ nofl_space_shrink(struct nofl_space *space, size_t bytes) {
if (pending > 0) {
size_t active = nofl_active_block_count(space);
size_t target = ceil(space->evacuation_minimum_reserve * active);
ssize_t avail = nofl_block_count(&space->evacuation_targets);
ssize_t avail = nofl_evacuation_block_count(space);
while (avail-- > target && pending > 0) {
struct nofl_block_ref block =
nofl_block_list_pop(&space->evacuation_targets);