diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-08-13 12:17:08 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-08-13 12:17:08 +0200 |
commit | 72b7d99d0db162a7118a36431f99a60a4fb39ef8 (patch) | |
tree | 2ba2bc8428470ec417e843f0e92b93884d2ad7f9 | |
parent | f0f3fe0b6c2eb93ff01058f389e6ae2a93ea20d4 (diff) | |
download | php-git-72b7d99d0db162a7118a36431f99a60a4fb39ef8.tar.gz |
Remove removed nested data from GC count
-rw-r--r-- | Zend/tests/gc_041.phpt | 5 | ||||
-rw-r--r-- | Zend/zend_gc.c | 27 |
2 files changed, 18 insertions, 14 deletions
diff --git a/Zend/tests/gc_041.phpt b/Zend/tests/gc_041.phpt index 7400e23756..fc849991e1 100644 --- a/Zend/tests/gc_041.phpt +++ b/Zend/tests/gc_041.phpt @@ -18,10 +18,11 @@ $o->nested[] =& $o->nested; $o->ryat = $o; $x =& $o->chtg; unset($o); -gc_collect_cycles(); +var_dump(gc_collect_cycles()); var_dump($x); ?> --EXPECT-- +int(0) object(ryat)#1 (3) { ["ryat"]=> *RECURSION* @@ -32,4 +33,4 @@ object(ryat)#1 (3) { [0]=> *RECURSION* } -}
\ No newline at end of file +} diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 199387643d..e1c2295d74 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1318,11 +1318,12 @@ static int gc_collect_roots(uint32_t *flags, gc_stack *stack) return count; } -static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffer *root) +static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffer *root) { HashTable *ht = NULL; Bucket *p, *end; zval *zv; + int count = 0; tail_call: do { @@ -1331,18 +1332,20 @@ tail_call: gc_remove_from_roots(root); GC_REF_SET_INFO(ref, 0); root = NULL; + count++; } else if (GC_REF_ADDRESS(ref) != 0 && GC_REF_CHECK_COLOR(ref, GC_BLACK)) { GC_TRACE_REF(ref, "removing from buffer"); GC_REMOVE_FROM_BUFFER(ref); + count++; } else if (GC_TYPE(ref) == IS_REFERENCE) { if (Z_REFCOUNTED(((zend_reference*)ref)->val)) { ref = Z_COUNTED(((zend_reference*)ref)->val); goto tail_call; } - return; + return count; } else { - return; + return count; } if (GC_TYPE(ref) == IS_OBJECT) { @@ -1357,15 +1360,15 @@ tail_call: ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { - if (!n) return; + if (!n) return count; while (!Z_REFCOUNTED_P(--end)) { - if (zv == end) return; + if (zv == end) return count; } } while (zv != end) { if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - gc_remove_nested_data_from_buffer(ref, NULL); + count += gc_remove_nested_data_from_buffer(ref, NULL); } zv++; } @@ -1374,15 +1377,15 @@ tail_call: goto tail_call; } } else { - return; + return count; } } else if (GC_TYPE(ref) == IS_ARRAY) { ht = (zend_array*)ref; } else { - return; + return count; } - if (!ht->nNumUsed) return; + if (!ht->nNumUsed) return count; p = ht->arData; end = p + ht->nNumUsed; while (1) { @@ -1394,7 +1397,7 @@ tail_call: if (Z_REFCOUNTED_P(zv)) { break; } - if (p == end) return; + if (p == end) return count; } while (p != end) { zv = &p->val; @@ -1403,7 +1406,7 @@ tail_call: } if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - gc_remove_nested_data_from_buffer(ref, NULL); + count += gc_remove_nested_data_from_buffer(ref, NULL); } p++; } @@ -1510,7 +1513,7 @@ ZEND_API int zend_gc_collect_cycles(void) if (GC_IS_GARBAGE(current->ref)) { p = GC_GET_PTR(current->ref); if (GC_REFCOUNT(p) > refcounts[idx]) { - gc_remove_nested_data_from_buffer(p, current); + count -= gc_remove_nested_data_from_buffer(p, current); } } current++; |