Skip to content

Commit ace18f4

Browse files
authored
JIT: Avoid IS_UNDEF check for ZEND_FETCH_DIM/OBJ_IS with a result type guard (php#14298)
1 parent 2c91b73 commit ace18f4

File tree

2 files changed

+26
-31
lines changed

2 files changed

+26
-31
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7744,8 +7744,13 @@ static zend_jit_addr zend_jit_guard_fetch_result_type(zend_jit_ctx *jit,
77447744
SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN, 1);
77457745

77467746
if (deref) {
7747-
ir_ref if_type = jit_if_Z_TYPE(jit, val_addr, type);
7747+
ir_ref if_type;
77487748

7749+
if (type == IS_NULL && (opline->opcode == ZEND_FETCH_DIM_IS || opline->opcode == ZEND_FETCH_OBJ_IS)) {
7750+
if_type = ir_IF(ir_ULE(jit_Z_TYPE(jit, val_addr), ir_CONST_U8(type)));
7751+
} else {
7752+
if_type = jit_if_Z_TYPE(jit, val_addr, type);
7753+
}
77497754
ir_IF_TRUE(if_type);
77507755
end1 = ir_END();
77517756
ref1 = ref;
@@ -7770,7 +7775,11 @@ static zend_jit_addr zend_jit_guard_fetch_result_type(zend_jit_ctx *jit,
77707775
return 0;
77717776
}
77727777

7773-
jit_guard_Z_TYPE(jit, val_addr, type, res_exit_addr);
7778+
if (!deref && type == IS_NULL && (opline->opcode == ZEND_FETCH_DIM_IS || opline->opcode == ZEND_FETCH_OBJ_IS)) {
7779+
ir_GUARD(ir_ULE(jit_Z_TYPE(jit, val_addr), ir_CONST_U8(type)), ir_CONST_ADDR(res_exit_addr));
7780+
} else {
7781+
jit_guard_Z_TYPE(jit, val_addr, type, res_exit_addr);
7782+
}
77747783

77757784
if (deref) {
77767785
ir_MERGE_WITH(end1);
@@ -11576,39 +11585,20 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
1157611585
if (packed_loaded) {
1157711586
ir_ref type_ref = jit_Z_TYPE_ref(jit, ref);
1157811587

11579-
if (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) {
11580-
ir_ref if_def = ir_IF(type_ref);
11581-
ir_IF_TRUE(if_def);
11582-
ir_refs_add(found_inputs, ir_END());
11583-
ir_refs_add(found_vals, ref);
11584-
ir_IF_FALSE(if_def);
11585-
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
11586-
jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr));
11587-
} else if (type == BP_VAR_IS && not_found_exit_addr) {
11588-
jit_SIDE_EXIT(jit, ir_CONST_ADDR(not_found_exit_addr));
11589-
} else if (type == BP_VAR_IS && result_type_guard) {
11590-
ir_END_list(*not_found_inputs);
11591-
} else {
11592-
ir_END_list(idx_not_found_inputs);
11593-
}
11594-
} else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
11588+
if (result_type_guard) {
1159511589
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
11596-
if (!result_type_guard) {
11597-
ir_GUARD(type_ref, ir_CONST_ADDR(exit_addr));
11598-
}
11590+
} else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
11591+
ir_GUARD(type_ref, ir_CONST_ADDR(exit_addr));
1159911592
} else if (type == BP_VAR_IS && not_found_exit_addr) {
1160011593
ir_GUARD(type_ref, ir_CONST_ADDR(not_found_exit_addr));
11601-
} else if (type == BP_VAR_IS && result_type_guard) {
11602-
ir_ref if_def = ir_IF(type_ref);
11603-
ir_IF_FALSE(if_def);
11604-
ir_END_list(*not_found_inputs);
11605-
ir_IF_TRUE(if_def);
1160611594
} else {
1160711595
ir_ref if_def = ir_IF(type_ref);
1160811596
ir_IF_FALSE(if_def);
1160911597
ir_END_list(idx_not_found_inputs);
1161011598
ir_IF_TRUE(if_def);
1161111599
}
11600+
ir_refs_add(found_inputs, ir_END());
11601+
ir_refs_add(found_vals, ref);
1161211602
}
1161311603
if (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) {
1161411604
if (if_packed) {
@@ -11641,10 +11631,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
1164111631
}
1164211632
ir_refs_add(found_inputs, ir_END());
1164311633
ir_refs_add(found_vals, ref);
11644-
} else if (packed_loaded) {
11645-
ir_refs_add(found_inputs, ir_END());
11646-
ir_refs_add(found_vals, ref);
11647-
} else {
11634+
} else if (!packed_loaded) {
1164811635
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
1164911636
jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr));
1165011637
} else if (type == BP_VAR_IS && not_found_exit_addr) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8497,7 +8497,15 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
84978497

84988498
if (UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) {
84998499
/* Undefined array index or property */
8500-
repeat_last_opline = 1;
8500+
const zend_op *op = t->exit_info[exit_num].opline;
8501+
ZEND_ASSERT(op);
8502+
op--;
8503+
if (op->opcode == ZEND_FETCH_DIM_IS || op->opcode == ZEND_FETCH_OBJ_IS) {
8504+
ZVAL_NULL(EX_VAR_NUM(i));
8505+
} else {
8506+
assert(op->opcode == ZEND_FETCH_DIM_R || op->opcode == ZEND_FETCH_LIST_R || op->opcode == ZEND_FETCH_OBJ_R);
8507+
repeat_last_opline = 1;
8508+
}
85018509
} else {
85028510
ZVAL_COPY(EX_VAR_NUM(i), val);
85038511
}

0 commit comments

Comments
 (0)