Skip to content

Commit 31a9933

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix GH-9266: GC root buffer keeps growing when dtors are present
2 parents 3a843f9 + 0709578 commit 31a9933

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

Zend/tests/gc_045.phpt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
GC 045: Total count persisted when GC is rerun due to destructor call
3+
--INI--
4+
zend.enable_gc=1
5+
--FILE--
6+
<?php
7+
class GlobalData
8+
{
9+
public static Bar $bar;
10+
}
11+
12+
class Value
13+
{
14+
public function __destruct()
15+
{
16+
new Bar();
17+
}
18+
}
19+
20+
class Bar
21+
{
22+
public function __construct()
23+
{
24+
GlobalData::$bar = $this;
25+
}
26+
}
27+
28+
class Foo
29+
{
30+
public Foo $selfRef;
31+
public Value $val;
32+
33+
public function __construct(Value $val)
34+
{
35+
$this->val = $val;
36+
$this->selfRef = $this;
37+
}
38+
}
39+
40+
for ($j = 0; $j < 10; $j++) {
41+
for ($i = 0; $i < 3000; $i++) {
42+
new Foo(new Value());
43+
}
44+
}
45+
46+
var_dump(gc_status());
47+
?>
48+
--EXPECT--
49+
array(4) {
50+
["runs"]=>
51+
int(10)
52+
["collected"]=>
53+
int(25000)
54+
["threshold"]=>
55+
int(10001)
56+
["roots"]=>
57+
int(10000)
58+
}

Zend/zend_gc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,12 +1469,13 @@ static void zend_gc_root_tmpvars(void);
14691469

14701470
ZEND_API int zend_gc_collect_cycles(void)
14711471
{
1472-
int count = 0;
1472+
int total_count = 0;
14731473
bool should_rerun_gc = 0;
14741474
bool did_rerun_gc = 0;
14751475

14761476
rerun_gc:
14771477
if (GC_G(num_roots)) {
1478+
int count;
14781479
gc_root_buffer *current, *last;
14791480
zend_refcounted *p;
14801481
uint32_t gc_flags = 0;
@@ -1652,6 +1653,7 @@ ZEND_API int zend_gc_collect_cycles(void)
16521653

16531654
GC_TRACE("Collection finished");
16541655
GC_G(collected) += count;
1656+
total_count += count;
16551657
GC_G(gc_active) = 0;
16561658
}
16571659

@@ -1668,7 +1670,7 @@ ZEND_API int zend_gc_collect_cycles(void)
16681670
finish:
16691671
zend_get_gc_buffer_release();
16701672
zend_gc_root_tmpvars();
1671-
return count;
1673+
return total_count;
16721674
}
16731675

16741676
ZEND_API void zend_gc_get_status(zend_gc_status *status)

0 commit comments

Comments
 (0)