Skip to content

Commit 733c9e6

Browse files
committed
Remove WeakMap entries whose key is only reacheable through the entry value
1 parent e49777f commit 733c9e6

12 files changed

+526
-14
lines changed

Zend/tests/weakrefs/gh10043-001.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Self-referencing map entry GC - 001
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$map[$obj] = $obj;
14+
15+
gc_collect_cycles();
16+
17+
var_dump($map);
18+
19+
$obj = null;
20+
gc_collect_cycles();
21+
22+
var_dump($map);
23+
24+
--EXPECTF--
25+
object(WeakMap)#%d (1) {
26+
[0]=>
27+
array(2) {
28+
["key"]=>
29+
object(Value)#%d (1) {
30+
["value"]=>
31+
string(1) "a"
32+
}
33+
["value"]=>
34+
object(Value)#%d (1) {
35+
["value"]=>
36+
string(1) "a"
37+
}
38+
}
39+
}
40+
object(WeakMap)#%d (0) {
41+
}

Zend/tests/weakrefs/gh10043-002.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Self-referencing map entry GC - 002
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$map[$obj] = [$obj];
14+
15+
gc_collect_cycles();
16+
17+
var_dump($map);
18+
19+
$obj = null;
20+
gc_collect_cycles();
21+
22+
var_dump($map);
23+
24+
--EXPECTF--
25+
object(WeakMap)#%d (1) {
26+
[0]=>
27+
array(2) {
28+
["key"]=>
29+
object(Value)#%d (1) {
30+
["value"]=>
31+
string(1) "a"
32+
}
33+
["value"]=>
34+
array(1) {
35+
[0]=>
36+
object(Value)#%d (1) {
37+
["value"]=>
38+
string(1) "a"
39+
}
40+
}
41+
}
42+
}
43+
object(WeakMap)#1 (0) {
44+
}

Zend/tests/weakrefs/gh10043-003.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
Self-referencing map entry GC - 003
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$map[$obj] = [$obj, $map];
14+
$ref = WeakReference::create($map);
15+
16+
gc_collect_cycles();
17+
18+
var_dump($ref->get());
19+
20+
gc_collect_cycles();
21+
22+
// $obj is first in the root buffer
23+
$obj = null;
24+
$map = null;
25+
gc_collect_cycles();
26+
27+
var_dump($ref->get());
28+
29+
--EXPECTF--
30+
object(WeakMap)#%d (1) {
31+
[0]=>
32+
array(2) {
33+
["key"]=>
34+
object(Value)#%d (1) {
35+
["value"]=>
36+
string(1) "a"
37+
}
38+
["value"]=>
39+
array(2) {
40+
[0]=>
41+
object(Value)#%d (1) {
42+
["value"]=>
43+
string(1) "a"
44+
}
45+
[1]=>
46+
*RECURSION*
47+
}
48+
}
49+
}
50+
NULL

Zend/tests/weakrefs/gh10043-004.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
Self-referencing map entry GC - 004
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$map[$obj] = [$map, $obj];
14+
$ref = WeakReference::create($map);
15+
16+
gc_collect_cycles();
17+
18+
var_dump($ref->get());
19+
20+
gc_collect_cycles();
21+
22+
// $map is first in the root buffer
23+
$map = null;
24+
$obj = null;
25+
gc_collect_cycles();
26+
27+
var_dump($ref->get());
28+
29+
--EXPECTF--
30+
object(WeakMap)#%d (1) {
31+
[0]=>
32+
array(2) {
33+
["key"]=>
34+
object(Value)#%d (1) {
35+
["value"]=>
36+
string(1) "a"
37+
}
38+
["value"]=>
39+
array(2) {
40+
[0]=>
41+
*RECURSION*
42+
[1]=>
43+
object(Value)#%d (1) {
44+
["value"]=>
45+
string(1) "a"
46+
}
47+
}
48+
}
49+
}
50+
NULL

Zend/tests/weakrefs/gh10043-005.phpt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
Self-referencing map entry GC - 005
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$value = [$obj];
14+
$map[$obj] = $value;
15+
$obj = null;
16+
17+
gc_collect_cycles();
18+
19+
var_dump($map);
20+
21+
gc_collect_cycles();
22+
23+
$value = null;
24+
25+
gc_collect_cycles();
26+
27+
var_dump($map);
28+
29+
--EXPECTF--
30+
object(WeakMap)#%d (1) {
31+
[0]=>
32+
array(2) {
33+
["key"]=>
34+
object(Value)#%d (1) {
35+
["value"]=>
36+
string(1) "a"
37+
}
38+
["value"]=>
39+
array(1) {
40+
[0]=>
41+
object(Value)#%d (1) {
42+
["value"]=>
43+
string(1) "a"
44+
}
45+
}
46+
}
47+
}
48+
object(WeakMap)#1 (0) {
49+
}

Zend/tests/weakrefs/gh10043-006.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Self-referencing map entry GC - 006
3+
--FILE--
4+
<?php
5+
6+
class Value {
7+
public function __construct(public readonly string $value) {
8+
}
9+
}
10+
11+
$map = new WeakMap();
12+
$obj = new Value('a');
13+
$map[$obj] = $obj;
14+
15+
gc_collect_cycles();
16+
17+
$obj2 = $obj;
18+
$obj = null;
19+
$map2 = $map;
20+
$map = null;
21+
22+
gc_collect_cycles();
23+
24+
var_dump($map2);
25+
26+
--EXPECT--
27+
object(WeakMap)#1 (1) {
28+
[0]=>
29+
array(2) {
30+
["key"]=>
31+
object(Value)#2 (1) {
32+
["value"]=>
33+
string(1) "a"
34+
}
35+
["value"]=>
36+
object(Value)#2 (1) {
37+
["value"]=>
38+
string(1) "a"
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)