Skip to content

Commit df615f2

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

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

Zend/zend_hash.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,6 +2435,36 @@ 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+
GC_SET_REFCOUNT(target, 1);
2446+
GC_TYPE_INFO(target) = GC_ARRAY;
2447+
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
2448+
2449+
target->nTableMask = source->nTableMask;
2450+
target->nNumUsed = source->nNumUsed;
2451+
target->nNumOfElements = source->nNumOfElements;
2452+
target->nTableSize = source->nTableSize;
2453+
target->nInternalPointer = source->nInternalPointer;
2454+
target->nNextFreeElement = source->nNextFreeElement;
2455+
target->pDestructor = ZVAL_PTR_DTOR;
2456+
2457+
if (HT_IS_PACKED(source)) {
2458+
HT_SET_DATA_ADDR(target, emalloc(HT_PACKED_SIZE(target)));
2459+
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_PACKED_USED_SIZE(source));
2460+
} else {
2461+
HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target)));
2462+
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
2463+
}
2464+
2465+
return target;
2466+
}
2467+
24382468
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source)
24392469
{
24402470
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)