Skip to content

Commit 39143f8

Browse files
committed
Use optimized zend_array_dup_immutable()
We can make some assumptions about the value of the fields.
1 parent 3747883 commit 39143f8

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

Zend/zend_hash.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,6 +2435,34 @@ static zend_always_inline uint32_t zend_array_dup_elements(const HashTable *sour
24352435
return idx;
24362436
}
24372437

2438+
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup_immutable(const HashTable *source)
2439+
{
2440+
IS_CONSISTENT(source);
2441+
ZEND_ASSERT(GC_FLAGS(source) & IS_ARRAY_IMMUTABLE);
2442+
2443+
HashTable *target;
2444+
ALLOC_HASHTABLE(target);
2445+
2446+
*target = *source;
2447+
2448+
/* Immutable arrays don't have an iterator count. */
2449+
ZEND_ASSERT(HT_FLAGS(source) == (HT_FLAGS(source) & HASH_FLAG_MASK));
2450+
2451+
GC_SET_REFCOUNT(target, 1);
2452+
GC_TYPE_INFO(target) = GC_ARRAY;
2453+
target->pDestructor = ZVAL_PTR_DTOR;
2454+
2455+
if (HT_IS_PACKED(source)) {
2456+
HT_SET_DATA_ADDR(target, emalloc(HT_PACKED_SIZE(target)));
2457+
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_PACKED_USED_SIZE(source));
2458+
} else {
2459+
HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target)));
2460+
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
2461+
}
2462+
2463+
return target;
2464+
}
2465+
24382466
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source)
24392467
{
24402468
uint32_t idx;

Zend/zend_hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size);
345345
ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(const zval *val1, const zval *val2);
346346
ZEND_API uint32_t zend_array_count(HashTable *ht);
347347
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source);
348+
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup_immutable(const HashTable *source);
348349
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht);
349350
ZEND_API HashTable* zend_array_to_list(const HashTable *source);
350351
ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht);

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6442,7 +6442,7 @@ ZEND_VM_HANDLER(210, ZEND_ARRAY_DUP, CONST, UNUSED)
64426442
zend_array *copy;
64436443
USE_OPLINE
64446444

6445-
copy = zend_array_dup(Z_ARRVAL_P(GET_OP1_ZVAL_PTR(BP_VAR_R)));
6445+
copy = zend_array_dup_immutable(Z_ARRVAL_P(GET_OP1_ZVAL_PTR(BP_VAR_R)));
64466446
ZVAL_ARR(EX_VAR(opline->result.var), copy);
64476447

64486448
ZEND_VM_NEXT_OPCODE();

Zend/zend_vm_execute.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)