Skip to content

Use more compact representation for packed arrays. #7491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
320ad87
Use more compact representation for packed arrays.
dstogov Sep 14, 2021
63f76a6
Fixed memory leaks in ext/standard/tests/array/shuffle_basic2.phpt
dstogov Sep 14, 2021
ebda1e8
Move condition
dstogov Sep 20, 2021
6b1e401
Revert packed array related changes
dstogov Oct 26, 2021
d5c69ed
Merge branch 'master' into packed_ht
dstogov Oct 26, 2021
ebbde91
ws
dstogov Oct 26, 2021
ea245bd
Packed arrays can't contain IS_INDIRECT elements
dstogov Oct 26, 2021
1b30fd9
Use specific array/hash/packed iterators where possible
dstogov Oct 27, 2021
319383d
Use general hash/packed iterators
dstogov Oct 27, 2021
6092d79
Micro-optimization of genral hash/packed array iteration macros ZEND_…
dstogov Oct 28, 2021
718042a
Fixed ARM64 JIT
dstogov Oct 28, 2021
8e33bf8
Sparate ZEND_ARRAY_ELEMET_SIZE, ZEND_ARRAY_ELEMET, ZEND_ARRAY_NEXT_EL…
dstogov Oct 29, 2021
7c6f54e
Rename ZEND_HASH_*_FOREACH_* iteration macros
dstogov Nov 1, 2021
bf21211
Merge branch 'master' into packed_ht
dstogov Nov 1, 2021
bf4bf22
Fixed typo
dstogov Nov 1, 2021
a9f8192
Fixed comment
dstogov Nov 2, 2021
7b81cde
Remove redundand HT_IS_PACKED asserts and add a missed one
dstogov Nov 2, 2021
570fadd
Use specialized packed/hash iterators
dstogov Nov 2, 2021
cc3b921
Use general hash iteration macros
dstogov Nov 2, 2021
361eb14
Attempt to fix Windows build
dstogov Nov 2, 2021
bf316ba
Use genral macro "ZEND_HASH_ELEMENT(ht, i)" instead of "HT_IS_PACKED(…
dstogov Nov 2, 2021
ff48182
Use specialized packed iterator. (We checked for !HT_IS_CACHE above).
dstogov Nov 3, 2021
9bbaf67
Use general hash/packed iteratr or HT_IS_CACHE check
dstogov Nov 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Zend/Optimizer/block_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,9 +1058,9 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
uint32_t s = 0;
ZEND_ASSERT(b->successors_count == (opline->opcode == ZEND_MATCH ? 1 : 2) + zend_hash_num_elements(jumptable));

ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
Z_LVAL_P(zv) = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[s++]].start);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[s++]].start);
break;
}
Expand Down
12 changes: 6 additions & 6 deletions Zend/Optimizer/dfa_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
ZVAL_TRUE(&tmp);
dst = zend_new_array(zend_hash_num_elements(src));
if (strict) {
ZEND_HASH_FOREACH_VAL(src, val) {
ZEND_ARRAY_FOREACH_VAL(src, val) {
if (Z_TYPE_P(val) == IS_STRING) {
zend_hash_add(dst, Z_STR_P(val), &tmp);
} else if (Z_TYPE_P(val) == IS_LONG) {
Expand All @@ -425,16 +425,16 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
ok = 0;
break;
}
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
} else {
ZEND_HASH_FOREACH_VAL(src, val) {
ZEND_ARRAY_FOREACH_VAL(src, val) {
if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) {
zend_array_destroy(dst);
ok = 0;
break;
}
zend_hash_add(dst, Z_STR_P(val), &tmp);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
}

if (ok) {
Expand Down Expand Up @@ -660,11 +660,11 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
{
HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
zval *zv;
ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)) == old->start) {
Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, dst->start);
}
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) {
opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, dst->start);
}
Expand Down
8 changes: 4 additions & 4 deletions Zend/Optimizer/sccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ static inline zend_result ct_eval_add_array_unpack(zval *result, zval *array) {
}

