From: Petter A. Urkedal Date: Sun, 3 Dec 2017 11:42:59 +0000 (+0100) Subject: Fix marking of disclaim-reachable objects in the incremental mode X-Git-Tag: v7.4.8~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11bd89fd8976a787527d343f0a0b29afee9719b0;p=gc Fix marking of disclaim-reachable objects in the incremental mode Issue #192 (bdwgc). Unconditional marking is done analogously to marking from uncollectible blocks, since they are meant to secure access to data for disclaim notifiers after the data is no longer marked. * mark.c [ENABLE_DISCLAIM] (GC_push_next_marked_dirty): Honor MARK_UNCONDITIONALLY when rescanning dirty blocks during incremental marking. --- diff --git a/mark.c b/mark.c index ce012aed..4a189372 100644 --- a/mark.c +++ b/mark.c @@ -1908,7 +1908,21 @@ STATIC struct hblk * GC_push_next_marked(struct hblk *h) h += OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz); hhdr = HDR(h); } - GC_push_marked(h, hhdr); +# ifdef ENABLE_DISCLAIM + if ((hhdr -> hb_flags & MARK_UNCONDITIONALLY) != 0) { + GC_push_unconditionally(h, hhdr); + + /* Then we may ask, why not also add the MARK_UNCONDITIONALLY */ + /* case to GC_push_next_marked, which is also applied to */ + /* uncollectible blocks? But it seems to me that the function */ + /* does not need to scan uncollectible (and unconditionally */ + /* marked) blocks since those are already handled in the */ + /* MS_PUSH_UNCOLLECTABLE phase. */ + } else +# endif + /* else */ { + GC_push_marked(h, hhdr); + } return(h + OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz)); } #endif /* !GC_DISABLE_INCREMENTAL */