mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.1'
* PHP-8.1: Fix GH-9266: GC root buffer keeps growing when dtors are present
This commit is contained in:
commit
31a99331c1
2 changed files with 62 additions and 2 deletions
58
Zend/tests/gc_045.phpt
Normal file
58
Zend/tests/gc_045.phpt
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
--TEST--
|
||||||
|
GC 045: Total count persisted when GC is rerun due to destructor call
|
||||||
|
--INI--
|
||||||
|
zend.enable_gc=1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class GlobalData
|
||||||
|
{
|
||||||
|
public static Bar $bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Value
|
||||||
|
{
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
new Bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
GlobalData::$bar = $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo
|
||||||
|
{
|
||||||
|
public Foo $selfRef;
|
||||||
|
public Value $val;
|
||||||
|
|
||||||
|
public function __construct(Value $val)
|
||||||
|
{
|
||||||
|
$this->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)
|
||||||
|
}
|
|
@ -1469,12 +1469,13 @@ static void zend_gc_root_tmpvars(void);
|
||||||
|
|
||||||
ZEND_API int zend_gc_collect_cycles(void)
|
ZEND_API int zend_gc_collect_cycles(void)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int total_count = 0;
|
||||||
bool should_rerun_gc = 0;
|
bool should_rerun_gc = 0;
|
||||||
bool did_rerun_gc = 0;
|
bool did_rerun_gc = 0;
|
||||||
|
|
||||||
rerun_gc:
|
rerun_gc:
|
||||||
if (GC_G(num_roots)) {
|
if (GC_G(num_roots)) {
|
||||||
|
int count;
|
||||||
gc_root_buffer *current, *last;
|
gc_root_buffer *current, *last;
|
||||||
zend_refcounted *p;
|
zend_refcounted *p;
|
||||||
uint32_t gc_flags = 0;
|
uint32_t gc_flags = 0;
|
||||||
|
@ -1652,6 +1653,7 @@ rerun_gc:
|
||||||
|
|
||||||
GC_TRACE("Collection finished");
|
GC_TRACE("Collection finished");
|
||||||
GC_G(collected) += count;
|
GC_G(collected) += count;
|
||||||
|
total_count += count;
|
||||||
GC_G(gc_active) = 0;
|
GC_G(gc_active) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1668,7 +1670,7 @@ rerun_gc:
|
||||||
finish:
|
finish:
|
||||||
zend_get_gc_buffer_release();
|
zend_get_gc_buffer_release();
|
||||||
zend_gc_root_tmpvars();
|
zend_gc_root_tmpvars();
|
||||||
return count;
|
return total_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEND_API void zend_gc_get_status(zend_gc_status *status)
|
ZEND_API void zend_gc_get_status(zend_gc_status *status)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue