Skip to content

Commit 6ac1688

Browse files
committed
Reduce amount of "cold" code generated for FETCH_OBJ_* instructions
1 parent 7a9f0cc commit 6ac1688

File tree

2 files changed

+51
-70
lines changed

2 files changed

+51
-70
lines changed

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,26 +1241,32 @@ static void ZEND_FASTCALL zend_jit_verify_return_slow(zval *arg, const zend_op_a
12411241
}
12421242
}
12431243

1244-
static void ZEND_FASTCALL zend_jit_fetch_obj_r_slow(zend_object *zobj, zval *offset, zval *result, uint32_t cache_slot)
1244+
static void ZEND_FASTCALL zend_jit_fetch_obj_r_slow(zend_object *zobj)
12451245
{
12461246
zval *retval;
12471247
zend_execute_data *execute_data = EG(current_execute_data);
1248-
zend_string *name, *tmp_name;
1248+
const zend_op *opline = EX(opline);
1249+
zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
1250+
zval *result = EX_VAR(opline->result.var);
1251+
void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS);
12491252

1250-
name = zval_get_tmp_string(offset, &tmp_name);
1251-
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, CACHE_ADDR(cache_slot), result);
1252-
zend_tmp_string_release(tmp_name);
1253+
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, result);
12531254
if (retval != result) {
12541255
ZVAL_COPY_DEREF(result, retval);
12551256
} else if (UNEXPECTED(Z_ISREF_P(retval))) {
12561257
zend_unwrap_reference(retval);
12571258
}
12581259
}
12591260

1260-
static void ZEND_FASTCALL zend_jit_fetch_obj_r_dynamic(zend_object *zobj, intptr_t prop_offset, zval *offset, zval *result, uint32_t cache_slot)
1261+
static void ZEND_FASTCALL zend_jit_fetch_obj_r_dynamic(zend_object *zobj, intptr_t prop_offset)
12611262
{
12621263
if (zobj->properties) {
12631264
zval *retval;
1265+
zend_execute_data *execute_data = EG(current_execute_data);
1266+
const zend_op *opline = EX(opline);
1267+
zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
1268+
zval *result = EX_VAR(opline->result.var);
1269+
void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS);
12641270

12651271
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
12661272
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
@@ -1269,50 +1275,56 @@ static void ZEND_FASTCALL zend_jit_fetch_obj_r_dynamic(zend_object *zobj, intptr
12691275
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
12701276

12711277
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
1272-
(EXPECTED(p->key == Z_STR_P(offset)) ||
1273-
(EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
1278+
(EXPECTED(p->key == name) ||
1279+
(EXPECTED(p->h == ZSTR_H(name)) &&
12741280
EXPECTED(p->key != NULL) &&
1275-
EXPECTED(ZSTR_LEN(p->key) == Z_STRLEN_P(offset)) &&
1276-
EXPECTED(memcmp(ZSTR_VAL(p->key), Z_STRVAL_P(offset), Z_STRLEN_P(offset)) == 0)))) {
1281+
EXPECTED(ZSTR_LEN(p->key) == ZSTR_LEN(name)) &&
1282+
EXPECTED(memcmp(ZSTR_VAL(p->key), ZSTR_VAL(name), ZSTR_LEN(name)) == 0)))) {
12771283
ZVAL_COPY_DEREF(result, &p->val);
12781284
return;
12791285
}
12801286
}
1281-
CACHE_PTR_EX((void**)((char*)EG(current_execute_data)->run_time_cache + cache_slot) + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
1287+
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
12821288
}
12831289

1284-
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
1290+
retval = zend_hash_find_ex(zobj->properties, name, 1);
12851291

12861292
if (EXPECTED(retval)) {
12871293
intptr_t idx = (char*)retval - (char*)zobj->properties->arData;
1288-
CACHE_PTR_EX((void**)((char*)EG(current_execute_data)->run_time_cache + cache_slot) + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
1294+
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
12891295
ZVAL_COPY_DEREF(result, retval);
12901296
return;
12911297
}
12921298
}
1293-
zend_jit_fetch_obj_r_slow(zobj, offset, result, cache_slot);
1299+
zend_jit_fetch_obj_r_slow(zobj);
12941300
}
12951301

