diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-12-19 21:59:13 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-03-08 15:02:31 -0500 |
commit | ce22a3e2f2e8168f80d77807d79214e1cfbccb44 (patch) | |
tree | 48cefd6e71113693c421483c765d22580fcea273 /rts/sm | |
parent | 7c817c0a4ab857e03d09526a481f63e313598c5b (diff) | |
download | haskell-ce22a3e2f2e8168f80d77807d79214e1cfbccb44.tar.gz |
nonmoving: Allow pinned gen0 objects to be WEAK keys
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/NonMovingMark.c | 18 |
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); |