mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
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
This commit is contained in:
@@ -34,6 +34,8 @@ PHP 8.5 UPGRADE NOTES
|
||||
$object. If compared to a statically unknown value $object == $true, it
|
||||
would always return false. This behavior was consolidated to always follow
|
||||
the behavior of (bool) $object.
|
||||
. The return value of gc_collect_cycles() no longer includes strings and
|
||||
resources that were indirectly collected through cycles.
|
||||
|
||||
- Intl:
|
||||
. The extension now requires at least ICU 57.1.
|
||||
|
||||
@@ -818,7 +818,7 @@ tail_call:
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
zval *weakmap = zv+1;
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(weakmap));
|
||||
if (Z_OPT_REFCOUNTED_P(entry)) {
|
||||
if (Z_OPT_COLLECTABLE_P(entry)) {
|
||||
GC_UNSET_FROM_WEAKMAP_KEY(entry);
|
||||
if (GC_REF_CHECK_COLOR(Z_COUNTED_P(weakmap), GC_GREY)) {
|
||||
/* Weakmap was scanned in gc_mark_roots, we must
|
||||
@@ -855,7 +855,7 @@ tail_call:
|
||||
ZEND_ASSERT(Z_TYPE_P(zv+1) == IS_PTR);
|
||||
zval *key = zv;
|
||||
zval *entry = (zval*) Z_PTR_P(zv+1);
|
||||
if (Z_OPT_REFCOUNTED_P(entry)) {
|
||||
if (Z_OPT_COLLECTABLE_P(entry)) {
|
||||
GC_UNSET_FROM_WEAKMAP(entry);
|
||||
if (GC_REF_CHECK_COLOR(Z_COUNTED_P(key), GC_GREY)) {
|
||||
/* Key was scanned in gc_mark_roots, we must
|
||||
@@ -893,7 +893,7 @@ tail_call:
|
||||
if (!GC_REF_CHECK_COLOR(ht, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ht);
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
@@ -909,14 +909,14 @@ tail_call:
|
||||
|
||||
handle_zvals:
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
zv++;
|
||||
while (--n) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
@@ -948,7 +948,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
@@ -959,7 +959,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
@@ -975,7 +975,7 @@ handle_ht:
|
||||
p++;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
@@ -1019,7 +1019,7 @@ tail_call:
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
zval *weakmap = zv+1;
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(weakmap));
|
||||
if (Z_REFCOUNTED_P(entry)) {
|
||||
if (Z_COLLECTABLE_P(entry)) {
|
||||
GC_SET_FROM_WEAKMAP_KEY(entry);
|
||||
ref = Z_COUNTED_P(entry);
|
||||
/* Only DELREF if the contribution from the weakmap has
|
||||
@@ -1043,7 +1043,7 @@ tail_call:
|
||||
for (; n != 0; n--) {
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
if (Z_REFCOUNTED_P(entry)) {
|
||||
if (Z_COLLECTABLE_P(entry)) {
|
||||
GC_SET_FROM_WEAKMAP(entry);
|
||||
ref = Z_COUNTED_P(entry);
|
||||
/* Only DELREF if the contribution from the weakmap key
|
||||
@@ -1069,7 +1069,7 @@ tail_call:
|
||||
if (!GC_REF_CHECK_COLOR(ht, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ht, GC_GREY);
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
@@ -1084,14 +1084,14 @@ tail_call:
|
||||
}
|
||||
handle_zvals:
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
zv++;
|
||||
while (--n) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
@@ -1123,7 +1123,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
@@ -1134,7 +1134,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
@@ -1150,7 +1150,7 @@ handle_ht:
|
||||
p++;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
@@ -1263,7 +1263,7 @@ tail_call:
|
||||
for (; n != 0; n--) {
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
if (Z_OPT_REFCOUNTED_P(entry)) {
|
||||
if (Z_OPT_COLLECTABLE_P(entry)) {
|
||||
ref = Z_COUNTED_P(entry);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1282,7 +1282,7 @@ tail_call:
|
||||
GC_REF_SET_COLOR(ht, GC_WHITE);
|
||||
GC_STACK_PUSH((zend_refcounted *) ht);
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1297,13 +1297,13 @@ tail_call:
|
||||
|
||||
handle_zvals:
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
zv++;
|
||||
while (--n) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1335,7 +1335,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1345,7 +1345,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1360,7 +1360,7 @@ handle_ht:
|
||||
p++;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
@@ -1473,7 +1473,7 @@ tail_call:
|
||||
for (; n != 0; n--) {
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
if (Z_REFCOUNTED_P(entry) && GC_FROM_WEAKMAP_KEY(entry)) {
|
||||
if (Z_COLLECTABLE_P(entry) && GC_FROM_WEAKMAP_KEY(entry)) {
|
||||
GC_UNSET_FROM_WEAKMAP_KEY(entry);
|
||||
GC_UNSET_FROM_WEAKMAP(entry);
|
||||
ref = Z_COUNTED_P(entry);
|
||||
@@ -1494,7 +1494,7 @@ tail_call:
|
||||
for (; n != 0; n--) {
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
if (Z_REFCOUNTED_P(entry) && GC_FROM_WEAKMAP(entry)) {
|
||||
if (Z_COLLECTABLE_P(entry) && GC_FROM_WEAKMAP(entry)) {
|
||||
GC_UNSET_FROM_WEAKMAP_KEY(entry);
|
||||
GC_UNSET_FROM_WEAKMAP(entry);
|
||||
ref = Z_COUNTED_P(entry);
|
||||
@@ -1517,7 +1517,7 @@ tail_call:
|
||||
if (GC_REF_CHECK_COLOR(ht, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ht);
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
@@ -1533,14 +1533,14 @@ tail_call:
|
||||
|
||||
handle_zvals:
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
zv++;
|
||||
while (--n) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
@@ -1576,7 +1576,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
@@ -1587,7 +1587,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
@@ -1603,7 +1603,7 @@ handle_ht:
|
||||
p++;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
@@ -1681,7 +1681,7 @@ tail_call:
|
||||
GC_REMOVE_FROM_BUFFER(ref);
|
||||
count++;
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
if (Z_COLLECTABLE(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
goto tail_call;
|
||||
}
|
||||
@@ -1704,7 +1704,7 @@ tail_call:
|
||||
for (; n != 0; n--) {
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_PTR);
|
||||
zval *entry = (zval*) Z_PTR_P(zv);
|
||||
if (Z_OPT_REFCOUNTED_P(entry)) {
|
||||
if (Z_OPT_COLLECTABLE_P(entry)) {
|
||||
ref = Z_COUNTED_P(entry);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
@@ -1717,7 +1717,7 @@ tail_call:
|
||||
zv = table;
|
||||
if (UNEXPECTED(ht)) {
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
@@ -1732,11 +1732,11 @@ tail_call:
|
||||
|
||||
handle_zvals:
|
||||
for (; n != 0; n--) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
zv++;
|
||||
while (--n) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
@@ -1763,7 +1763,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
p++;
|
||||
while (--n) {
|
||||
@@ -1771,7 +1771,7 @@ handle_ht:
|
||||
if (Z_TYPE_P(zv) == IS_INDIRECT) {
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
if (Z_COLLECTABLE_P(zv)) {
|
||||
zend_refcounted *ref = Z_COUNTED_P(zv);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
@@ -2175,7 +2175,7 @@ static void zend_gc_check_root_tmpvars(void) {
|
||||
if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
|
||||
uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
|
||||
zval *var = ZEND_CALL_VAR(ex, var_num);
|
||||
if (Z_REFCOUNTED_P(var)) {
|
||||
if (Z_COLLECTABLE_P(var)) {
|
||||
gc_check_possible_root(Z_COUNTED_P(var));
|
||||
}
|
||||
}
|
||||
@@ -2205,7 +2205,7 @@ static void zend_gc_remove_root_tmpvars(void) {
|
||||
if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
|
||||
uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
|
||||
zval *var = ZEND_CALL_VAR(ex, var_num);
|
||||
if (Z_REFCOUNTED_P(var)) {
|
||||
if (Z_COLLECTABLE_P(var)) {
|
||||
GC_REMOVE_FROM_BUFFER(Z_COUNTED_P(var));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -808,7 +808,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
|
||||
#define IS_ARRAY_EX (IS_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_OBJECT_EX (IS_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_RESOURCE_EX (IS_RESOURCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_REFERENCE_EX (IS_REFERENCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_REFERENCE_EX (IS_REFERENCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT))
|
||||
|
||||
#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
|
||||
|
||||
@@ -943,6 +943,9 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
|
||||
#define Z_OPT_REFCOUNTED(zval) Z_TYPE_INFO_REFCOUNTED(Z_TYPE_INFO(zval))
|
||||
#define Z_OPT_REFCOUNTED_P(zval_p) Z_OPT_REFCOUNTED(*(zval_p))
|
||||
|
||||
#define Z_OPT_COLLECTABLE(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
|
||||
#define Z_OPT_COLLECTABLE_P(zval_p) Z_OPT_COLLECTABLE(*(zval_p))
|
||||
|
||||
/* deprecated: (COPYABLE is the same as IS_ARRAY) */
|
||||
#define Z_OPT_COPYABLE(zval) (Z_OPT_TYPE(zval) == IS_ARRAY)
|
||||
#define Z_OPT_COPYABLE_P(zval_p) Z_OPT_COPYABLE(*(zval_p))
|
||||
|
||||
Reference in New Issue
Block a user