summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-03-06 23:09:31 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-03-07 09:50:25 +0100
commit3b5b64ce75b00a00a256f1a59655a0830d071036 (patch)
treea000feac3908e3b767de4ca063b52e1ffb172aa8
parentdcbac8ade6d45ee4a34dfaec0f20aa7700e84dad (diff)
downloadphp-git-3b5b64ce75b00a00a256f1a59655a0830d071036.tar.gz
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.
-rw-r--r--Zend/zend_gc.c9
1 files changed, 4 insertions, 5 deletions
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++;
}