From: Dmitry Stogov Date: Tue, 21 Jul 2020 12:39:13 +0000 (+0300) Subject: Fix type recording and side exit information for FE_FETCH_* instructions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7686118212f6785320c5dac72f2b6d02d5021faf;p=php Fix type recording and side exit information for FE_FETCH_* instructions --- diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 7668f47f2a..0703d9e805 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -655,8 +655,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (opline->op2_type & (IS_TMP_VAR|IS_VAR|IS_CV) && opline->opcode != ZEND_INSTANCEOF && opline->opcode != ZEND_UNSET_STATIC_PROP - && opline->opcode != ZEND_FE_FETCH_R - && opline->opcode != ZEND_FE_FETCH_RW) { + && (opline->op2_type == IS_CV + || (opline->opcode != ZEND_FE_FETCH_R + && opline->opcode != ZEND_FE_FETCH_RW))) { zval *zv = EX_VAR(opline->op2.var); uint8_t flags = 0; diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 8e8ec5694a..9bf9f89540 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3277,6 +3277,8 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra const zend_op *exit_opline = NULL; uint32_t exit_point; const void *exit_addr; + uint32_t old_info = 0; + zend_jit_trace_stack *stack = JIT_G(current_frame)->stack; if (zend_is_smart_branch(opline)) { zend_bool exit_if_true = 0; @@ -3302,6 +3304,10 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: + if (opline->op2_type == IS_CV) { + old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var)); + SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN); + } exit_opline = (trace->opline == opline + 1) ? ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : opline + 1; @@ -3313,6 +3319,15 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra exit_point = zend_jit_trace_get_exit_point(opline, exit_opline, trace, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); + switch (opline->opcode) { + case ZEND_FE_FETCH_R: + case ZEND_FE_FETCH_RW: + if (opline->op2_type == IS_CV) { + SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var), old_info); + } + break; + } + if (!exit_addr) { return 0; }