Skip to content

Commit 31b7aef

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: JIT: Avoid property type reloading
2 parents a12aee5 + bec1d2f commit 31b7aef

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11943,6 +11943,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1194311943
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
1194411944
zend_jit_addr prop_addr;
1194511945
uint32_t res_info = RES_INFO();
11946+
bool type_loaded = 0;
1194611947

1194711948
ZEND_ASSERT(opline->op2_type == IS_CONST);
1194811949
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
@@ -12033,6 +12034,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1203312034
| ldr REG2w, [TMP1, #offsetof(zval,u1.type_info)]
1203412035
| IF_UNDEF REG2w, >5
1203512036
| mov FCARG1x, TMP1
12037+
type_loaded = 1;
1203612038
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1, 0);
1203712039
if (opline->opcode == ZEND_FETCH_OBJ_W
1203812040
&& (!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,
1207412076
}
1207512077
} else {
1207612078
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
1207812079
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
1207912080
if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
1208012081
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
@@ -12084,12 +12085,20 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1208412085
if (!exit_addr) {
1208512086
return 0;
1208612087
}
12088+
type_loaded = 1;
12089+
| MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
1208712090
| IF_UNDEF REG2w, &exit_addr
1208812091
}
1208912092
} else {
12093+
type_loaded = 1;
12094+
| MEM_ACCESS_32_WITH_UOFFSET ldr, REG2w, FCARG1x, (prop_info->offset + offsetof(zval,u1.type_info)), TMP1
1209012095
| IF_UNDEF REG2w, >5
1209112096
}
1209212097
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+
}
1209312102
| IF_NOT_TYPE REG2w, IS_OBJECT_EX, >4
1209412103
| GET_ZVAL_PTR REG2, prop_addr, TMP1
1209512104
| GC_ADDREF REG2, TMP1w
@@ -12112,6 +12121,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1211212121

1211312122
if (flags == ZEND_FETCH_DIM_WRITE) {
1211412123
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+
}
1211512128
| cmp REG2w, #IS_FALSE
1211612129
| ble >1
1211712130
|.cold_code
@@ -12126,6 +12139,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1212612139
|.code
1212712140
}
1212812141
} 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+
}
1212912146
| GET_LOW_8BITS TMP1w, REG2w
1213012147
| IF_TYPE TMP1w, IS_REFERENCE, >1
1213112148
if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) {
@@ -12188,6 +12205,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1218812205
ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
1218912206
}
1219012207

12208+
type = concrete_type(res_info);
12209+
1219112210
if (prop_type != IS_UNKNOWN
1219212211
&& prop_type != IS_UNDEF
1219312212
&& prop_type != IS_REFERENCE
@@ -12209,20 +12228,33 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1220912228
return 0;
1221012229
}
1221112230

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+
}
1221212235
| // ZVAL_DEREF()
1221312236
| GET_LOW_8BITS TMP1w, REG2w
1221412237
| IF_NOT_TYPE TMP1w, IS_REFERENCE, >1
1221512238
| GET_Z_PTR REG0, REG0
1221612239
| add REG0, REG0, #offsetof(zend_reference, val)
12240+
if (type >= IS_STRING) {
12241+
| GET_ZVAL_TYPE_INFO REG2w, val_addr, TMP1
12242+
}
1221712243
}
1221812244
res_info &= ~MAY_BE_GUARD;
1221912245
ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
12220-
type = concrete_type(res_info);
1222112246
if (type < IS_STRING) {
1222212247
|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+
}
1222412253
} 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+
}
1222612258
|1:
1222712259
| GET_LOW_8BITS TMP1w, REG2w
1222812260
| IF_NOT_TYPE TMP1w, type, &exit_addr

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12637,6 +12637,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1263712637
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
1263812638
zend_jit_addr prop_addr;
1263912639
uint32_t res_info = RES_INFO();
12640+
bool type_loaded = 0;
1264012641

