@@ -11943,6 +11943,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
11943
11943
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
11944
11944
zend_jit_addr prop_addr;
11945
11945
uint32_t res_info = RES_INFO();
11946
+ bool type_loaded = 0;
11946
11947
11947
11948
ZEND_ASSERT(opline->op2_type == IS_CONST);
11948
11949
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
@@ -12033,6 +12034,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12033
12034
| ldr REG2w, [TMP1, #offsetof(zval,u1.type_info)]
12034
12035
| IF_UNDEF REG2w, >5
12035
12036
| mov FCARG1x, TMP1
12037
+ type_loaded = 1;
12036
12038
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1, 0);
12037
12039
if (opline->opcode == ZEND_FETCH_OBJ_W
12038
12040
&& (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS))) {
@@ -12074,7 +12076,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12074
12076
}
12075
12077
} else {
12076
12078
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1, prop_info->offset);
12077
- | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12078
12079
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
12079
12080
if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
12080
12081
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
@@ -12084,12 +12085,20 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12084
12085
if (!exit_addr) {
12085
12086
return 0;
12086
12087
}
12088
+ type_loaded = 1;
12089
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12087
12090
| IF_UNDEF REG2w, &exit_addr
12088
12091
}
12089
12092
} else {
12093
+ type_loaded = 1;
12094
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12090
12095
| IF_UNDEF REG2w, >5
12091
12096
}
12092
12097
if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_READONLY)) {
12098
+ if (!type_loaded) {
12099
+ type_loaded = 1;
12100
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12101
+ }
12093
12102
| IF_NOT_TYPE REG2w, IS_OBJECT_EX, >4
12094
12103
| GET_ZVAL_PTR REG2, prop_addr, TMP1
12095
12104
| GC_ADDREF REG2, TMP1w
@@ -12112,6 +12121,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12112
12121
12113
12122
if (flags == ZEND_FETCH_DIM_WRITE) {
12114
12123
if ((ZEND_TYPE_FULL_MASK(prop_info->type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY)) == 0) {
12124
+ if (!type_loaded) {
12125
+ type_loaded = 1;
12126
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12127
+ }
12115
12128
| cmp REG2w, #IS_FALSE
12116
12129
| ble >1
12117
12130
|.cold_code
@@ -12126,6 +12139,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12126
12139
|.code
12127
12140
}
12128
12141
} else if (flags == ZEND_FETCH_REF) {
12142
+ if (!type_loaded) {
12143
+ type_loaded = 1;
12144
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12145
+ }
12129
12146
| GET_LOW_8BITS TMP1w, REG2w
12130
12147
| IF_TYPE TMP1w, IS_REFERENCE, >1
12131
12148
if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) {
@@ -12188,6 +12205,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12188
12205
ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
12189
12206
}
12190
12207
12208
+ type = concrete_type(res_info);
12209
+
12191
12210
if (prop_type != IS_UNKNOWN
12192
12211
&& prop_type != IS_UNDEF
12193
12212
&& prop_type != IS_REFERENCE
@@ -12209,20 +12228,33 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
12209
12228
return 0;
12210
12229
}
12211
12230
12231
+ if (!type_loaded) {
12232
+ type_loaded = 1;
12233
+ | MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
12234
+ }
12212
12235
| // ZVAL_DEREF()
12213
12236
| GET_LOW_8BITS TMP1w, REG2w
12214
12237
| IF_NOT_TYPE TMP1w, IS_REFERENCE, >1
12215
12238
| GET_Z_PTR REG0, REG0
12216
12239
| add REG0, REG0, #offsetof(zend_reference, val)
12240
+ if (type >= IS_STRING) {
12241
+ | GET_ZVAL_TYPE_INFO REG2w, val_addr, TMP1
12242
+ }
12217
12243
}
12218
12244
res_info &= ~MAY_BE_GUARD;
12219
12245
ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
12220
- type = concrete_type(res_info);
12221
12246
if (type < IS_STRING) {
12222
12247
|1:
12223
- | IF_NOT_ZVAL_TYPE val_addr, type, &exit_addr, ZREG_TMP1
12248
+ if (type_loaded) {
12249
+ | IF_NOT_TYPE TMP2w, type, &exit_addr
12250
+ } else {
12251
+ | IF_NOT_ZVAL_TYPE val_addr, type, &exit_addr, ZREG_TMP1
12252
+ }
12224
12253
} else {
12225
- | GET_ZVAL_TYPE_INFO REG2w, val_addr, TMP1
12254
+ if (!type_loaded) {
12255
+ type_loaded = 1;
12256
+ | GET_ZVAL_TYPE_INFO REG2w, val_addr, TMP1
12257
+ }
12226
12258
|1:
12227
12259
| GET_LOW_8BITS TMP1w, REG2w
12228
12260
| IF_NOT_TYPE TMP1w, type, &exit_addr
0 commit comments