Skip to content

Commit e1c6fb7

Browse files
dstogoviluuu1994
authored andcommitted
JIT support for delayed destructor for zend_assign_to_typed_ref/prop
1 parent fdbea4f commit e1c6fb7

File tree

4 files changed

+110
-31
lines changed

4 files changed

+110
-31
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5743,22 +5743,31 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
57435743
if (opline) {
57445744
| SET_EX_OPLINE opline, REG0
57455745
}
5746-
if (val_type == IS_CONST) {
5747-
| EXT_CALL zend_jit_assign_const_to_typed_ref, REG0
5748-
} else if (val_type == IS_TMP_VAR) {
5749-
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, REG0
5750-
} else if (val_type == IS_VAR) {
5751-
| EXT_CALL zend_jit_assign_var_to_typed_ref, REG0
5752-
} else if (val_type == IS_CV) {
5753-
| EXT_CALL zend_jit_assign_cv_to_typed_ref, REG0
5746+
if (!res_addr) {
5747+
if (val_type == IS_CONST) {
5748+
| EXT_CALL zend_jit_assign_const_to_typed_ref, REG0
5749+
} else if (val_type == IS_TMP_VAR) {
5750+
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, REG0
5751+
} else if (val_type == IS_VAR) {
5752+
| EXT_CALL zend_jit_assign_var_to_typed_ref, REG0
5753+
} else if (val_type == IS_CV) {
5754+
| EXT_CALL zend_jit_assign_cv_to_typed_ref, REG0
5755+
} else {
5756+
ZEND_UNREACHABLE();
5757+
}
57545758
} else {
5755-
ZEND_UNREACHABLE();
5756-
}
5757-
if (res_addr) {
5758-
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_X0, 0); // RETVAL
5759-
5760-
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_REG1, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
5761-
| TRY_ADDREF -1, REG1w, REG2, TMP1w
5759+
| LOAD_ZVAL_ADDR CARG3, res_addr
5760+
if (val_type == IS_CONST) {
5761+
| EXT_CALL zend_jit_assign_const_to_typed_ref2, REG0
5762+
} else if (val_type == IS_TMP_VAR) {
5763+
| EXT_CALL zend_jit_assign_tmp_to_typed_ref2, REG0
5764+
} else if (val_type == IS_VAR) {
5765+
| EXT_CALL zend_jit_assign_var_to_typed_ref2, REG0
5766+
} else if (val_type == IS_CV) {
5767+
| EXT_CALL zend_jit_assign_cv_to_typed_ref2, REG0
5768+
} else {
5769+
ZEND_UNREACHABLE();
5770+
}
57625771
}
57635772
if (check_exception) {
57645773
| // if (UNEXPECTED(EG(exception) != NULL)) {

ext/opcache/jit/zend_jit_disasm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,10 @@ static int zend_jit_disasm_init(void)
659659
REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref);
660660
REGISTER_HELPER(zend_jit_assign_var_to_typed_ref);
661661
REGISTER_HELPER(zend_jit_assign_cv_to_typed_ref);
662+
REGISTER_HELPER(zend_jit_assign_const_to_typed_ref2);
663+
REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref2);
664+
REGISTER_HELPER(zend_jit_assign_var_to_typed_ref2);
665+
REGISTER_HELPER(zend_jit_assign_cv_to_typed_ref2);
662666
REGISTER_HELPER(zend_jit_pre_inc_typed_ref);
663667
REGISTER_HELPER(zend_jit_pre_dec_typed_ref);
664668
REGISTER_HELPER(zend_jit_post_inc_typed_ref);

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,51 @@ static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref,
21862186
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
21872187
}
21882188

2189+
static zend_always_inline zval* zend_jit_assign_to_typed_ref2_helper(zend_reference *ref, zval *value, zval *result, uint8_t value_type)
2190+
{
2191+
zval variable, *ret;
2192+
zend_refcounted *garbage = NULL;
2193+
2194+
ZVAL_REF(&variable, ref);
2195+
ret = zend_assign_to_variable_ex(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)), &garbage);
2196+
ZVAL_COPY(result, ret);
2197+
if (garbage) {
2198+
GC_DTOR(garbage);
2199+
}
2200+
return ret;
2201+
}
2202+
2203+
static zval* ZEND_FASTCALL zend_jit_assign_const_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
2204+
{
2205+
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_CONST);
2206+
}
2207+
2208+
static zval* ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
2209+
{
2210+
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_TMP_VAR);
2211+
}
2212+
2213+
static zval* ZEND_FASTCALL zend_jit_assign_var_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
2214+
{
2215+
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_VAR);
2216+
}
2217+
2218+
static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
2219+
{
2220+
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
2221+
const zend_op *opline = EG(current_execute_data)->opline;
2222+
uint32_t var;
2223+
if (opline->opcode == ZEND_ASSIGN) {
2224+
var = opline->op2.var;
2225+
} else {
2226+
ZEND_ASSERT((opline + 1)->opcode == ZEND_OP_DATA);
2227+
var = (opline + 1)->op1.var;
2228+
}
2229+
zend_jit_undefined_op_helper(var);
2230+
value = &EG(uninitialized_zval);
2231+
}
2232+
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_CV);
2233+
}
21892234

