summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-10-22 19:10:23 +0000
committerZubin Duggal <zubin.duggal@gmail.com>2023-02-08 19:05:11 +0530
commitc7f6cc07cfe6f1d76a97918b5960883618930f31 (patch)
treeecc43c9eadd9c9a327304dba48ce66faacb1ce1d
parentf463d9e46ed694afdd66f264560289644c89734e (diff)
downloadhaskell-c7f6cc07cfe6f1d76a97918b5960883618930f31.tar.gz
nonmoving: Handle new closures in nonmovingIsNowAlive
(cherry picked from commit 36ca160d0f199a688cf5fbc91d4bb92d2d4ea14e)
-rw-r--r--rts/sm/NonMoving.h12
-rw-r--r--rts/sm/NonMovingMark.c14
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);
+ }
}
}