From c7f6cc07cfe6f1d76a97918b5960883618930f31 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 22 Oct 2022 19:10:23 +0000 Subject: nonmoving: Handle new closures in nonmovingIsNowAlive (cherry picked from commit 36ca160d0f199a688cf5fbc91d4bb92d2d4ea14e) --- rts/sm/NonMoving.h | 12 +++++------- rts/sm/NonMovingMark.c | 14 +++++++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h index 22dcd6e980..960a9a7825 100644 --- a/rts/sm/NonMoving.h +++ b/rts/sm/NonMoving.h @@ -289,19 +289,17 @@ INLINE_HEADER void nonmovingSetClosureMark(StgPtr p) nonmovingSetMark(nonmovingGetSegment(p), nonmovingGetBlockIdx(p)); } -/* Was the given closure marked this major GC cycle? */ -INLINE_HEADER bool nonmovingClosureMarkedThisCycle(StgPtr p) +INLINE_HEADER uint8_t nonmovingGetClosureMark(StgPtr p) { struct NonmovingSegment *seg = nonmovingGetSegment(p); nonmoving_block_idx blk_idx = nonmovingGetBlockIdx(p); - return nonmovingGetMark(seg, blk_idx) == nonmovingMarkEpoch; + return nonmovingGetMark(seg, blk_idx); } -INLINE_HEADER bool nonmovingClosureMarked(StgPtr p) +/* Was the given closure marked this major GC cycle? */ +INLINE_HEADER bool nonmovingClosureMarkedThisCycle(StgPtr p) { - struct NonmovingSegment *seg = nonmovingGetSegment(p); - nonmoving_block_idx blk_idx = nonmovingGetBlockIdx(p); - return nonmovingGetMark(seg, blk_idx) != 0; + return nonmovingGetClosureMark(p) == nonmovingMarkEpoch; } // Can be called during a major collection to determine whether a particular diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index b70b3234d0..27a23ed0f6 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -1861,7 +1861,19 @@ static bool nonmovingIsNowAlive (StgClosure *p) || (bd->flags & BF_MARKED) != 0; // The object was marked } else { - return nonmovingClosureMarkedThisCycle((P_)p); + struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p); + StgClosure *snapshot_loc = + (StgClosure *) nonmovingSegmentGetBlock(seg, nonmovingSegmentInfo(seg)->next_free_snap); + if (p >= snapshot_loc && nonmovingGetClosureMark((StgPtr) p) == 0) { + /* + * In this case we are looking at a block that wasn't allocated + * at the time that the snapshot was taken. As we do not mark such + * blocks, we must assume that it is reachable. + */ + return true; + } else { + return nonmovingClosureMarkedThisCycle((P_)p); + } } } -- cgit v1.2.1