21902235
static zend_property_info *zend_jit_get_prop_not_accepting_double(zend_reference *ref)
21912236
{
@@ -2504,6 +2549,7 @@ static void ZEND_FASTCALL zend_jit_assign_obj_helper(zend_object *zobj, zend_str
25042549
static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend_property_info *info, zval *value, zval *result)
25052550
{
25062551
zend_execute_data *execute_data = EG(current_execute_data);
2552+
zend_refcounted *garbage = NULL;
25072553
zval tmp;
25082554

25092555
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
@@ -2534,10 +2580,13 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend
25342580

25352581
Z_PROP_FLAG_P(property_val) &= ~IS_PROP_REINITABLE;
25362582

2537-
value = zend_assign_to_variable(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES());
2583+
value = zend_assign_to_variable_ex(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
25382584
if (result) {
25392585
ZVAL_COPY_DEREF(result, value);
25402586
}
2587+
if (garbage) {
2588+
GC_DTOR(garbage);
2589+
}
25412590
}
25422591

25432592
static zend_never_inline void _zend_jit_assign_op_overloaded_property(zend_object *object, zend_string *name, void **cache_slot, zval *value, binary_op_type binary_op)

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6285,22 +6285,39 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
62856285
if (opline) {
62866286
| SET_EX_OPLINE opline, r0
62876287
}
6288-
if (val_type == IS_CONST) {
6289-
| EXT_CALL zend_jit_assign_const_to_typed_ref, r0
6290-
} else if (val_type == IS_TMP_VAR) {
6291-
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, r0
6292-
} else if (val_type == IS_VAR) {
6293-
| EXT_CALL zend_jit_assign_var_to_typed_ref, r0
6294-
} else if (val_type == IS_CV) {
6295-
| EXT_CALL zend_jit_assign_cv_to_typed_ref, r0
6288+
if (!res_addr) {
6289+
if (val_type == IS_CONST) {
6290+
| EXT_CALL zend_jit_assign_const_to_typed_ref, r0
6291+
} else if (val_type == IS_TMP_VAR) {
6292+
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, r0
6293+
} else if (val_type == IS_VAR) {
6294+
| EXT_CALL zend_jit_assign_var_to_typed_ref, r0
6295+
} else if (val_type == IS_CV) {
6296+
| EXT_CALL zend_jit_assign_cv_to_typed_ref, r0
6297+
} else {
6298+
ZEND_UNREACHABLE();
6299+
}
62966300
} else {
6297-
ZEND_UNREACHABLE();
6298-
}
6299-
if (res_addr) {
6300-
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
6301-
6302-
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_R1, ZREG_R2
6303-
| TRY_ADDREF -1, ch, r2
6301+
|.if X64
6302+
| LOAD_ZVAL_ADDR CARG3, res_addr
6303+
|.else
6304+
| sub r4, 12
6305+
| PUSH_ZVAL_ADDR res_addr, r0
6306+
|.endif
6307+
if (val_type == IS_CONST) {
6308+
| EXT_CALL zend_jit_assign_const_to_typed_ref2, r0
6309+
} else if (val_type == IS_TMP_VAR) {
6310+
| EXT_CALL zend_jit_assign_tmp_to_typed_ref2, r0
6311+
} else if (val_type == IS_VAR) {
6312+
| EXT_CALL zend_jit_assign_var_to_typed_ref2, r0
6313+
} else if (val_type == IS_CV) {
6314+
| EXT_CALL zend_jit_assign_cv_to_typed_ref2, r0
6315+
} else {
6316+
ZEND_UNREACHABLE();
6317+
}
6318+
|.if not(X64)
6319+
| add r4, 12
6320+
|.endif
63046321
}
63056322
if (check_exception) {
63066323
| // if (UNEXPECTED(EG(exception) != NULL)) {

0 commit comments

Comments
 (0)