Skip to content

Commit da1c672

Browse files
committed
Replace exceptional code by side exit to VM
1 parent e2a8b3e commit da1c672

File tree

1 file changed

+80
-75
lines changed

1 file changed

+80
-75
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 80 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10501,95 +10501,100 @@ static int zend_jit_bind_global(dasm_State **Dst, const zend_op *opline, const z
1050110501
static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array)
1050210502
{
1050310503
uint32_t arg_num = opline->op1.num;
10504-
10505-
| cmp dword EX->This.u2.num_args, arg_num
10506-
| jb >1
10507-
|.cold_code
10508-
|1:
10509-
| SAVE_VALID_OPLINE opline, r0
10510-
| mov FCARG1a, FP
10511-
| EXT_CALL zend_missing_arg_error, r0
10512-
| jmp ->exception_handler
10513-
|.code
10504+
zend_arg_info *arg_info = NULL;
1051410505

1051510506
if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
10516-
zend_arg_info *arg_info = NULL;
10517-
1051810507
if (EXPECTED(arg_num <= op_array->num_args)) {
1051910508
arg_info = &op_array->arg_info[arg_num-1];
1052010509
} else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
1052110510
arg_info = &op_array->arg_info[op_array->num_args];
1052210511
}
10523-
if (arg_info) {
10524-
zend_type type = arg_info->type;
10512+
if (arg_info && !ZEND_TYPE_IS_SET(arg_info->type)) {
10513+
arg_info = NULL;
10514+
}
10515+
}
1052510516

10526-
if (ZEND_TYPE_IS_SET(type)) {
10527-
// Type check
10528-
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10517+
if (arg_info || (opline+1)->opcode != ZEND_RECV) {
10518+
| cmp dword EX->This.u2.num_args, arg_num
10519+
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
10520+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM);
10521+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
1052910522

10530-
| LOAD_ZVAL_ADDR r0, res_addr
10531-
if (ZEND_ARG_SEND_MODE(arg_info)) {
10532-
| GET_Z_PTR r0, r0
10533-
| add r0, offsetof(zend_reference, val)
10534-
}
10523+
if (!exit_addr) {
10524+
return 0;
10525+
}
10526+
| jb &exit_addr
10527+
} else {
10528+
| jb >1
10529+
|.cold_code
10530+
|1:
10531+
| SAVE_VALID_OPLINE opline, r0
10532+
| mov FCARG1a, FP
10533+
| EXT_CALL zend_missing_arg_error, r0
10534+
| jmp ->exception_handler
10535+
|.code
10536+
}
10537+
}
1053510538

10536-
uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
10537-
if (type_mask == 0) {
10538-
| jmp >8
10539-
} else if (is_power_of_two(type_mask)) {
10540-
uint32_t type_code = concrete_type(type_mask);
10541-
| cmp byte [r0 + 8], type_code
10542-
| jne >8
10543-
} else {
10544-
| mov edx, 1
10545-
| mov cl, byte [r0 + 8]
10546-
| shl edx, cl
10547-
| test edx, type_mask
10548-
| je >8
10549-
}
10539+
if (arg_info) {
10540+
// Type check
10541+
zend_type type = arg_info->type;
10542+
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10543+
uint32_t type_mask;
1055010544

10551-
|.cold_code
10552-
|8:
10553-
| SAVE_VALID_OPLINE opline, r0
10554-
| mov FCARG1a, r0
10555-
| mov r0, EX->run_time_cache
10556-
| add r0, opline->extended_value
10557-
| mov FCARG2a, EX->func
10558-
|.if X64WIN
10559-
| mov CARG3, arg_num
10560-
| LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10561-
| mov aword A5, r0
10562-
| EXT_CALL zend_jit_verify_arg_slow, r0
10563-
|.elif X64
10564-
| mov CARG3, arg_num
10565-
| LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10566-
| mov CARG5, r0
10567-
| EXT_CALL zend_jit_verify_arg_slow, r0
10568-
|.else
10569-
| sub r4, 4
10570-
| push r0
10571-
| push (ptrdiff_t)arg_info
10572-
| push arg_num
10573-
| EXT_CALL zend_jit_verify_arg_slow, r0
10574-
| add r4, 4
10575-
|.endif
10576-
if (!zend_jit_check_exception(Dst)) {
10577-
return 0;
10578-
}
10579-
| jmp >1
10580-
|.code
10581-
|1:
10545+
| LOAD_ZVAL_ADDR r0, res_addr
10546+
if (ZEND_ARG_SEND_MODE(arg_info)) {
10547+
| GET_Z_PTR r0, r0
10548+
| add r0, offsetof(zend_reference, val)
10549+
}
1058210550

10583-
if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
10584-
last_valid_opline = NULL;
10585-
if (!zend_jit_set_valid_ip(Dst, opline + 1)) {
10586-
return 0;
10587-
}
10588-
}
10551+
type_mask = ZEND_TYPE_PURE_MASK(type);
10552+
if (type_mask == 0) {
10553+
| jmp >8
10554+
} else if (is_power_of_two(type_mask)) {
10555+
uint32_t type_code = concrete_type(type_mask);
10556+
| cmp byte [r0 + 8], type_code
10557+
| jne >8
10558+
} else {
10559+
| mov edx, 1
10560+
| mov cl, byte [r0 + 8]
10561+
| shl edx, cl
10562+
| test edx, type_mask
10563+
| je >8
10564+
}
1058910565

10590-
return 1;
10591-
}
10566+
|.cold_code
10567+
|8:
10568+
| SAVE_VALID_OPLINE opline, r0
10569+
| mov FCARG1a, r0
10570+
| mov r0, EX->run_time_cache
10571+
| add r0, opline->extended_value
10572+
| mov FCARG2a, EX->func
10573+
|.if X64WIN
10574+
| mov CARG3, arg_num
10575+
| LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10576+
| mov aword A5, r0
10577+
| EXT_CALL zend_jit_verify_arg_slow, r0
10578+
|.elif X64
10579+
| mov CARG3, arg_num
10580+
| LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10581+
| mov CARG5, r0
10582+
| EXT_CALL zend_jit_verify_arg_slow, r0
10583+
|.else
10584+
| sub r4, 4
10585+
| push r0
10586+
| push (ptrdiff_t)arg_info
10587+
| push arg_num
10588+
| EXT_CALL zend_jit_verify_arg_slow, r0
10589+
| add r4, 4
10590+
|.endif
10591+
10592+
if (!zend_jit_check_exception(Dst)) {
10593+
return 0;
1059210594
}
10595+
| jmp >1
10596+
|.code
10597+
|1:
1059310598
}
1059410599

1059510600
if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {

0 commit comments

Comments
 (0)