1296-
static void ZEND_FASTCALL zend_jit_fetch_obj_is_slow(zend_object *zobj, zval *offset, zval *result, uint32_t cache_slot)
1302+
static void ZEND_FASTCALL zend_jit_fetch_obj_is_slow(zend_object *zobj)
12971303
{
12981304
zval *retval;
12991305
zend_execute_data *execute_data = EG(current_execute_data);
1300-
zend_string *name, *tmp_name;
1306+
const zend_op *opline = EX(opline);
1307+
zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
1308+
zval *result = EX_VAR(opline->result.var);
1309+
void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS);
13011310

1302-
name = zval_get_tmp_string(offset, &tmp_name);
1303-
retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, CACHE_ADDR(cache_slot), result);
1304-
zend_tmp_string_release(tmp_name);
1311+
retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, result);
13051312
if (retval != result) {
13061313
ZVAL_COPY_DEREF(result, retval);
13071314
} else if (UNEXPECTED(Z_ISREF_P(retval))) {
13081315
zend_unwrap_reference(retval);
13091316
}
13101317
}
13111318

1312-
static void ZEND_FASTCALL zend_jit_fetch_obj_is_dynamic(zend_object *zobj, intptr_t prop_offset, zval *offset, zval *result, uint32_t cache_slot)
1319+
static void ZEND_FASTCALL zend_jit_fetch_obj_is_dynamic(zend_object *zobj, intptr_t prop_offset)
13131320
{
13141321
if (zobj->properties) {
13151322
zval *retval;
1323+
zend_execute_data *execute_data = EG(current_execute_data);
1324+
const zend_op *opline = EX(opline);
1325+
zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
1326+
zval *result = EX_VAR(opline->result.var);
1327+
void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS);
13161328

13171329
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
13181330
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
@@ -1321,28 +1333,28 @@ static void ZEND_FASTCALL zend_jit_fetch_obj_is_dynamic(zend_object *zobj, intpt
13211333
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
13221334

13231335
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
1324-
(EXPECTED(p->key == Z_STR_P(offset)) ||
1325-
(EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) &&
1336+
(EXPECTED(p->key == name) ||
1337+
(EXPECTED(p->h == ZSTR_H(name)) &&
13261338
EXPECTED(p->key != NULL) &&
1327-
EXPECTED(ZSTR_LEN(p->key) == Z_STRLEN_P(offset)) &&
1328-
EXPECTED(memcmp(ZSTR_VAL(p->key), Z_STRVAL_P(offset), Z_STRLEN_P(offset)) == 0)))) {
1339+
EXPECTED(ZSTR_LEN(p->key) == ZSTR_LEN(name)) &&
1340+
EXPECTED(memcmp(ZSTR_VAL(p->key), ZSTR_VAL(name), ZSTR_LEN(name)) == 0)))) {
13291341
ZVAL_COPY_DEREF(result, &p->val);
13301342
return;
13311343
}
13321344
}
1333-
CACHE_PTR_EX((void**)((char*)EG(current_execute_data)->run_time_cache + cache_slot) + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
1345+
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
13341346
}
13351347

1336-
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
1348+
retval = zend_hash_find_ex(zobj->properties, name, 1);
13371349

13381350
if (EXPECTED(retval)) {
13391351
intptr_t idx = (char*)retval - (char*)zobj->properties->arData;
1340-
CACHE_PTR_EX((void**)((char*)EG(current_execute_data)->run_time_cache + cache_slot) + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
1352+
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
13411353
ZVAL_COPY(result, retval);
13421354
return;
13431355
}
13441356
}
1345-
zend_jit_fetch_obj_is_slow(zobj, offset, result, cache_slot);
1357+
zend_jit_fetch_obj_is_slow(zobj);
13461358
}
13471359