SEPARATE_ARRAY(result);
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(array), key, value) {
ZEND_ARRAY_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(array), key, value) {
if (key) {
value = zend_hash_update(Z_ARR_P(result), key, value);
} else {
Expand All @@ -597,7 +597,7 @@ static inline zend_result ct_eval_add_array_unpack(zval *result, zval *array) {
return FAILURE;
}
Z_TRY_ADDREF_P(value);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
return SUCCESS;
}

Expand Down Expand Up @@ -2009,7 +2009,7 @@ static void join_hash_tables(HashTable *ret, HashTable *ht1, HashTable *ht2)
zend_string *key;
zval *val1, *val2;

ZEND_HASH_FOREACH_KEY_VAL(ht1, index, key, val1) {
ZEND_ARRAY_FOREACH_KEY_VAL(ht1, index, key, val1) {
if (key) {
val2 = zend_hash_find(ht2, key);
} else {
Expand All @@ -2023,7 +2023,7 @@ static void join_hash_tables(HashTable *ret, HashTable *ht1, HashTable *ht2)
}
Z_TRY_ADDREF_P(val1);
}
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
}

static zend_result join_partial_arrays(zval *a, zval *b)
Expand Down
8 changes: 4 additions & 4 deletions Zend/Optimizer/zend_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,9 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
{
HashTable *jumptable = Z_ARRVAL_P(CRT_CONSTANT(opline->op2));
zval *zv;
ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)));
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
BB_START(i + 1);
break;
Expand Down Expand Up @@ -574,9 +574,9 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
block->successors_count = (opline->opcode == ZEND_MATCH ? 1 : 2) + zend_hash_num_elements(jumptable);
block->successors = zend_arena_calloc(arena, block->successors_count, sizeof(int));

ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
block->successors[s++] = block_map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))];
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();

