]> granicus.if.org Git - php/commitdiff
Fix garbage marking in gc_collect_roots()
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 6 Mar 2018 22:09:31 +0000 (23:09 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 7 Mar 2018 08:50:25 +0000 (09:50 +0100)
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.

Zend/zend_gc.c

index b3c1fc9f129c2d7c7b635b30cb15ac361432033a..4b2ed4af60af550fa372bb9db09619e99a5ed684 100644 (file)
@@ -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++;
        }