13481360
static zend_always_inline zend_bool promotes_to_array(zval *val) {
@@ -1437,26 +1449,27 @@ static zend_never_inline zend_bool zend_handle_fetch_obj_flags(
14371449
return 1;
14381450
}
14391451

1440-
static void ZEND_FASTCALL zend_jit_fetch_obj_w_slow(zend_object *zobj, zval *offset, zval *result, uint32_t cache_slot)
1452+
static void ZEND_FASTCALL zend_jit_fetch_obj_w_slow(zend_object *zobj)
14411453
{
14421454
zval *retval;
14431455
zend_execute_data *execute_data = EG(current_execute_data);
1444-
const zend_op *opline = execute_data->opline;
1445-
zend_string *name, *tmp_name;
1456+
const zend_op *opline = EX(opline);
1457+
zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
1458+
zval *result = EX_VAR(opline->result.var);
1459+
void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS);
14461460

1447-
name = zval_get_tmp_string(offset, &tmp_name);
1448-
retval = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_W, CACHE_ADDR(cache_slot));
1461+
retval = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_W, cache_slot);
14491462
if (NULL == retval) {
1450-
retval = zobj->handlers->read_property(zobj, name, BP_VAR_W, CACHE_ADDR(cache_slot), result);
1463+
retval = zobj->handlers->read_property(zobj, name, BP_VAR_W, cache_slot, result);
14511464
if (retval == result) {
14521465
if (UNEXPECTED(Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1)) {
14531466
ZVAL_UNREF(retval);
14541467
}
1455-
goto end;
1468+
return;
14561469
}
14571470
} else if (UNEXPECTED(Z_ISERROR_P(retval))) {
14581471
ZVAL_ERROR(result);
1459-
goto end;
1472+
return;
14601473
}
14611474

14621475
ZVAL_INDIRECT(result, retval);
@@ -1469,23 +1482,20 @@ static void ZEND_FASTCALL zend_jit_fetch_obj_w_slow(zend_object *zobj, zval *off
14691482
zend_property_info *prop_info = NULL;
14701483

14711484
if (opline->op2_type == IS_CONST) {
1472-
prop_info = CACHED_PTR_EX(CACHE_ADDR(cache_slot) + 2);
1485+
prop_info = CACHED_PTR_EX(cache_slot + 2);
14731486
if (!prop_info) {
14741487
break;
14751488
}
14761489
}
14771490
if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, retval, zobj, prop_info, flags))) {
1478-
goto end;
1491+
return;
14791492
}
14801493
}
14811494
} while (0);
14821495

14831496
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
14841497
ZVAL_NULL(retval);
14851498
}
1486-
1487-
end:
1488-
zend_tmp_string_release(tmp_name);
14891499
}
14901500

14911501
static void ZEND_FASTCALL zend_jit_check_array_promotion(zval *val, zend_property_info *prop)

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10984,15 +10984,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1098410984

1098510985
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || offset == ZEND_WRONG_PROPERTY_OFFSET) {
1098610986
|5:
10987-
| LOAD_ADDR FCARG2a, member
10988-
|.if X64
10989-
| LOAD_ZVAL_ADDR CARG3, res_addr
10990-
| mov CARG4, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)
10991-
|.else
10992-
| sub r4, 8
10993-
| push (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)
10994-
| PUSH_ZVAL_ADDR res_addr, r0
10995-
|.endif
1099610987
| SAVE_VALID_OPLINE opline, r0
1099710988
if (opline->opcode == ZEND_FETCH_OBJ_W) {
1099810989
| EXT_CALL zend_jit_fetch_obj_w_slow, r0
@@ -11001,9 +10992,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1100110992
} else {
1100210993
| EXT_CALL zend_jit_fetch_obj_is_slow, r0
1100310994
}
11004-
|.if not(X64)
11005-
| add r4, 8
11006-
|.endif
1100710995
| jmp >9
1100810996
}
1100910997

@@ -11045,29 +11033,12 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1104511033
&& opline->opcode != ZEND_FETCH_OBJ_W) {
1104611034
|8:
1104711035
| mov FCARG2a, r0
11048-
|.if X64WIN
11049-
| LOAD_ADDR CARG3, member
11050-
| LOAD_ZVAL_ADDR CARG4, res_addr
11051-
| mov aword A5, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)
11052-
|.elif X64
11053-
| LOAD_ADDR CARG3, member
11054-
| LOAD_ZVAL_ADDR CARG4, res_addr
11055-
| mov CARG5, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)
11056-
|.else
11057-
| sub r4, 4
11058-
| push (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)
11059-
| PUSH_ZVAL_ADDR res_addr, r0
11060-
| PUSH_ADDR member, r0
11061-
|.endif
1106211036
| SAVE_VALID_OPLINE opline, r0
1106311037
if (opline->opcode != ZEND_FETCH_OBJ_IS) {
1106411038
| EXT_CALL zend_jit_fetch_obj_r_dynamic, r0
1106511039
} else {
1106611040
| EXT_CALL zend_jit_fetch_obj_is_dynamic, r0
1106711041
}
11068-
|.if not(X64)
11069-
| add r4, 4
11070-
|.endif
1107111042
| jmp >9
1107211043
}
1107311044

0 commit comments

Comments
 (0)