Skip to content

Commit ebda10b

Browse files
committed
Inline array operations
1 parent 798c58a commit ebda10b

File tree

3 files changed

+120
-83
lines changed

3 files changed

+120
-83
lines changed

Zend/zend_execute.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,7 +2996,7 @@ static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_UNSET(z
29962996
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET EXECUTE_DATA_CC);
29972997
}
29982998

2999-
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, bool is_list, int slow, void **cache_slot EXECUTE_DATA_DC)
2999+
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, bool is_list, int slow EXECUTE_DATA_DC)
30003000
{
30013001
zval *retval;
30023002

@@ -3005,10 +3005,6 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
30053005
try_array:
30063006
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type EXECUTE_DATA_CC);
30073007
ZVAL_COPY_DEREF(result, retval);
3008-
if (cache_slot && !HT_IS_PACKED(Z_ARRVAL_P(container))) {
3009-
Bucket *bucket = (Bucket*)((uintptr_t)retval - XtOffsetOf(Bucket, val));
3010-
CACHE_PTR_EX(cache_slot, (void *)(bucket - Z_ARRVAL_P(container)->arData + 1));
3011-
}
30123008
return;
30133009
} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
30143010
container = Z_REFVAL_P(container);
@@ -3149,37 +3145,30 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
31493145
static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC)
31503146
{
31513147
zval *result = EX_VAR(opline->result.var);
3152-
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0, NULL EXECUTE_DATA_CC);
3153-
}
3154-
3155-
static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R_ex(zval *container, zval *dim, int dim_type, void **cache_slot OPLINE_DC EXECUTE_DATA_DC)
3156-
{
3157-
zval *result = EX_VAR(opline->result.var);
3158-
ZEND_ASSERT(cache_slot);
3159-
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0, cache_slot EXECUTE_DATA_CC);
3148+
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0 EXECUTE_DATA_CC);
31603149
}
31613150

31623151
static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC)
31633152
{
31643153
zval *result = EX_VAR(opline->result.var);
3165-
zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 0, 1, NULL EXECUTE_DATA_CC);
3154+
zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 0, 1 EXECUTE_DATA_CC);
31663155
}
31673156

31683157
static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC)
31693158
{
31703159
zval *result = EX_VAR(opline->result.var);
3171-
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 0, 0, NULL EXECUTE_DATA_CC);
3160+
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 0, 0 EXECUTE_DATA_CC);
31723161
}
31733162

31743163
static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC)
31753164
{
31763165
zval *result = EX_VAR(opline->result.var);
3177-
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0, NULL EXECUTE_DATA_CC);
3166+
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0 EXECUTE_DATA_CC);
31783167
}
31793168

31803169
ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type)
31813170
{
3182-
zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0, NULL NO_EXECUTE_DATA_CC);
3171+
zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0 NO_EXECUTE_DATA_CC);
31833172
}
31843173

31853174
static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, zval *offset EXECUTE_DATA_DC)

