Skip to content

Commit 9c7f0aa

Browse files
committed
Delay freeing of garbage for write_property
1 parent d0dea8e commit 9c7f0aa

14 files changed

+358
-11
lines changed

Zend/tests/gh10168/assign_prop.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_prop_ref_with_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop ref with prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_prop_with_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop with prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_untyped_prop.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_untyped_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_untyped_prop_ref_with_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop ref with prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/tests/gh10168/assign_untyped_prop_with_prop_ref.phpt

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
--TEST--
22
GH-10168: Assign prop with prop ref
3-
--XFAIL--
43
--FILE--
54
<?php
65

Zend/zend_execute_API.c

+3
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ void init_executor(void) /* {{{ */
196196
EG(filename_override) = NULL;
197197
EG(lineno_override) = -1;
198198

199+
EG(delay_assignment_garbage) = false;
200+
EG(delayed_assignment_garbage) = NULL;
201+
199202
zend_fiber_init();
200203
zend_weakrefs_init();
201204

Zend/zend_globals.h

+3
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ struct _zend_executor_globals {
287287
zend_ulong reserved_stack_size;
288288
#endif
289289

290+
bool delay_assignment_garbage;
291+
zend_refcounted *delayed_assignment_garbage;
292+
290293
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
291294
};
292295

Zend/zend_object_handlers.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,22 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
836836
value = &tmp;
837837
}
838838

839-
found:
840-
variable_ptr = zend_assign_to_variable(
841-
variable_ptr, value, IS_TMP_VAR, property_uses_strict_types());
839+
found:;
840+
zend_refcounted *garbage = NULL;
841+
variable_ptr = zend_assign_to_variable_ex(
842+
variable_ptr, value, IS_TMP_VAR, property_uses_strict_types(), &garbage);
843+
if (garbage) {
844+
if (EG(delay_assignment_garbage)) {
845+
EG(delay_assignment_garbage) = false;
846+
EG(delayed_assignment_garbage) = garbage;
847+
} else {
848+
if (GC_DELREF(garbage) == 0) {
849+
rc_dtor_func(garbage);
850+
} else {
851+
gc_check_possible_root_no_ref(garbage);
852+
}
853+
}
854+
}
842855
goto exit;
843856
}
844857
if (Z_PROP_FLAG_P(variable_ptr) == IS_PROP_UNINIT) {

Zend/zend_vm_def.h

+9
Original file line numberDiff line numberDiff line change
@@ -2487,7 +2487,16 @@ ZEND_VM_C_LABEL(fast_assign_obj):
24872487
ZVAL_DEREF(value);
24882488
}
24892489

2490+
bool previous_delay_assignment_garbage = EG(delay_assignment_garbage);
2491+
zend_refcounted *previous_delayed_assignment_garbage = EG(delayed_assignment_garbage);
2492+
EG(delay_assignment_garbage) = true;
2493+
EG(delayed_assignment_garbage) = NULL;
24902494
value = zobj->handlers->write_property(zobj, name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
2495+
if (EG(delayed_assignment_garbage)) {
2496+
garbage = EG(delayed_assignment_garbage);
2497+
}
2498+
EG(delay_assignment_garbage) = previous_delay_assignment_garbage;
2499+
EG(delayed_assignment_garbage) = previous_delayed_assignment_garbage;
24912500

24922501
if (OP2_TYPE != IS_CONST) {
24932502
zend_tmp_string_release(tmp_name);

0 commit comments

Comments
 (0)