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.
This commit is contained in:
Nikita Popov 2018-03-06 23:09:31 +01:00
parent dcbac8ade6
commit 3b5b64ce75

View 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++;
}