wingo pushed a commit to branch wip-whippet in repository guile. commit 96b68095b72a9c11c62dfeed1e031f9ae818df86 Author: Andy Wingo <wi...@igalia.com> AuthorDate: Wed Aug 3 12:06:19 2022 +0200
Fix mark pattern updating for generational whippet After a minor collection, we were erroneously failing to sweep dead objects with the survivor tag. --- whippet.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/whippet.h b/whippet.h index 63ee0262e..b533093f5 100644 --- a/whippet.h +++ b/whippet.h @@ -1032,6 +1032,7 @@ heap_object_is_young(struct heap *heap, struct gcobj *obj) { static void mark_space_trace_generational_roots(struct mark_space *space, struct heap *heap) { + ASSERT(!space->evacuating); uint8_t live_tenured_mask = space->live_mask; for (size_t s = 0; s < space->nslabs; s++) { struct slab *slab = &space->slabs[s]; @@ -1045,7 +1046,7 @@ static void mark_space_trace_generational_roots(struct mark_space *space, // We could accelerate this but GRANULES_PER_REMSET_BYTE is 16 // on 64-bit hosts, so maybe it's not so important. for (size_t granule = base; granule < limit; granule++) { - if (slab->metadata[granule] & live_tenured_mask) { + if (slab->metadata[granule] & space->live_mask) { struct block *block0 = &slab->blocks[0]; uintptr_t addr = ((uintptr_t)block0->data) + granule * GRANULE_SIZE; struct gcobj *obj = (struct gcobj*)addr; @@ -1141,9 +1142,13 @@ static uint64_t broadcast_byte(uint8_t byte) { return result * 0x0101010101010101ULL; } -static void rotate_mark_bytes(struct mark_space *space) { - space->live_mask = rotate_dead_survivor_marked(space->live_mask); - space->marked_mask = rotate_dead_survivor_marked(space->marked_mask); +static void update_mark_patterns(struct mark_space *space, + int advance_mark_mask) { + uint8_t survivor_mask = space->marked_mask; + uint8_t next_marked_mask = rotate_dead_survivor_marked(survivor_mask); + if (advance_mark_mask) + space->marked_mask = next_marked_mask; + space->live_mask = survivor_mask | next_marked_mask; space->sweep_mask = broadcast_byte(space->live_mask); } @@ -1410,8 +1415,7 @@ static void mark_space_finish_gc(struct mark_space *space, enum gc_kind gc_kind) { space->evacuating = 0; reset_sweeper(space); - if ((gc_kind & GC_KIND_FLAG_MINOR) == 0) - rotate_mark_bytes(space); + update_mark_patterns(space, 0); reset_statistics(space); release_evacuation_target_blocks(space); } @@ -1426,6 +1430,7 @@ static void collect(struct mutator *mut) { } DEBUG("start collect #%ld:\n", heap->count); enum gc_kind gc_kind = determine_collection_kind(heap); + update_mark_patterns(space, !(gc_kind & GC_KIND_FLAG_MINOR)); large_object_space_start_gc(lospace, gc_kind & GC_KIND_FLAG_MINOR); tracer_prepare(heap); request_mutators_to_stop(heap); @@ -1906,12 +1911,8 @@ static int mark_space_init(struct mark_space *space, struct heap *heap) { if (!slabs) return 0; - uint8_t dead = METADATA_BYTE_MARK_0; - uint8_t survived = METADATA_BYTE_MARK_1; - uint8_t marked = METADATA_BYTE_MARK_2; - space->marked_mask = marked; - space->live_mask = survived | marked; - rotate_mark_bytes(space); + space->marked_mask = METADATA_BYTE_MARK_0; + update_mark_patterns(space, 0); space->slabs = slabs; space->nslabs = nslabs; space->low_addr = (uintptr_t) slabs;