wingo pushed a commit to branch wip-whippet
in repository guile.
commit 50836264268baed97323b2f7a750a6fd6757d2ae
Author: Andy Wingo <[email protected]>
AuthorDate: Tue Aug 5 11:20:05 2025 +0200
Fix hole collection
---
src/mmc.c | 4 ++--
src/nofl-holeset.h | 1 +
src/nofl-space.h | 25 ++++++++++++++++---------
3 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/mmc.c b/src/mmc.c
index 0ad5e12b8..6d20cffa6 100644
--- a/src/mmc.c
+++ b/src/mmc.c
@@ -133,7 +133,7 @@ gc_trace_worker_call_with_data(void (*f)(struct gc_tracer
*tracer,
struct gc_heap *heap,
struct gc_trace_worker *worker) {
struct gc_trace_worker_data data;
- nofl_allocator_reset(&data.allocator);
+ nofl_allocator_init(&data.allocator);
f(tracer, heap, worker, &data);
nofl_allocator_finish(&data.allocator, heap_nofl_space(heap));
}
@@ -240,7 +240,7 @@ add_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
mut->heap = heap;
mut->event_listener_data =
heap->event_listener.mutator_added(heap->event_listener_data);
- nofl_allocator_reset(&mut->allocator);
+ nofl_allocator_init(&mut->allocator);
gc_field_set_writer_init(&mut->logger, &heap->remembered_set);
heap_lock(heap);
// We have no roots. If there is a GC currently in progress, we have
diff --git a/src/nofl-holeset.h b/src/nofl-holeset.h
index 6a3cfda9f..1cba592ec 100644
--- a/src/nofl-holeset.h
+++ b/src/nofl-holeset.h
@@ -115,6 +115,7 @@ nofl_holeset_try_pop(struct nofl_holeset *holes, size_t
granules) {
} else {
struct nofl_hole_with_size *hole_with_size = ret;
hole_granules = hole_with_size->granules;
+ GC_ASSERT(hole_granules);
hole_with_size->granules = 0;
}
diff --git a/src/nofl-space.h b/src/nofl-space.h
index a623acd8e..82dbfc5d9 100644
--- a/src/nofl-space.h
+++ b/src/nofl-space.h
@@ -614,6 +614,11 @@ static void
nofl_allocator_reset(struct nofl_allocator *alloc) {
alloc->alloc = alloc->sweep = 0;
alloc->block = nofl_block_null();
+}
+
+static void
+nofl_allocator_init(struct nofl_allocator *alloc) {
+ nofl_allocator_reset(alloc);
nofl_holeset_clear(&alloc->holes);
}
@@ -739,11 +744,12 @@ nofl_allocator_acquire_evacuation_target(struct
nofl_allocator* alloc,
return nofl_allocator_acquire_empty_block(alloc, space);
}
-static void
-nofl_allocator_finish_hole(struct nofl_allocator *alloc) {
+static inline void
+nofl_allocator_finish_hole(struct nofl_allocator *alloc, int collect_holes) {
size_t granules = (alloc->sweep - alloc->alloc) / NOFL_GRANULE_SIZE;
if (granules) {
- nofl_holeset_push_local(&alloc->holes, alloc->alloc, granules);
+ if (collect_holes)
+ nofl_holeset_push_local(&alloc->holes, alloc->alloc, granules);
alloc->block.summary->holes_with_fragmentation++;
alloc->block.summary->fragmentation_granules += granules;
alloc->alloc = alloc->sweep;
@@ -819,9 +825,10 @@ nofl_allocator_next_hole_in_block(struct nofl_allocator
*alloc,
static void
nofl_allocator_finish_sweeping_in_block(struct nofl_allocator *alloc,
- uint8_t survivor_mark) {
+ uint8_t survivor_mark,
+ int collect_holes) {
do {
- nofl_allocator_finish_hole(alloc);
+ nofl_allocator_finish_hole(alloc, collect_holes);
} while (nofl_allocator_next_hole_in_block(alloc, survivor_mark));
}
@@ -836,7 +843,7 @@ nofl_allocator_release_block(struct nofl_allocator *alloc,
} else if (space->evacuating) {
nofl_allocator_release_full_evacuation_target(alloc, space);
} else {
- nofl_allocator_finish_sweeping_in_block(alloc, space->survivor_mark);
+ nofl_allocator_finish_sweeping_in_block(alloc, space->survivor_mark, 1);
nofl_allocator_release_full_block(alloc, space);
}
}
@@ -867,7 +874,7 @@ nofl_allocator_next_hole_in_block_of_size(struct
nofl_allocator *alloc,
return 0;
while (1) {
- nofl_allocator_finish_hole(alloc);
+ nofl_allocator_finish_hole(alloc, min_granules != 0);
size_t granules =
nofl_allocator_next_hole_in_block(alloc, space->survivor_mark);
if (granules == 0) {
@@ -929,7 +936,7 @@ nofl_allocator_next_hole(struct nofl_allocator *alloc,
break;
if (min_granules <= granules)
return granules;
- nofl_allocator_finish_hole(alloc);
+ nofl_allocator_finish_hole(alloc, 1);
nofl_allocator_release_full_block(alloc, space);
}
@@ -1397,7 +1404,7 @@ nofl_space_promote_blocks(struct nofl_space *space) {
block.summary->holes_with_fragmentation = 0;
block.summary->fragmentation_granules = 0;
struct nofl_allocator alloc = { block.addr, block.addr, block };
- nofl_allocator_finish_sweeping_in_block(&alloc, space->current_mark);
+ nofl_allocator_finish_sweeping_in_block(&alloc, space->current_mark, 0);
atomic_fetch_add(&space->old_generation_granules,
NOFL_GRANULES_PER_BLOCK - block.summary->hole_granules);
nofl_block_list_push(&space->old, block);