Skip to content

Commit e69317b

Browse files
committed
Reduce gc stack usage for strings (and resources)
Adding strings to the worklist is useless, because they never contribute to cycles. The assembly size on x86_64 does not change. This significantly improves performance in this synthetic benchmark by 33%. function test($a) {} $a = new stdClass(); $a->self = $a; $a->prop1 = str_repeat('a', 10); $a->prop2 = str_repeat('a', 10); $a->prop3 = str_repeat('a', 10); $a->prop4 = str_repeat('a', 10); $a->prop5 = str_repeat('a', 10); $a->prop6 = str_repeat('a', 10); $a->prop7 = str_repeat('a', 10); $a->prop8 = str_repeat('a', 10); $a->prop9 = str_repeat('a', 10); $a->prop10 = str_repeat('a', 10); for ($i = 0; $i < 10_000_000; $i++) { test($a); gc_collect_cycles(); } This requires adding IS_TYPE_COLLECTABLE to IS_REFERENCE_EX to ensure these values continue to be pushed onto the stack. Luckily, IS_TYPE_COLLECTABLE is currently only used in gc_check_possible_root(), where the checked value cannot be a reference. Note that this changes the output of gc_collect_cycles(). Non-cyclic, refcounted values no longer count towards the total reported values collected. Also, there is some obvious overlap with GH-17130. This change should be good nonetheless, especially if we can remove the GC_COLLECTABLE(Z_COUNTED_P(zv)) condition in PHP 9 and rely on Z_COLLECTABLE_P() exclusively, given we can assume an object doesn't become cyclic at runtime anymore. Closes GH-17194
1 parent 287aeeb commit e69317b

File tree

3 files changed

+46
-41
lines changed

3 files changed

+46
-41
lines changed

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ PHP 8.5 UPGRADE NOTES
3434
$object. If compared to a statically unknown value $object == $true, it
3535
would always return false. This behavior was consolidated to always follow
3636
the behavior of (bool) $object.
37+
. The return value of gc_collect_cycles() no longer includes strings and
38+
resources that were indirectly collected through cycles.
3739

3840
- Intl:
3941
. The extension now requires at least ICU 57.1.

