From: Nikita Popov Date: Tue, 6 Mar 2018 22:09:31 +0000 (+0100) Subject: Fix garbage marking in gc_collect_roots() X-Git-Tag: php-7.3.0alpha1~237 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b5b64ce75b00a00a256f1a59655a0830d071036;p=php Fix garbage marking in gc_collect_roots() gc_collect_white() will mark white nodes as black and add them as garbage, but only if it's not buffered yet. The already buffered roots are instead marked as garbage in gc_collect_roots() directly. However, if gc_collect_white() marked a (buffered) root as black through recursion, it would not subsequently be marked as garbage. --- diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index b3c1fc9f12..4b2ed4af60 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1167,11 +1167,10 @@ static int gc_collect_roots(uint32_t *flags) while (idx != end) { current = GC_IDX2PTR(idx); ref = current->ref; - if (GC_IS_ROOT(ref)) { - if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) { - current->ref = GC_MAKE_GARBAGE(ref); - count += gc_collect_white(ref, flags); - } + ZEND_ASSERT(GC_IS_ROOT(ref)); + current->ref = GC_MAKE_GARBAGE(ref); + if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) { + count += gc_collect_white(ref, flags); } idx++; }