summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-12-19 21:59:13 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-03-08 15:02:31 -0500
commitce22a3e2f2e8168f80d77807d79214e1cfbccb44 (patch)
tree48cefd6e71113693c421483c765d22580fcea273 /rts/sm
parent7c817c0a4ab857e03d09526a481f63e313598c5b (diff)
downloadhaskell-ce22a3e2f2e8168f80d77807d79214e1cfbccb44.tar.gz
nonmoving: Allow pinned gen0 objects to be WEAK keys
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/NonMovingMark.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index c4c43ad7dc..d46ace2849 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -1915,16 +1915,26 @@ static bool nonmovingIsNowAlive (StgClosure *p)
bdescr *bd = Bdescr((P_)p);
- // All non-static objects in the non-moving heap should be marked as
- // BF_NONMOVING
- ASSERT(bd->flags & BF_NONMOVING);
+ const uint16_t flags = bd->flags;
+ if (flags & BF_LARGE) {
+ if (flags & BF_PINNED && !(flags & BF_NONMOVING)) {
+ // In this case we have a pinned object living in a non-full
+ // accumulator block which was not promoted to the nonmoving
+ // generation. Assume that the object is alive.
+ // See #22014.
+ return true;
+ }
- if (bd->flags & BF_LARGE) {
+ ASSERT(bd->flags & BF_NONMOVING);
return (bd->flags & BF_NONMOVING_SWEEPING) == 0
// the large object wasn't in the snapshot and therefore wasn't marked
|| (bd->flags & BF_MARKED) != 0;
// The object was marked
} else {
+ // All non-static objects in the non-moving heap should be marked as
+ // BF_NONMOVING.
+ ASSERT(bd->flags & BF_NONMOVING);
+
struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
StgClosure *snapshot_loc =
(StgClosure *) nonmovingSegmentGetBlock(seg, nonmovingSegmentInfo(seg)->next_free_snap);