Zend/zend_vm_def.h

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10271,15 +10271,18 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (op->op1_type != IS_CONST && op-
1027110271

1027210272
zval *container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
1027310273
zval *dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
10274+
zval *value;
10275+
1027410276
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
1027510277
ZEND_VM_C_LABEL(fetch_dim_r_const_index_array):
1027610278
HashTable *ht = Z_ARRVAL_P(container);
1027710279
if (Z_TYPE_P(dim) == IS_LONG) {
1027810280
zend_long offset = Z_LVAL_P(dim);
1027910281
if (HT_IS_PACKED(ht)) {
1028010282
if (EXPECTED((zend_ulong)offset < (zend_ulong)ht->nNumUsed)) {
10281-
zval *value = &ht->arPacked[offset];
10283+
value = &ht->arPacked[offset];
1028210284
if (EXPECTED(Z_TYPE_P(value) != IS_UNDEF)) {
10285+
ZEND_VM_C_LABEL(fetch_dim_r_cached_index_found):
1028310286
ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
1028410287
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
1028510288
SAVE_OPLINE();
@@ -10290,36 +10293,42 @@ ZEND_VM_C_LABEL(fetch_dim_r_const_index_array):
1029010293
}
1029110294
}
1029210295
}
10293-
SAVE_OPLINE();
10294-
zend_undefined_offset(offset);
10296+
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef);
10297+
}
10298+
uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value);
10299+
if (cached_offset && ht->nNumUsed >= cached_offset) {
10300+
Bucket *b = &ht->arData[cached_offset - 1];
10301+
if (!b->key && b->h == offset) {
10302+
value = &b->val;
10303+
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found);
10304+
}
10305+
}
10306+
10307+
value = _zend_hash_index_find(ht, offset);
10308+
ZEND_VM_C_LABEL(fetch_dim_r_cached_index_check):
10309+
if (EXPECTED(value)) {
10310+
Bucket *bucket = (Bucket*)((uintptr_t)value - XtOffsetOf(Bucket, val));
10311+
CACHE_PTR(opline->extended_value, (void *)(bucket - ht->arData + 1));
10312+
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found);
10313+
} else {
1029510314
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef);
1029610315
}
1029710316
} else {
1029810317
if (UNEXPECTED(HT_IS_PACKED(ht))) {
10299-
SAVE_OPLINE();
10300-
zend_undefined_index(Z_STR_P(dim));
1030110318
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef);
1030210319
}
10303-
}
10304-
10305-
uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value);
10306-
if (cached_offset && ht->nNumUsed >= cached_offset) {
10307-
Bucket *b = &ht->arData[cached_offset - 1];
10308-
if (!b->key ? (Z_TYPE_P(dim) == IS_LONG && b->h == Z_LVAL_P(dim)) : (Z_TYPE_P(dim) == IS_STRING && zend_string_equals(b->key, Z_STR_P(dim)))) {
10309-
ZVAL_COPY_DEREF(EX_VAR(opline->result.var), &b->val);
10310-
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
10311-
FREE_OP1();
10312-
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
10313-
} else {
10314-
ZEND_VM_NEXT_OPCODE();
10320+
uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value);
10321+
if (cached_offset && ht->nNumUsed >= cached_offset) {
10322+
Bucket *b = &ht->arData[cached_offset - 1];
10323+
if (b->key && zend_string_equals(b->key, Z_STR_P(dim))) {
10324+
value = &b->val;
10325+
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found);
1031510326
}
1031610327
}
10317-
}
1031810328

10319-
SAVE_OPLINE();
10320-
zend_fetch_dimension_address_read_R_ex(container, dim, OP2_TYPE, CACHE_ADDR(opline->extended_value) OPLINE_CC EXECUTE_DATA_CC);
10321-
FREE_OP1();
10322-
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
10329+
value = zend_hash_find(ht, Z_STR_P(dim));
10330+
ZEND_VM_C_GOTO(fetch_dim_r_cached_index_check);
10331+
}
1032310332
} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
1032410333
container = Z_REFVAL_P(container);
1032510334
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -10332,13 +10341,20 @@ ZEND_VM_C_LABEL(fetch_dim_r_const_index_slow):
1033210341
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1033310342
dim++;
1033410343
}
10344+
SAVE_OPLINE();
1033510345
zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
1033610346
FREE_OP1();
1033710347
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1033810348
}
1033910349

1034010350
ZEND_VM_C_LABEL(fetch_dim_r_cached_index_undef):
10351+
SAVE_OPLINE();
1034110352
ZVAL_NULL(EX_VAR(opline->result.var));
10353+
if (Z_TYPE_P(dim) == IS_LONG) {
10354+
zend_undefined_offset(Z_LVAL_P(dim));
10355+
} else {
10356+
zend_undefined_index(Z_STR_P(dim));
10357+
}
1034210358
FREE_OP1();
1034310359
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1034410360
}

Zend/zend_vm_execute.h

Lines changed: 76 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)