Zend/zend_gc.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
818818
zval *entry = (zval*) Z_PTR_P(zv);
819819
zval *weakmap = zv+1;
820820
ZEND_ASSERT(Z_REFCOUNTED_P(weakmap));
821-
if (Z_OPT_REFCOUNTED_P(entry)) {
821+
if (Z_OPT_COLLECTABLE_P(entry)) {
822822
GC_UNSET_FROM_WEAKMAP_KEY(entry);
823823
if (GC_REF_CHECK_COLOR(Z_COUNTED_P(weakmap), GC_GREY)) {
824824
/* Weakmap was scanned in gc_mark_roots, we must
@@ -855,7 +855,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
855855
ZEND_ASSERT(Z_TYPE_P(zv+1) == IS_PTR);
856856
zval *key = zv;
857857
zval *entry = (zval*) Z_PTR_P(zv+1);
858-
if (Z_OPT_REFCOUNTED_P(entry)) {
858+
if (Z_OPT_COLLECTABLE_P(entry)) {
859859
GC_UNSET_FROM_WEAKMAP(entry);
860860
if (GC_REF_CHECK_COLOR(Z_COUNTED_P(key), GC_GREY)) {
861861
/* Key was scanned in gc_mark_roots, we must
@@ -893,7 +893,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
893893
if (!GC_REF_CHECK_COLOR(ht, GC_BLACK)) {
894894
GC_REF_SET_BLACK(ht);
895895
for (; n != 0; n--) {
896-
if (Z_REFCOUNTED_P(zv)) {
896+
if (Z_COLLECTABLE_P(zv)) {
897897
ref = Z_COUNTED_P(zv);
898898
GC_ADDREF(ref);
899899
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
@@ -909,14 +909,14 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
909909

910910
handle_zvals:
911911
for (; n != 0; n--) {
912-
if (Z_REFCOUNTED_P(zv)) {
912+
if (Z_COLLECTABLE_P(zv)) {
913913
ref = Z_COUNTED_P(zv);
914914
GC_ADDREF(ref);
915915
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
916916
GC_REF_SET_BLACK(ref);
917917
zv++;
918918
while (--n) {
919-
if (Z_REFCOUNTED_P(zv)) {
919+
if (Z_COLLECTABLE_P(zv)) {
920920
zend_refcounted *ref = Z_COUNTED_P(zv);
921921
GC_ADDREF(ref);
922922
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
@@ -948,7 +948,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
948948
if (Z_TYPE_P(zv) == IS_INDIRECT) {
949949
zv = Z_INDIRECT_P(zv);
950950
}
951-
if (Z_REFCOUNTED_P(zv)) {
951+
if (Z_COLLECTABLE_P(zv)) {
952952
ref = Z_COUNTED_P(zv);
953953
GC_ADDREF(ref);
954954
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
@@ -959,7 +959,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
959959
if (Z_TYPE_P(zv) == IS_INDIRECT) {
960960
zv = Z_INDIRECT_P(zv);
961961
}
962-
if (Z_REFCOUNTED_P(zv)) {
962+
if (Z_COLLECTABLE_P(zv)) {
963963
zend_refcounted *ref = Z_COUNTED_P(zv);
964964
GC_ADDREF(ref);
965965
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
@@ -975,7 +975,7 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
975975
p++;
976976
}
977977
} else if (GC_TYPE(ref) == IS_REFERENCE) {
978-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
978+
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
979979
ref = Z_COUNTED(((zend_reference*)ref)->val);
980980
GC_ADDREF(ref);
981981
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
@@ -1019,7 +1019,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
10191019
zval *entry = (zval*) Z_PTR_P(zv);
10201020
zval *weakmap = zv+1;
10211021
ZEND_ASSERT(Z_REFCOUNTED_P(weakmap));
1022-
if (Z_REFCOUNTED_P(entry)) {
1022+
if (Z_COLLECTABLE_P(entry)) {
10231023
GC_SET_FROM_WEAKMAP_KEY(entry);
10241024
ref = Z_COUNTED_P(entry);
10251025
/* Only DELREF if the contribution from the weakmap has
@@ -1043,7 +1043,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
10431043
for (; n != 0; n--) {
10441044
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
10451045
zval *entry = (zval*) Z_PTR_P(zv);
1046-
if (Z_REFCOUNTED_P(entry)) {
1046+
if (Z_COLLECTABLE_P(entry)) {
10471047
GC_SET_FROM_WEAKMAP(entry);
10481048
ref = Z_COUNTED_P(entry);
10491049
/* Only DELREF if the contribution from the weakmap key
@@ -1069,7 +1069,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
10691069
if (!GC_REF_CHECK_COLOR(ht, GC_GREY)) {
10701070
GC_REF_SET_COLOR(ht, GC_GREY);
10711071
for (; n != 0; n--) {
1072-
if (Z_REFCOUNTED_P(zv)) {
1072+
if (Z_COLLECTABLE_P(zv)) {
10731073
ref = Z_COUNTED_P(zv);
10741074
GC_DELREF(ref);
10751075
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
@@ -1084,14 +1084,14 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
10841084
}
10851085
handle_zvals:
10861086
for (; n != 0; n--) {
1087-
if (Z_REFCOUNTED_P(zv)) {
1087+
if (Z_COLLECTABLE_P(zv)) {
10881088
ref = Z_COUNTED_P(zv);
10891089
GC_DELREF(ref);
10901090
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
10911091
GC_REF_SET_COLOR(ref, GC_GREY);
10921092
zv++;
10931093
while (--n) {
1094-
if (Z_REFCOUNTED_P(zv)) {
1094+
if (Z_COLLECTABLE_P(zv)) {
10951095
zend_refcounted *ref = Z_COUNTED_P(zv);
10961096
GC_DELREF(ref);
10971097
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
@@ -1123,7 +1123,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
11231123
if (Z_TYPE_P(zv) == IS_INDIRECT) {
11241124
zv = Z_INDIRECT_P(zv);
11251125
}
1126-
if (Z_REFCOUNTED_P(zv)) {
1126+
if (Z_COLLECTABLE_P(zv)) {
11271127
ref = Z_COUNTED_P(zv);
11281128
GC_DELREF(ref);
11291129
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
@@ -1134,7 +1134,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
11341134
if (Z_TYPE_P(zv) == IS_INDIRECT) {
11351135
zv = Z_INDIRECT_P(zv);
11361136
}
1137-
if (Z_REFCOUNTED_P(zv)) {
1137+
if (Z_COLLECTABLE_P(zv)) {
11381138
zend_refcounted *ref = Z_COUNTED_P(zv);
11391139
GC_DELREF(ref);
11401140
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
@@ -1150,7 +1150,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
11501150
p++;
11511151
}
11521152
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1153-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1153+
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
11541154
ref = Z_COUNTED(((zend_reference*)ref)->val);
11551155
GC_DELREF(ref);
11561156
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
@@ -1263,7 +1263,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
12631263
for (; n != 0; n--) {
12641264
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
12651265
zval *entry = (zval*) Z_PTR_P(zv);
1266-
if (Z_OPT_REFCOUNTED_P(entry)) {
1266+
if (Z_OPT_COLLECTABLE_P(entry)) {
12671267
ref = Z_COUNTED_P(entry);
12681268
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
12691269
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1282,7 +1282,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
12821282
GC_REF_SET_COLOR(ht, GC_WHITE);
12831283
GC_STACK_PUSH((zend_refcounted *) ht);
12841284
for (; n != 0; n--) {
1285-
if (Z_REFCOUNTED_P(zv)) {
1285+
if (Z_COLLECTABLE_P(zv)) {
12861286
ref = Z_COUNTED_P(zv);
12871287
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
12881288
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1297,13 +1297,13 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
12971297

12981298
handle_zvals:
12991299
for (; n != 0; n--) {
1300-
if (Z_REFCOUNTED_P(zv)) {
1300+
if (Z_COLLECTABLE_P(zv)) {
13011301
ref = Z_COUNTED_P(zv);
13021302
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
13031303
GC_REF_SET_COLOR(ref, GC_WHITE);
13041304
zv++;
13051305
while (--n) {
1306-
if (Z_REFCOUNTED_P(zv)) {
1306+
if (Z_COLLECTABLE_P(zv)) {
13071307
zend_refcounted *ref = Z_COUNTED_P(zv);
13081308
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
13091309
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1335,7 +1335,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
13351335
if (Z_TYPE_P(zv) == IS_INDIRECT) {
13361336
zv = Z_INDIRECT_P(zv);
13371337
}
1338-
if (Z_REFCOUNTED_P(zv)) {
1338+
if (Z_COLLECTABLE_P(zv)) {
13391339
ref = Z_COUNTED_P(zv);
13401340
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
13411341
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1345,7 +1345,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
13451345
if (Z_TYPE_P(zv) == IS_INDIRECT) {
13461346
zv = Z_INDIRECT_P(zv);
13471347
}
1348-
if (Z_REFCOUNTED_P(zv)) {
1348+
if (Z_COLLECTABLE_P(zv)) {
13491349
zend_refcounted *ref = Z_COUNTED_P(zv);
13501350
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
13511351
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1360,7 +1360,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
13601360
p++;
13611361
}
13621362
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1363-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1363+
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
13641364
ref = Z_COUNTED(((zend_reference*)ref)->val);
13651365
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
13661366
GC_REF_SET_COLOR(ref, GC_WHITE);
@@ -1473,7 +1473,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
14731473
for (; n != 0; n--) {
14741474
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
14751475
zval *entry = (zval*) Z_PTR_P(zv);
1476-
if (Z_REFCOUNTED_P(entry) && GC_FROM_WEAKMAP_KEY(entry)) {
1476+
if (Z_COLLECTABLE_P(entry) && GC_FROM_WEAKMAP_KEY(entry)) {
14771477
GC_UNSET_FROM_WEAKMAP_KEY(entry);
14781478
GC_UNSET_FROM_WEAKMAP(entry);
14791479
ref = Z_COUNTED_P(entry);
@@ -1494,7 +1494,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
14941494
for (; n != 0; n--) {
14951495
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
14961496
zval *entry = (zval*) Z_PTR_P(zv);
1497-
if (Z_REFCOUNTED_P(entry) && GC_FROM_WEAKMAP(entry)) {
1497+
if (Z_COLLECTABLE_P(entry) && GC_FROM_WEAKMAP(entry)) {
14981498
GC_UNSET_FROM_WEAKMAP_KEY(entry);
14991499
GC_UNSET_FROM_WEAKMAP(entry);
15001500
ref = Z_COUNTED_P(entry);
@@ -1517,7 +1517,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
15171517
if (GC_REF_CHECK_COLOR(ht, GC_WHITE)) {
15181518
GC_REF_SET_BLACK(ht);
15191519
for (; n != 0; n--) {
1520-
if (Z_REFCOUNTED_P(zv)) {
1520+
if (Z_COLLECTABLE_P(zv)) {
15211521
ref = Z_COUNTED_P(zv);
15221522
GC_ADDREF(ref);
15231523
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
@@ -1533,14 +1533,14 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
15331533

15341534
handle_zvals:
15351535
for (; n != 0; n--) {
1536-
if (Z_REFCOUNTED_P(zv)) {
1536+
if (Z_COLLECTABLE_P(zv)) {
15371537
ref = Z_COUNTED_P(zv);
15381538
GC_ADDREF(ref);
15391539
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
15401540
GC_REF_SET_BLACK(ref);
15411541
zv++;
15421542
while (--n) {
1543-
if (Z_REFCOUNTED_P(zv)) {
1543+
if (Z_COLLECTABLE_P(zv)) {
15441544
zend_refcounted *ref = Z_COUNTED_P(zv);
15451545
GC_ADDREF(ref);
15461546
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
@@ -1576,7 +1576,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
15761576
if (Z_TYPE_P(zv) == IS_INDIRECT) {
15771577
zv = Z_INDIRECT_P(zv);
15781578
}
1579-
if (Z_REFCOUNTED_P(zv)) {
1579+
if (Z_COLLECTABLE_P(zv)) {
15801580
ref = Z_COUNTED_P(zv);
15811581
GC_ADDREF(ref);
15821582
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
@@ -1587,7 +1587,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
15871587
if (Z_TYPE_P(zv) == IS_INDIRECT) {
15881588
zv = Z_INDIRECT_P(zv);
15891589
}
1590-
if (Z_REFCOUNTED_P(zv)) {
1590+
if (Z_COLLECTABLE_P(zv)) {
15911591
zend_refcounted *ref = Z_COUNTED_P(zv);
15921592
GC_ADDREF(ref);
15931593
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
@@ -1603,7 +1603,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
16031603
p++;
16041604
}
16051605
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1606-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1606+
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
16071607
ref = Z_COUNTED(((zend_reference*)ref)->val);
16081608
GC_ADDREF(ref);
16091609
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
@@ -1681,7 +1681,7 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe
16811681
GC_REMOVE_FROM_BUFFER(ref);
16821682
count++;
16831683
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1684-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1684+
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
16851685
ref = Z_COUNTED(((zend_reference*)ref)->val);
16861686
goto tail_call;
16871687
}
@@ -1704,7 +1704,7 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe
17041704
for (; n != 0; n--) {
17051705
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
17061706
zval *entry = (zval*) Z_PTR_P(zv);
1707-
if (Z_OPT_REFCOUNTED_P(entry)) {
1707+
if (Z_OPT_COLLECTABLE_P(entry)) {
17081708
ref = Z_COUNTED_P(entry);
17091709
GC_STACK_PUSH(ref);
17101710
}
@@ -1717,7 +1717,7 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe
17171717
zv = table;
17181718
if (UNEXPECTED(ht)) {
17191719
for (; n != 0; n--) {
1720-
if (Z_REFCOUNTED_P(zv)) {
1720+
if (Z_COLLECTABLE_P(zv)) {
17211721
ref = Z_COUNTED_P(zv);
17221722
GC_STACK_PUSH(ref);
17231723
}
@@ -1732,11 +1732,11 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe
17321732

17331733
handle_zvals:
17341734
for (; n != 0; n--) {
1735-
if (Z_REFCOUNTED_P(zv)) {
1735+
if (Z_COLLECTABLE_P(zv)) {
17361736
ref = Z_COUNTED_P(zv);
17371737
zv++;
17381738
while (--n) {
1739-
if (Z_REFCOUNTED_P(zv)) {
1739+
if (Z_COLLECTABLE_P(zv)) {
17401740
zend_refcounted *ref = Z_COUNTED_P(zv);
17411741
GC_STACK_PUSH(ref);
17421742
}
@@ -1763,15 +1763,15 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe
17631763
if (Z_TYPE_P(zv) == IS_INDIRECT) {
17641764
zv = Z_INDIRECT_P(zv);
17651765
}
1766-
if (Z_REFCOUNTED_P(zv)) {
1766+
if (Z_COLLECTABLE_P(zv)) {
17671767
ref = Z_COUNTED_P(zv);
17681768
p++;
17691769
while (--n) {
17701770
zv = &p->val;
17711771
if (Z_TYPE_P(zv) == IS_INDIRECT) {
17721772
zv = Z_INDIRECT_P(zv);
17731773
}
1774-
if (Z_REFCOUNTED_P(zv)) {
1774+
if (Z_COLLECTABLE_P(zv)) {
17751775
zend_refcounted *ref = Z_COUNTED_P(zv);
17761776
GC_STACK_PUSH(ref);
17771777
}
@@ -2175,7 +2175,7 @@ static void zend_gc_check_root_tmpvars(void) {
21752175
if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
21762176
uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
21772177
zval *var = ZEND_CALL_VAR(ex, var_num);
2178-
if (Z_REFCOUNTED_P(var)) {
2178+
if (Z_COLLECTABLE_P(var)) {
21792179
gc_check_possible_root(Z_COUNTED_P(var));
21802180
}
21812181
}
@@ -2205,7 +2205,7 @@ static void zend_gc_remove_root_tmpvars(void) {
22052205
if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
22062206
uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
22072207
zval *var = ZEND_CALL_VAR(ex, var_num);
2208-
if (Z_REFCOUNTED_P(var)) {
2208+
if (Z_COLLECTABLE_P(var)) {
22092209
GC_REMOVE_FROM_BUFFER(Z_COUNTED_P(var));
22102210
}
22112211
}

Zend/zend_types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
808808
#define IS_ARRAY_EX (IS_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
809809
#define IS_OBJECT_EX (IS_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
810810
#define IS_RESOURCE_EX (IS_RESOURCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
811-
#define IS_REFERENCE_EX (IS_REFERENCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
811+
#define IS_REFERENCE_EX (IS_REFERENCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
812812

813813
#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
814814

@@ -943,6 +943,9 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
943943
#define Z_OPT_REFCOUNTED(zval) Z_TYPE_INFO_REFCOUNTED(Z_TYPE_INFO(zval))
944944
#define Z_OPT_REFCOUNTED_P(zval_p) Z_OPT_REFCOUNTED(*(zval_p))
945945

946+
#define Z_OPT_COLLECTABLE(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
947+
#define Z_OPT_COLLECTABLE_P(zval_p) Z_OPT_COLLECTABLE(*(zval_p))
948+
946949
/* deprecated: (COPYABLE is the same as IS_ARRAY) */
947950
#define Z_OPT_COPYABLE(zval) (Z_OPT_TYPE(zval) == IS_ARRAY)
948951
#define Z_OPT_COPYABLE_P(zval_p) Z_OPT_COPYABLE(*(zval_p))

0 commit comments

Comments
 (0)