@@ -3039,9 +3039,13 @@ static void zend_jit_setup_disasm(void)
3039
3039
REGISTER_HELPER(zend_jit_assign_dim_op_helper);
3040
3040
REGISTER_HELPER(zend_jit_fetch_obj_w_slow);
3041
3041
REGISTER_HELPER(zend_jit_fetch_obj_r_slow);
3042
+ REGISTER_HELPER(zend_jit_fetch_obj_r_slow_ex);
3042
3043
REGISTER_HELPER(zend_jit_fetch_obj_is_slow);
3044
+ REGISTER_HELPER(zend_jit_fetch_obj_is_slow_ex);
3043
3045
REGISTER_HELPER(zend_jit_fetch_obj_r_dynamic);
3046
+ REGISTER_HELPER(zend_jit_fetch_obj_r_dynamic_ex);
3044
3047
REGISTER_HELPER(zend_jit_fetch_obj_is_dynamic);
3048
+ REGISTER_HELPER(zend_jit_fetch_obj_is_dynamic_ex);
3045
3049
REGISTER_HELPER(zend_jit_check_array_promotion);
3046
3050
REGISTER_HELPER(zend_jit_create_typed_ref);
3047
3051
REGISTER_HELPER(zend_jit_invalid_property_write);
@@ -13662,20 +13666,21 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
13662
13666
bool delayed_fetch_this,
13663
13667
bool op1_avoid_refcounting,
13664
13668
zend_class_entry *trace_ce,
13669
+ zend_jit_addr res_addr,
13665
13670
uint8_t prop_type,
13666
13671
int may_throw)
13667
13672
{
13668
13673
zval *member;
13669
13674
zend_property_info *prop_info;
13670
13675
bool may_be_dynamic = 1;
13671
- zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
13672
13676
zend_jit_addr prop_addr;
13673
13677
uint32_t res_info = RES_INFO();
13674
13678
ir_ref prop_type_ref = IR_UNUSED;
13675
13679
ir_ref obj_ref = IR_UNUSED;
13676
13680
ir_ref prop_ref = IR_UNUSED;
13677
13681
ir_ref end_inputs = IR_UNUSED;
13678
13682
ir_ref slow_inputs = IR_UNUSED;
13683
+ ir_ref end_values = IR_UNUSED;
13679
13684
13680
13685
ZEND_ASSERT(opline->op2_type == IS_CONST);
13681
13686
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
@@ -13804,13 +13809,28 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
13804
13809
jit_SET_EX_OPLINE(jit, opline);
13805
13810
13806
13811
if (opline->opcode != ZEND_FETCH_OBJ_IS) {
13807
- ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_dynamic),
13808
- obj_ref, offset_ref);
13812
+ if (((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info)
13813
+ || Z_MODE(res_addr) == IS_REG) {
13814
+ ir_ref val_addr = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_dynamic_ex),
13815
+ obj_ref, offset_ref);
13816
+ ir_END_PHI_list(end_values, val_addr);
13817
+ } else {
13818
+ ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_dynamic),
13819
+ obj_ref, offset_ref);
13820
+ ir_END_list(end_inputs);
13821
+ }
13809
13822
} else {
13810
- ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_is_dynamic),
13811
- obj_ref, offset_ref);
13823
+ if (((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info)
13824
+ || Z_MODE(res_addr) == IS_REG) {
13825
+ ir_ref val_addr = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_fetch_obj_is_dynamic_ex),
13826
+ obj_ref, offset_ref);
13827
+ ir_END_PHI_list(end_values, val_addr);
13828
+ } else {
13829
+ ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_is_dynamic),
13830
+ obj_ref, offset_ref);
13831
+ ir_END_list(end_inputs);
13832
+ }
13812
13833
}
13813
- ir_END_list(end_inputs);
13814
13834
}
13815
13835
ir_IF_FALSE(if_dynamic);
13816
13836
}
@@ -13996,12 +14016,56 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
13996
14016
}
13997
14017
ir_END_list(end_inputs);
13998
14018
} else {
14019
+ if (((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info)
14020
+ || Z_MODE(res_addr) == IS_REG) {
14021
+ ir_END_PHI_list(end_values, jit_ZVAL_ADDR(jit, prop_addr));
14022
+ } else {
14023
+ prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr);
14024
+
14025
+ if (!zend_jit_zval_copy_deref(jit, res_addr, prop_addr, prop_type_ref)) {
14026
+ return 0;
14027
+ }
14028
+ ir_END_list(end_inputs);
14029
+ }
14030
+ }
14031
+
14032
+ if (op1_avoid_refcounting) {
14033
+ SET_STACK_REG(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
14034
+ }
14035
+
14036
+ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) {
14037
+ ir_MERGE_list(slow_inputs);
14038
+ jit_SET_EX_OPLINE(jit, opline);
14039
+
14040
+ if (opline->opcode == ZEND_FETCH_OBJ_W) {
14041
+ ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_w_slow), obj_ref);
14042
+ ir_END_list(end_inputs);
14043
+ } else if (opline->opcode != ZEND_FETCH_OBJ_IS) {
14044
+ if (Z_MODE(res_addr) == IS_REG) {
14045
+ ir_ref val_ref = ir_CALL_1(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_slow_ex), obj_ref);
14046
+ ir_END_PHI_list(end_values, val_ref);
14047
+ } else {
14048
+ ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_slow), obj_ref);
14049
+ ir_END_list(end_inputs);
14050
+ }
14051
+ } else {
14052
+ ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_is_slow), obj_ref);
14053
+ ir_END_list(end_inputs);
14054
+ }
14055
+ }
14056
+
14057
+ if (end_values) {
14058
+ ir_ref val_ref = ir_PHI_list(end_values);
14059
+ zend_jit_addr val_addr = ZEND_ADDR_REF_ZVAL(val_ref);
13999
14060
bool result_avoid_refcounting = 0;
14000
14061
14001
- if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
14062
+ ZEND_ASSERT(opline->opcode == ZEND_FETCH_OBJ_R
14063
+ || opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG
14064
+ || opline->opcode == ZEND_FETCH_OBJ_IS);
14065
+ ZEND_ASSERT(end_inputs == IR_UNUSED);
14066
+ if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame)) {
14002
14067
uint8_t type = concrete_type(res_info);
14003
14068
uint32_t flags = 0;
14004
- zend_jit_addr val_addr = prop_addr;
14005
14069
14006
14070
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
14007
14071
&& !delayed_fetch_this
@@ -14026,39 +14090,14 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
14026
14090
14027
14091
res_info &= ~MAY_BE_GUARD;
14028
14092
ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
14029
-
14030
- // ZVAL_COPY
14031
- jit_ZVAL_COPY(jit, res_addr, -1, val_addr, res_info, !result_avoid_refcounting);
14032
- } else {
14033
- prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr);
14034
-
14035
- if (!zend_jit_zval_copy_deref(jit, res_addr, prop_addr, prop_type_ref)) {
14036
- return 0;
14037
- }
14038
14093
}
14039
- ir_END_list(end_inputs);
14040
- }
14041
-
14042
- if (op1_avoid_refcounting) {
14043
- SET_STACK_REG(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
14044
- }
14045
-
14046
- if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) {
14047
- ir_MERGE_list(slow_inputs);
14048
- jit_SET_EX_OPLINE(jit, opline);
14049
14094
14050
- if (opline->opcode == ZEND_FETCH_OBJ_W) {
14051
- ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_w_slow), obj_ref);
14052
- } else if (opline->opcode != ZEND_FETCH_OBJ_IS) {
14053
- ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_r_slow), obj_ref);
14054
- } else {
14055
- ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fetch_obj_is_slow), obj_ref);
14056
- }
14057
- ir_END_list(end_inputs);
14095
+ // ZVAL_COPY
14096
+ jit_ZVAL_COPY(jit, res_addr, -1, val_addr, res_info, !result_avoid_refcounting);
14097
+ } else {
14098
+ ir_MERGE_list(end_inputs);
14058
14099
}
14059
14100
14060
- ir_MERGE_list(end_inputs);
14061
-
14062
14101
if (opline->op1_type != IS_UNUSED && !delayed_fetch_this && !op1_indirect) {
14063
14102
if (opline->op1_type == IS_VAR
14064
14103
&& opline->opcode == ZEND_FETCH_OBJ_W
@@ -16662,6 +16701,14 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
16662
16701
return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&
16663
16702
(((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) ||
16664
16703
((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING));
16704
+ case ZEND_FETCH_OBJ_R:
16705
+ if (opline->op2_type != IS_CONST
16706
+ || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
16707
+ || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
16708
+ return 0;
16709
+ }
16710
+ op1_info = OP1_INFO();
16711
+ return opline->op1_type == IS_UNUSED || (op1_info & MAY_BE_OBJECT);
16665
16712
}
16666
16713
return 0;
16667
16714
}
0 commit comments