From eb7b233a3db9f3958bdf8d8eb6c76c6d9f00f5b9 Mon Sep 17 00:00:00 2001 From: Ben Gamari <ben@smart-cactus.org> Date: Sun, 17 Nov 2019 11:24:44 -0500 Subject: [PATCH] nonmoving: Fix handling on large object marking on 32-bit Previously we would reset the pointer pointing to the object to be marked to the beginning of the block when marking a large object. This did no harm on 64-bit but on 32-bit it broke, e.g. `arr020`, since we align pinned ByteArray allocations such that the payload is 8 byte-aligned. This means that the object might not begin at the beginning of the block., --- rts/sm/NonMovingMark.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index 638be30c200..085d7827df7 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -62,7 +62,13 @@ static void mark_PAP_payload (MarkQueue *queue, * collector and moved to nonmoving_large_objects during the next major GC. * When this happens the block gets its BF_NONMOVING_SWEEPING flag set to * indicate that it is part of the snapshot and consequently should be marked by - * the nonmoving mark phase.. + * the nonmoving mark phase. + * + * Note that pinned object blocks are treated as large objects containing only + * a single object. That is, the block has a single mark flag (BF_MARKED) and we + * consequently will trace the pointers of only one object per block. However, + * this is okay since the only type of pinned object supported by GHC is the + * pinned ByteArray#, which has no pointers. */ bdescr *nonmoving_large_objects = NULL; @@ -1281,9 +1287,6 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) if (bd->flags & BF_MARKED) { goto done; } - - // Mark contents - p = (StgClosure*)bd->start; } else { struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p); nonmoving_block_idx block_idx = nonmovingGetBlockIdx((StgPtr) p); -- GitLab