1264112642
ZEND_ASSERT(opline->op2_type == IS_CONST);
1264212643
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
@@ -12725,6 +12726,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1272512726
| mov edx, dword [FCARG1a + r0 + 8]
1272612727
| IF_UNDEF dl, >5
1272712728
| add FCARG1a, r0
12729+
type_loaded = 1;
1272812730
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1, 0);
1272912731
if (opline->opcode == ZEND_FETCH_OBJ_W
1273012732
&& (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS))) {
@@ -12774,7 +12776,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1277412776
}
1277512777
} else {
1277612778
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1, prop_info->offset);
12777-
| mov edx, dword [FCARG1a + prop_info->offset + 8]
1277812779
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
1277912780
if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
1278012781
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
@@ -12784,12 +12785,20 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1278412785
if (!exit_addr) {
1278512786
return 0;
1278612787
}
12788+
type_loaded = 1;
12789+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
1278712790
| IF_UNDEF dl, &exit_addr
1278812791
}
1278912792
} else {
12793+
type_loaded = 1;
12794+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
1279012795
| IF_UNDEF dl, >5
1279112796
}
1279212797
if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_READONLY)) {
12798+
if (!type_loaded) {
12799+
type_loaded = 1;
12800+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
12801+
}
1279312802
| IF_NOT_TYPE dl, IS_OBJECT, >4
1279412803
| GET_ZVAL_PTR r0, prop_addr
1279512804
| GC_ADDREF r0
@@ -12812,6 +12821,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1281212821

1281312822
if (flags == ZEND_FETCH_DIM_WRITE) {
1281412823
if ((ZEND_TYPE_FULL_MASK(prop_info->type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY)) == 0) {
12824+
if (!type_loaded) {
12825+
type_loaded = 1;
12826+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
12827+
}
1281512828
| cmp dl, IS_FALSE
1281612829
| jle >1
1281712830
|.cold_code
@@ -12826,6 +12839,10 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1282612839
|.code
1282712840
}
1282812841
} else if (flags == ZEND_FETCH_REF) {
12842+
if (!type_loaded) {
12843+
type_loaded = 1;
12844+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
12845+
}
1282912846
| IF_TYPE dl, IS_REFERENCE, >1
1283012847
if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) {
1283112848
| LOAD_ADDR FCARG2a, prop_info
@@ -12895,6 +12912,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1289512912
ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
1289612913
}
1289712914

12915+
type = concrete_type(res_info);
12916+
1289812917
if (prop_type != IS_UNKNOWN
1289912918
&& prop_type != IS_UNDEF
1290012919
&& prop_type != IS_REFERENCE
@@ -12916,19 +12935,32 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1291612935
return 0;
1291712936
}
1291812937

12938+
if (!type_loaded) {
12939+
type_loaded = 1;
12940+
| mov edx, dword [FCARG1a + prop_info->offset + 8]
12941+
}
1291912942
| // ZVAL_DEREF()
1292012943
| IF_NOT_TYPE dl, IS_REFERENCE, >1
1292112944
| GET_Z_PTR r0, r0
1292212945
| add r0, offsetof(zend_reference, val)
12946+
if (type >= IS_STRING) {
12947+
| GET_ZVAL_TYPE_INFO edx, val_addr
12948+
}
1292312949
}
1292412950
res_info &= ~MAY_BE_GUARD;
1292512951
ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
12926-
type = concrete_type(res_info);
1292712952
if (type < IS_STRING) {
1292812953
|1:
12929-
| IF_NOT_ZVAL_TYPE val_addr, type, &exit_addr
12954+
if (type_loaded) {
12955+
| IF_NOT_TYPE dl, type, &exit_addr
12956+
} else {
12957+
| IF_NOT_ZVAL_TYPE val_addr, type, &exit_addr
12958+
}
1293012959
} else {
12931-
| GET_ZVAL_TYPE_INFO edx, val_addr
12960+
if (!type_loaded) {
12961+
type_loaded = 1;
12962+
| GET_ZVAL_TYPE_INFO edx, val_addr
12963+
}
1293212964
|1:
1293312965
| IF_NOT_TYPE dl, type, &exit_addr
1293412966
}

0 commit comments

Comments
 (0)