summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-08-13 12:17:08 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-08-13 12:17:08 +0200
commit72b7d99d0db162a7118a36431f99a60a4fb39ef8 (patch)
tree2ba2bc8428470ec417e843f0e92b93884d2ad7f9
parentf0f3fe0b6c2eb93ff01058f389e6ae2a93ea20d4 (diff)
downloadphp-git-72b7d99d0db162a7118a36431f99a60a4fb39ef8.tar.gz
Remove removed nested data from GC count
-rw-r--r--Zend/tests/gc_041.phpt5
-rw-r--r--Zend/zend_gc.c27
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++;