From: Dmitry Stogov Date: Tue, 23 Jun 2020 15:31:42 +0000 (+0300) Subject: Replace exceptional code by side exit to VM X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da1c6724246661ff4fe7b6fe9db068ada7b500e2;p=php Replace exceptional code by side exit to VM --- diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 1d409f72ed..34e6c2e067 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -10501,95 +10501,100 @@ static int zend_jit_bind_global(dasm_State **Dst, const zend_op *opline, const z static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array) { uint32_t arg_num = opline->op1.num; - - | cmp dword EX->This.u2.num_args, arg_num - | jb >1 - |.cold_code - |1: - | SAVE_VALID_OPLINE opline, r0 - | mov FCARG1a, FP - | EXT_CALL zend_missing_arg_error, r0 - | jmp ->exception_handler - |.code + zend_arg_info *arg_info = NULL; if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { - zend_arg_info *arg_info = NULL; - if (EXPECTED(arg_num <= op_array->num_args)) { arg_info = &op_array->arg_info[arg_num-1]; } else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) { arg_info = &op_array->arg_info[op_array->num_args]; } - if (arg_info) { - zend_type type = arg_info->type; + if (arg_info && !ZEND_TYPE_IS_SET(arg_info->type)) { + arg_info = NULL; + } + } - if (ZEND_TYPE_IS_SET(type)) { - // Type check - zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + if (arg_info || (opline+1)->opcode != ZEND_RECV) { + | cmp dword EX->This.u2.num_args, arg_num + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); - | LOAD_ZVAL_ADDR r0, res_addr - if (ZEND_ARG_SEND_MODE(arg_info)) { - | GET_Z_PTR r0, r0 - | add r0, offsetof(zend_reference, val) - } + if (!exit_addr) { + return 0; + } + | jb &exit_addr + } else { + | jb >1 + |.cold_code + |1: + | SAVE_VALID_OPLINE opline, r0 + | mov FCARG1a, FP + | EXT_CALL zend_missing_arg_error, r0 + | jmp ->exception_handler + |.code + } + } - uint32_t type_mask = ZEND_TYPE_PURE_MASK(type); - if (type_mask == 0) { - | jmp >8 - } else if (is_power_of_two(type_mask)) { - uint32_t type_code = concrete_type(type_mask); - | cmp byte [r0 + 8], type_code - | jne >8 - } else { - | mov edx, 1 - | mov cl, byte [r0 + 8] - | shl edx, cl - | test edx, type_mask - | je >8 - } + if (arg_info) { + // Type check + zend_type type = arg_info->type; + zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + uint32_t type_mask; - |.cold_code - |8: - | SAVE_VALID_OPLINE opline, r0 - | mov FCARG1a, r0 - | mov r0, EX->run_time_cache - | add r0, opline->extended_value - | mov FCARG2a, EX->func - |.if X64WIN - | mov CARG3, arg_num - | LOAD_ADDR CARG4, (ptrdiff_t)arg_info - | mov aword A5, r0 - | EXT_CALL zend_jit_verify_arg_slow, r0 - |.elif X64 - | mov CARG3, arg_num - | LOAD_ADDR CARG4, (ptrdiff_t)arg_info - | mov CARG5, r0 - | EXT_CALL zend_jit_verify_arg_slow, r0 - |.else - | sub r4, 4 - | push r0 - | push (ptrdiff_t)arg_info - | push arg_num - | EXT_CALL zend_jit_verify_arg_slow, r0 - | add r4, 4 - |.endif - if (!zend_jit_check_exception(Dst)) { - return 0; - } - | jmp >1 - |.code - |1: + | LOAD_ZVAL_ADDR r0, res_addr + if (ZEND_ARG_SEND_MODE(arg_info)) { + | GET_Z_PTR r0, r0 + | add r0, offsetof(zend_reference, val) + } - if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) { - last_valid_opline = NULL; - if (!zend_jit_set_valid_ip(Dst, opline + 1)) { - return 0; - } - } + type_mask = ZEND_TYPE_PURE_MASK(type); + if (type_mask == 0) { + | jmp >8 + } else if (is_power_of_two(type_mask)) { + uint32_t type_code = concrete_type(type_mask); + | cmp byte [r0 + 8], type_code + | jne >8 + } else { + | mov edx, 1 + | mov cl, byte [r0 + 8] + | shl edx, cl + | test edx, type_mask + | je >8 + } - return 1; - } + |.cold_code + |8: + | SAVE_VALID_OPLINE opline, r0 + | mov FCARG1a, r0 + | mov r0, EX->run_time_cache + | add r0, opline->extended_value + | mov FCARG2a, EX->func + |.if X64WIN + | mov CARG3, arg_num + | LOAD_ADDR CARG4, (ptrdiff_t)arg_info + | mov aword A5, r0 + | EXT_CALL zend_jit_verify_arg_slow, r0 + |.elif X64 + | mov CARG3, arg_num + | LOAD_ADDR CARG4, (ptrdiff_t)arg_info + | mov CARG5, r0 + | EXT_CALL zend_jit_verify_arg_slow, r0 + |.else + | sub r4, 4 + | push r0 + | push (ptrdiff_t)arg_info + | push arg_num + | EXT_CALL zend_jit_verify_arg_slow, r0 + | add r4, 4 + |.endif + + if (!zend_jit_check_exception(Dst)) { + return 0; } + | jmp >1 + |.code + |1: } if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {