From 0709578517e4367f8b69d013f0f30c3a21624fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Ols=CC=8Cavsky=CC=81?= Date: Mon, 8 Aug 2022 18:47:21 +0200 Subject: [PATCH] Fix GH-9266: GC root buffer keeps growing when dtors are present Do not reset cleared count on GC rerun. Closes GH-9265. --- NEWS | 2 ++ Zend/tests/gc_045.phpt | 58 ++++++++++++++++++++++++++++++++++++++++++ Zend/zend_gc.c | 6 +++-- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/gc_045.phpt diff --git a/NEWS b/NEWS index d2dcfbce70c..d274cbe5e04 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed --CGI-- support of run-tests.php. (cmb) . Fixed incorrect double to long casting in latest clang. (zeriyoshi) + . Fixed bug GH-9266 (GC root buffer keeps growing when dtors are present). + (Michael Olšavský) - Date: . Fixed bug GH-8730 (DateTime::diff miscalculation is same time zone of diff --git a/Zend/tests/gc_045.phpt b/Zend/tests/gc_045.phpt new file mode 100644 index 00000000000..865462ecfbc --- /dev/null +++ b/Zend/tests/gc_045.phpt @@ -0,0 +1,58 @@ +--TEST-- +GC 045: Total count persisted when GC is rerun due to destructor call +--INI-- +zend.enable_gc=1 +--FILE-- +val = $val; + $this->selfRef = $this; + } +} + +for ($j = 0; $j < 10; $j++) { + for ($i = 0; $i < 3000; $i++) { + new Foo(new Value()); + } +} + +var_dump(gc_status()); +?> +--EXPECT-- +array(4) { + ["runs"]=> + int(10) + ["collected"]=> + int(25000) + ["threshold"]=> + int(10001) + ["roots"]=> + int(10000) +} diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 5c7a73aa273..f062747eaeb 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1439,12 +1439,13 @@ static void zend_gc_root_tmpvars(void); ZEND_API int zend_gc_collect_cycles(void) { - int count = 0; + int total_count = 0; bool should_rerun_gc = 0; bool did_rerun_gc = 0; rerun_gc: if (GC_G(num_roots)) { + int count; gc_root_buffer *current, *last; zend_refcounted *p; uint32_t gc_flags = 0; @@ -1622,6 +1623,7 @@ rerun_gc: GC_TRACE("Collection finished"); GC_G(collected) += count; + total_count += count; GC_G(gc_active) = 0; } @@ -1638,7 +1640,7 @@ rerun_gc: finish: zend_get_gc_buffer_release(); zend_gc_root_tmpvars(); - return count; + return total_count; } ZEND_API void zend_gc_get_status(zend_gc_status *status)