From ebb94af754ca3d365d400fda2190a7625c3c42fb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 16 Jul 2020 00:19:00 +0300 Subject: [PATCH] Fixed tracing JIT for ASSIGN to typed reference --- ext/opcache/jit/zend_jit_helpers.c | 10 ++--- ext/opcache/jit/zend_jit_trace.c | 3 ++ ext/opcache/jit/zend_jit_x86.dasc | 66 +++++++++++++++++++----------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 681b095a18..c282dea4e2 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1632,7 +1632,7 @@ static void ZEND_FASTCALL zend_jit_vm_stack_free_args_helper(zend_execute_data * zend_vm_stack_free_args(call); } -static zend_always_inline void zend_jit_assign_to_typed_ref(zend_reference *ref, zval *value, zend_uchar value_type) +static zend_always_inline void zend_jit_assign_to_typed_ref_helper(zend_reference *ref, zval *value, zend_uchar value_type) { zval variable; @@ -1642,22 +1642,22 @@ static zend_always_inline void zend_jit_assign_to_typed_ref(zend_reference *ref, static void ZEND_FASTCALL zend_jit_assign_const_to_typed_ref(zend_reference *ref, zval *value) { - zend_jit_assign_to_typed_ref(ref, value, IS_CONST); + zend_jit_assign_to_typed_ref_helper(ref, value, IS_CONST); } static void ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref(zend_reference *ref, zval *value) { - zend_jit_assign_to_typed_ref(ref, value, IS_TMP_VAR); + zend_jit_assign_to_typed_ref_helper(ref, value, IS_TMP_VAR); } static void ZEND_FASTCALL zend_jit_assign_var_to_typed_ref(zend_reference *ref, zval *value) { - zend_jit_assign_to_typed_ref(ref, value, IS_VAR); + zend_jit_assign_to_typed_ref_helper(ref, value, IS_VAR); } static void ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, zval *value) { - zend_jit_assign_to_typed_ref(ref, value, IS_CV); + zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV); } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a5bc5f34af..b64429b1a7 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3341,6 +3341,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 0)) { goto jit_failure; } + if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, op_array, opline->op2_type, op2_addr, 1)) { + goto jit_failure; + } op1_def_addr = op1_addr; } else { USE_OP1_TRACE_TYPE(); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 9508cd3fa7..5a181b0df8 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -5389,6 +5389,44 @@ static int zend_jit_simple_assign(dasm_State **Dst, return 1; } +static int zend_jit_assign_to_typed_ref(dasm_State **Dst, + const zend_op *opline, + const zend_op_array *op_array, + zend_uchar val_type, + zend_jit_addr val_addr, + zend_bool check_exception) +{ + | // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) { + | cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0 + | jnz >2 + |.cold_code + |2: + | LOAD_ZVAL_ADDR FCARG2a, val_addr + | SAVE_VALID_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 + } else { + ZEND_UNREACHABLE(); + } + if (check_exception) { + | // if (UNEXPECTED(EG(exception) != NULL)) { + | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 + | je >8 // END OF zend_jit_assign_to_variable() + | jmp ->exception_handler + } else { + | jmp >8 + } + |.code + + return 1; +} + static int zend_jit_assign_to_variable(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, @@ -5415,26 +5453,10 @@ static int zend_jit_assign_to_variable(dasm_State **Dst, | IF_NOT_Z_TYPE, FCARG1a, IS_REFERENCE, >1 | // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) { | GET_Z_PTR FCARG1a, FCARG1a - | cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0 - | jnz >2 - | add FCARG1a, offsetof(zend_reference, val) - |.cold_code - |2: - | LOAD_ZVAL_ADDR FCARG2a, val_addr - | SAVE_VALID_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 - } else { - ZEND_UNREACHABLE(); + if (!zend_jit_assign_to_typed_ref(Dst, opline, op_array, val_type, val_addr, check_exception)) { + return 0; } - | jmp >8 - |.code + | add FCARG1a, offsetof(zend_reference, val) |1: } if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { @@ -7878,7 +7900,7 @@ static int zend_jit_assign(dasm_State **Dst, const zend_op *opline, const zend_o } if (!zend_jit_assign_to_variable(Dst, opline, op_array, op1_addr, op1_info, op1_def_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr, - may_throw && !(op1_info & MAY_BE_REF) && (op1_info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY)))) { + may_throw)) { return 0; } if (!zend_jit_store_var_if_necessary_ex(Dst, opline->op1.var, op1_addr, op1_def_info, op1_use_addr, op1_info)) { @@ -7890,10 +7912,6 @@ static int zend_jit_assign(dasm_State **Dst, const zend_op *opline, const zend_o } } - if (may_throw && (op1_info & MAY_BE_REF)) { - zend_jit_check_exception(Dst); - } - return 1; } -- 2.50.1