block->successors[s++] = block_map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)];
if (opline->opcode != ZEND_MATCH) {
Expand Down
8 changes: 4 additions & 4 deletions Zend/Optimizer/zend_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void zend_dump_ht(HashTable *ht)
zval *val;
bool first = 1;

ZEND_HASH_FOREACH_KEY_VAL(ht, index, key, val) {
ZEND_ARRAY_FOREACH_KEY_VAL(ht, index, key, val) {
if (first) {
first = 0;
} else {
Expand All @@ -44,7 +44,7 @@ void zend_dump_ht(HashTable *ht)
}
fprintf(stderr, " =>");
zend_dump_const(val);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
}

void zend_dump_const(const zval *zv)
Expand Down Expand Up @@ -643,7 +643,7 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block
zend_string *key;
zend_ulong num_key;
zval *zv;
ZEND_HASH_FOREACH_KEY_VAL(jumptable, num_key, key, zv) {
ZEND_ARRAY_FOREACH_KEY_VAL(jumptable, num_key, key, zv) {
if (key) {
fprintf(stderr, " \"%s\":", ZSTR_VAL(key));
} else {
Expand All @@ -654,7 +654,7 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block
} else {
fprintf(stderr, " %04u,", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)));
}
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
fprintf(stderr, " default:");
} else {
zend_dump_const(op);
Expand Down
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -2031,14 +2031,14 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
tmp |= MAY_BE_RCN;
}

ZEND_HASH_FOREACH_STR_KEY_VAL(ht, str, val) {
ZEND_ARRAY_FOREACH_STR_KEY_VAL(ht, str, val) {
if (str) {
tmp |= MAY_BE_ARRAY_KEY_STRING;
} else {
tmp |= MAY_BE_ARRAY_KEY_LONG;
}
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
if (HT_IS_PACKED(ht)) {
tmp &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
}
Expand Down
8 changes: 4 additions & 4 deletions Zend/Optimizer/zend_optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,9 +676,9 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z
{
HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
zval *zv;
ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)));
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
break;
}
Expand Down Expand Up @@ -722,9 +722,9 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
{
HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
zval *zv;
ZEND_HASH_FOREACH_VAL(jumptable, zv) {
ZEND_ARRAY_FOREACH_VAL(jumptable, zv) {
Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))]);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]);
break;
}
Expand Down
8 changes: 4 additions & 4 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static void print_hash(smart_str *buf, HashTable *ht, int indent, bool is_object
}
smart_str_appends(buf, "(\n");
indent += PRINT_ZVAL_INDENT;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
ZEND_ARRAY_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
for (i = 0; i < indent; i++) {
smart_str_appendc(buf, ' ');
}
Expand Down Expand Up @@ -345,7 +345,7 @@ static void print_hash(smart_str *buf, HashTable *ht, int indent, bool is_object
smart_str_appends(buf, "] => ");
zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT);
smart_str_appends(buf, "\n");
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
indent -= PRINT_ZVAL_INDENT;
for (i = 0; i < indent; i++) {
smart_str_appendc(buf, ' ');
Expand All @@ -361,7 +361,7 @@ static void print_flat_hash(smart_str *buf, HashTable *ht) /* {{{ */
zend_ulong num_key;
int i = 0;

ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
ZEND_ARRAY_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
if (i++ > 0) {
smart_str_appendc(buf, ',');
}
Expand All @@ -373,7 +373,7 @@ static void print_flat_hash(smart_str *buf, HashTable *ht) /* {{{ */
}
smart_str_appends(buf, "] => ");
zend_print_flat_zval_r_to_buf(buf, tmp);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
}
/* }}} */

Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3919,7 +3919,7 @@ ZEND_API zend_result zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function
fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
fci->params = params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval));

ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) {
ZEND_ARRAY_FOREACH_VAL(Z_ARRVAL_P(args), arg) {
if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) {
ZVAL_NEW_REF(params, arg);
Z_TRY_ADDREF_P(arg);
Expand All @@ -3928,7 +3928,7 @@ ZEND_API zend_result zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function
}
params++;
n++;
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();

return SUCCESS;
}
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2798,10 +2798,10 @@ static void *tracked_realloc(void *ptr, size_t new_size) {
static void tracked_free_all() {
HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs;
zend_ulong h;
ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) {
ZEND_ARRAY_FOREACH_NUM_KEY(tracked_allocs, h) {
void *ptr = (void *) (uintptr_t) (h << ZEND_MM_ALIGNMENT_LOG2);
free(ptr);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
}
#endif

Expand Down
8 changes: 4 additions & 4 deletions Zend/zend_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) {
zval *val;
zend_string *key;

ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZEND_ARRAY_FOREACH_STR_KEY_VAL(ht, key, val) {
if (key) {
zend_hash_update(Z_ARRVAL_P(result), key, val);
} else {
Expand All @@ -471,7 +471,7 @@ static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) {
}
}
Z_TRY_ADDREF_P(val);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
return SUCCESS;
}

Expand Down Expand Up @@ -1418,7 +1418,7 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priorit
zval *val;
bool first = true;
smart_str_appendc(str, '[');
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zv), idx, key, val) {
ZEND_ARRAY_FOREACH_KEY_VAL(Z_ARRVAL_P(zv), idx, key, val) {
if (first) {
first = false;
} else {
Expand All @@ -1433,7 +1433,7 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priorit
smart_str_appends(str, " => ");
}
zend_ast_export_zval(str, val, 0, indent);
} ZEND_HASH_FOREACH_END();
} ZEND_ARRAY_FOREACH_END();
smart_str_appendc(str, ']');
break;
}
Expand Down
12 changes: 6 additions & 6 deletions Zend/zend_attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname,
if (attributes) {
zend_attribute *attr;

ZEND_HASH_FOREACH_PTR(attributes, attr) {
ZEND_PACKED_FOREACH_PTR(attributes, attr) {
if (attr->offset == offset && zend_string_equals(attr->lcname, lcname)) {
return attr;
}
} ZEND_HASH_FOREACH_END();
} ZEND_PACKED_FOREACH_END();
}

return NULL;
Expand All @@ -93,13 +93,13 @@ static zend_attribute *get_attribute_str(HashTable *attributes, const char *str,
if (attributes) {
zend_attribute *attr;

ZEND_HASH_FOREACH_PTR(attributes, attr) {
ZEND_PACKED_FOREACH_PTR(attributes, attr) {
if (attr->offset == offset && ZSTR_LEN(attr->lcname) == len) {
if (0 == memcmp(ZSTR_VAL(attr->lcname), str, len)) {
return attr;
}
}
} ZEND_HASH_FOREACH_END();
} ZEND_PACKED_FOREACH_END();
}

return NULL;
Expand Down Expand Up @@ -173,13 +173,13 @@ ZEND_API bool zend_is_attribute_repeated(HashTable *attributes, zend_attribute *
{
zend_attribute *other;

ZEND_HASH_FOREACH_PTR(attributes, other) {
ZEND_PACKED_FOREACH_PTR(attributes, other) {
if (other != attr && other->offset == attr->offset) {
if (zend_string_equals(other->lcname, attr->lcname)) {
return 1;
}
}
} ZEND_HASH_FOREACH_END();
} ZEND_PACKED_FOREACH_END();

return 0;
}
Expand Down
Loading