diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-10-22 19:10:23 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-03-08 15:02:30 -0500 |
commit | 2db92e015655e7fc22e559020572bf23233ffaae (patch) | |
tree | caed5d7f0376a0ac2844d3b2da630c0fa3dc63fe | |
parent | 58e53bc4d33dad76b3250997f1a8300d0041f387 (diff) | |
download | haskell-2db92e015655e7fc22e559020572bf23233ffaae.tar.gz |
nonmoving: Handle new closures in nonmovingIsNowAlive
We must conservatively assume that new closures are reachable since we
are not guaranteed to mark such blocks.
-rw-r--r-- | rts/sm/NonMoving.h | 12 | ||||
-rw-r--r-- | 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 1f82a77a93..5be85788d7 100644 --- a/rts/sm/NonMoving.h +++ b/rts/sm/NonMoving.h @@ -300,19 +300,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 f91bcbd58d..56cb73b5e4 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -1896,7 +1896,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); + } } } |