@@ -3654,6 +3654,27 @@ static int zend_jit_update_regs(dasm_State **Dst, zend_jit_addr src, zend_jit_ad
3654
3654
return 1;
3655
3655
}
3656
3656
3657
+ static int zend_jit_escape_if_undef_r0(dasm_State **Dst, int var, uint32_t flags, const zend_op *opline)
3658
+ {
3659
+ zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
3660
+
3661
+ | IF_NOT_ZVAL_TYPE val_addr, IS_UNDEF, >1
3662
+
3663
+ if (flags & ZEND_JIT_EXIT_RESTORE_CALL) {
3664
+ if (!zend_jit_save_call_chain(Dst, -1)) {
3665
+ return 0;
3666
+ }
3667
+ }
3668
+
3669
+ ZEND_ASSERT(opline);
3670
+ zend_jit_set_ip(Dst, opline - 1);
3671
+
3672
+ | jmp ->trace_escape
3673
+ |1:
3674
+
3675
+ return 1;
3676
+ }
3677
+
3657
3678
static int zend_jit_store_const(dasm_State **Dst, int var, zend_reg reg)
3658
3679
{
3659
3680
zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var));
@@ -5116,7 +5137,10 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5116
5137
if (op1_info & MAY_BE_ARRAY_HASH) {
5117
5138
| IF_NOT_Z_TYPE r0, IS_UNDEF, >8
5118
5139
} else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5119
- | IF_Z_TYPE r0, IS_UNDEF, &exit_addr
5140
+ /* perform IS_UNDEF check only after result type guard (during deoptimization) */
5141
+ if (!found_exit_addr || (op1_info & MAY_BE_ARRAY_HASH)) {
5142
+ | IF_Z_TYPE r0, IS_UNDEF, &exit_addr
5143
+ }
5120
5144
} else if (type == BP_VAR_IS && not_found_exit_addr) {
5121
5145
| IF_Z_TYPE r0, IS_UNDEF, ¬_found_exit_addr
5122
5146
} else if (type == BP_VAR_IS && found_exit_addr) {
@@ -11457,6 +11481,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
11457
11481
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
11458
11482
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
11459
11483
zend_jit_addr prop_addr;
11484
+ uint32_t res_info = RES_INFO();
11460
11485
11461
11486
ZEND_ASSERT(opline->op2_type == IS_CONST);
11462
11487
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
@@ -11570,13 +11595,16 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
11570
11595
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, prop_info->offset);
11571
11596
| mov edx, dword [FCARG1a + prop_info->offset + 8]
11572
11597
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
11573
- int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
11574
- const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
11598
+ if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
11599
+ /* perform IS_UNDEF check only after result type guard (during deoptimization) */
11600
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
11601
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
11575
11602
11576
- if (!exit_addr) {
11577
- return 0;
11603
+ if (!exit_addr) {
11604
+ return 0;
11605
+ }
11606
+ | IF_UNDEF dl, &exit_addr
11578
11607
}
11579
- | IF_UNDEF dl, &exit_addr
11580
11608
} else {
11581
11609
| IF_UNDEF dl, >5
11582
11610
}
@@ -11634,7 +11662,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
11634
11662
| SET_ZVAL_PTR res_addr, FCARG1a
11635
11663
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
11636
11664
} else {
11637
- uint32_t res_info = RES_INFO();
11638
11665
zend_bool result_avoid_refcounting = 0;
11639
11666
11640
11667
if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
0 commit comments