Skip to content

Commit 8cbb0ff

Browse files
committed
Use guards for ZEND_FETCH_OBJ_R/IS to eliminate repeatable checks
1 parent e42cab2 commit 8cbb0ff

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,9 +2767,14 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
27672767
ce = NULL;
27682768
if (opline->op1_type == IS_UNUSED) {
27692769
op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN;
2770+
op1_addr = 0;
27702771
ce = op_array->scope;
27712772
} else {
27722773
op1_info = OP1_INFO();
2774+
if (!(op1_info & MAY_BE_OBJECT)) {
2775+
break;
2776+
}
2777+
op1_addr = OP1_REG_ADDR();
27732778
if (ssa->var_info && ssa->ops) {
27742779
zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes];
27752780
if (ssa_op->op1_use >= 0) {
@@ -2780,11 +2785,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
27802785
}
27812786
}
27822787
}
2783-
if (!(op1_info & MAY_BE_OBJECT)) {
2784-
break;
2785-
}
27862788
if (!zend_jit_fetch_obj_read(&dasm_state, opline, op_array,
2787-
op1_info, ce,
2789+
op1_info, op1_addr, ce,
27882790
zend_may_throw(opline, ssa_op, op_array, ssa))) {
27892791
goto jit_failure;
27902792
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,23 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
15471547
}
15481548
}
15491549
break;
1550+
case ZEND_FETCH_OBJ_FUNC_ARG:
1551+
if (!frame
1552+
|| !frame->call
1553+
|| !frame->call->func
1554+
|| !TRACE_FRAME_IS_LAST_SEND_BY_VAL(frame->call)) {
1555+
break;
1556+
}
1557+
/* break missing intentionally */
1558+
case ZEND_FETCH_OBJ_R:
1559+
case ZEND_FETCH_OBJ_IS:
1560+
if (opline->op2_type != IS_CONST
1561+
|| Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
1562+
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
1563+
break;
1564+
}
1565+
ADD_OP1_TRACE_GUARD();
1566+
break;
15501567
default:
15511568
break;
15521569
}
@@ -3720,8 +3737,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
37203737
if (opline->op1_type == IS_UNUSED) {
37213738
op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN;
37223739
ce = op_array->scope;
3740+
op1_addr = 0;
37233741
} else {
37243742
op1_info = OP1_INFO();
3743+
if (!(op1_info & MAY_BE_OBJECT)) {
3744+
break;
3745+
}
3746+
op1_addr = OP1_REG_ADDR();
3747+
if (orig_op1_type != IS_UNKNOWN
3748+
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3749+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
3750+
goto jit_failure;
3751+
}
3752+
} else {
3753+
CHECK_OP1_TRACE_TYPE();
3754+
}
37253755
if (ssa->var_info && ssa->ops) {
37263756
if (ssa_op->op1_use >= 0) {
37273757
zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use;
@@ -3731,11 +3761,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
37313761
}
37323762
}
37333763
}
3734-
if (!(op1_info & MAY_BE_OBJECT)) {
3735-
break;
3736-
}
37373764
if (!zend_jit_fetch_obj_read(&dasm_state, opline, op_array,
3738-
op1_info, ce,
3765+
op1_info, op1_addr, ce,
37393766
zend_may_throw(opline, ssa_op, op_array, ssa))) {
37403767
goto jit_failure;
37413768
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10789,12 +10789,11 @@ static zend_bool zend_may_be_dynamic_property(zend_class_entry *ce, zend_string
1078910789
return 0;
1079010790
}
1079110791

10792-
static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_class_entry *ce, int may_throw)
10792+
static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_jit_addr op1_addr, zend_class_entry *ce, int may_throw)
1079310793
{
1079410794
zval *member;
1079510795
uint32_t offset;
1079610796
zend_bool may_be_dynamic = 1;
10797-
zend_jit_addr op1_addr = 0, orig_op1_addr = 0;
1079810797
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
1079910798
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
1080010799
zend_jit_addr prop_addr;
@@ -10809,11 +10808,10 @@ static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, cons
1080910808
if (opline->op1_type == IS_UNUSED) {
1081010809
| GET_ZVAL_PTR FCARG1a, this_addr
1081110810
} else {
10812-
op1_addr = orig_op1_addr = OP1_ADDR();
1081310811
if (op1_info & MAY_BE_REF) {
10814-
| LOAD_ZVAL_ADDR r0, op1_addr
10815-
| ZVAL_DEREF r0, op1_info
10816-
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
10812+
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
10813+
| ZVAL_DEREF FCARG1a, op1_info
10814+
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
1081710815
}
1081810816
if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) {
1081910817
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
@@ -10895,14 +10893,18 @@ static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, cons
1089510893
if (opline->opcode != ZEND_FETCH_OBJ_IS) {
1089610894
| SAVE_VALID_OPLINE opline, r1
1089710895
if (op1_info & MAY_BE_UNDEF) {
10896+
zend_jit_addr orig_op1_addr = OP1_ADDR();
10897+
1089810898
if (op1_info & MAY_BE_ANY) {
1089910899
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1
1090010900
}
1090110901
| mov FCARG1d, opline->op1.var
1090210902
| EXT_CALL zend_jit_undefined_op_helper, r0
1090310903
|1:
10904+
| LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
10905+
} else {
10906+
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
1090410907
}
10905-
| LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
1090610908
| LOAD_ADDR FCARG2a, Z_STRVAL_P(member)
1090710909
| EXT_CALL zend_jit_invalid_property_read, r0
1090810910
}

0 commit comments

Comments
 (0)