JIT support for delayed destructor for zend_assign_to_typed_ref/prop

This commit is contained in:
Dmitry Stogov 2023-04-03 22:46:35 +03:00 committed by Ilija Tovilo
parent fdbea4f39e
commit e1c6fb76c0
No known key found for this signature in database
GPG key ID: A4F5D403F118200A
4 changed files with 110 additions and 31 deletions

View file

@ -5743,22 +5743,31 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
if (opline) {
| SET_EX_OPLINE opline, REG0
}
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref, REG0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, REG0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref, REG0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref, REG0
if (!res_addr) {
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref, REG0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, REG0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref, REG0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref, REG0
} else {
ZEND_UNREACHABLE();
}
} else {
ZEND_UNREACHABLE();
}
if (res_addr) {
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_X0, 0); // RETVAL
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_REG1, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
| TRY_ADDREF -1, REG1w, REG2, TMP1w
| LOAD_ZVAL_ADDR CARG3, res_addr
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref2, REG0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref2, REG0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref2, REG0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref2, REG0
} else {
ZEND_UNREACHABLE();
}
}
if (check_exception) {
| // if (UNEXPECTED(EG(exception) != NULL)) {

View file

@ -659,6 +659,10 @@ static int zend_jit_disasm_init(void)
REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref);
REGISTER_HELPER(zend_jit_assign_var_to_typed_ref);
REGISTER_HELPER(zend_jit_assign_cv_to_typed_ref);
REGISTER_HELPER(zend_jit_assign_const_to_typed_ref2);
REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref2);
REGISTER_HELPER(zend_jit_assign_var_to_typed_ref2);
REGISTER_HELPER(zend_jit_assign_cv_to_typed_ref2);
REGISTER_HELPER(zend_jit_pre_inc_typed_ref);
REGISTER_HELPER(zend_jit_pre_dec_typed_ref);
REGISTER_HELPER(zend_jit_post_inc_typed_ref);

View file

@ -2186,6 +2186,51 @@ static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref,
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
}
static zend_always_inline zval* zend_jit_assign_to_typed_ref2_helper(zend_reference *ref, zval *value, zval *result, uint8_t value_type)
{
zval variable, *ret;
zend_refcounted *garbage = NULL;
ZVAL_REF(&variable, ref);
ret = zend_assign_to_variable_ex(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)), &garbage);
ZVAL_COPY(result, ret);
if (garbage) {
GC_DTOR(garbage);
}
return ret;
}
static zval* ZEND_FASTCALL zend_jit_assign_const_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
{
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_CONST);
}
static zval* ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
{
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_TMP_VAR);
}
static zval* ZEND_FASTCALL zend_jit_assign_var_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
{
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_VAR);
}
static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref2(zend_reference *ref, zval *value, zval *result)
{
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
const zend_op *opline = EG(current_execute_data)->opline;
uint32_t var;
if (opline->opcode == ZEND_ASSIGN) {
var = opline->op2.var;
} else {
ZEND_ASSERT((opline + 1)->opcode == ZEND_OP_DATA);
var = (opline + 1)->op1.var;
}
zend_jit_undefined_op_helper(var);
value = &EG(uninitialized_zval);
}
return zend_jit_assign_to_typed_ref2_helper(ref, value, result, IS_CV);
}
static zend_property_info *zend_jit_get_prop_not_accepting_double(zend_reference *ref)
{
@ -2504,6 +2549,7 @@ static void ZEND_FASTCALL zend_jit_assign_obj_helper(zend_object *zobj, zend_str
static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend_property_info *info, zval *value, zval *result)
{
zend_execute_data *execute_data = EG(current_execute_data);
zend_refcounted *garbage = NULL;
zval tmp;
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
Z_PROP_FLAG_P(property_val) &= ~IS_PROP_REINITABLE;
value = zend_assign_to_variable(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES());
value = zend_assign_to_variable_ex(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
if (result) {
ZVAL_COPY_DEREF(result, value);
}
if (garbage) {
GC_DTOR(garbage);
}
}
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)

View file

@ -6285,22 +6285,39 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
if (opline) {
| SET_EX_OPLINE opline, r0
}
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref, r0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, r0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref, r0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref, r0
if (!res_addr) {
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref, r0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref, r0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref, r0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref, r0
} else {
ZEND_UNREACHABLE();
}
} else {
ZEND_UNREACHABLE();
}
if (res_addr) {
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_R1, ZREG_R2
| TRY_ADDREF -1, ch, r2
|.if X64
| LOAD_ZVAL_ADDR CARG3, res_addr
|.else
| sub r4, 12
| PUSH_ZVAL_ADDR res_addr, r0
|.endif
if (val_type == IS_CONST) {
| EXT_CALL zend_jit_assign_const_to_typed_ref2, r0
} else if (val_type == IS_TMP_VAR) {
| EXT_CALL zend_jit_assign_tmp_to_typed_ref2, r0
} else if (val_type == IS_VAR) {
| EXT_CALL zend_jit_assign_var_to_typed_ref2, r0
} else if (val_type == IS_CV) {
| EXT_CALL zend_jit_assign_cv_to_typed_ref2, r0
} else {
ZEND_UNREACHABLE();
}
|.if not(X64)
| add r4, 12
|.endif
}
if (check_exception) {
| // if (UNEXPECTED(EG(exception) != NULL)) {