Don't protect GC while destroying zvals. We may need to add GC
roots during this phase.
--- /dev/null
+--TEST--
+Bug #78589: Memory leak with GC + __destruct()
+--FILE--
+<?php
+
+class Test {
+ public function __destruct() {}
+}
+
+$test = new Test;
+$test->foo = [&$test->foo];
+$ary = [&$ary, $test];
+unset($ary, $test);
+gc_collect_cycles();
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
/* Destroy zvals */
GC_TRACE("Destroying zvals");
- GC_G(gc_protected) = 1;
current = GC_IDX2PTR(GC_FIRST_ROOT);
last = GC_IDX2PTR(GC_G(first_unused));
while (current != last) {
GC_TRACE("Collection finished");
GC_G(collected) += count;
- GC_G(gc_protected) = 0;
GC_G(gc_active) = 0;
}