Skip to content

Commit ab7b38e

Browse files
committed
Added new optimized zend_array_destroy() function
1 parent 8319f59 commit ab7b38e

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

Zend/zend_hash.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "zend.h"
2323
#include "zend_globals.h"
24+
#include "zend_variables.h"
2425

2526
#if ZEND_DEBUG
2627
/*
@@ -944,6 +945,47 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
944945
pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT);
945946
}
946947

948+
ZEND_API void zend_array_destroy(HashTable *ht TSRMLS_DC)
949+
{
950+
Bucket *p, *end;
951+
952+
IS_CONSISTENT(ht);
953+
954+
if (ht->nNumUsed) {
955+
956+
/* In some rare cases destructors of regular arrays may be changed */
957+
if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) {
958+
zend_hash_destroy(ht);
959+
return;
960+
}
961+
962+
p = ht->arData;
963+
end = p + ht->nNumUsed;
964+
SET_INCONSISTENT(HT_IS_DESTROYING);
965+
966+
if (ht->u.flags & HASH_FLAG_PACKED) {
967+
do {
968+
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
969+
i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC TSRMLS_CC);
970+
}
971+
} while (++p != end);
972+
} else {
973+
do {
974+
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
975+
i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC TSRMLS_CC);
976+
if (EXPECTED(p->key)) {
977+
zend_string_release(p->key);
978+
}
979+
}
980+
} while (++p != end);
981+
}
982+
983+
SET_INCONSISTENT(HT_DESTROYED);
984+
} else if (EXPECTED(!ht->nTableMask)) {
985+
return;
986+
}
987+
pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT);
988+
}
947989

948990
ZEND_API void zend_hash_clean(HashTable *ht)
949991
{

Zend/zend_hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint
216216
ZEND_API int zend_hash_rehash(HashTable *ht);
217217

218218
ZEND_API void zend_array_dup(HashTable *target, HashTable *source);
219+
ZEND_API void zend_array_destroy(HashTable *ht TSRMLS_DC);
219220

220221
#if ZEND_DEBUG
221222
/* debug */

Zend/zend_objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC)
5454
FREE_HASHTABLE(object->guards);
5555
}
5656
if (object->properties) {
57-
zend_hash_destroy(object->properties);
57+
zend_array_destroy(object->properties TSRMLS_CC);
5858
FREE_HASHTABLE(object->properties);
5959
}
6060
count = object->ce->default_properties_count;

Zend/zend_variables.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
4545
/* break possible cycles */
4646
GC_TYPE(arr) = IS_NULL;
4747
GC_REMOVE_FROM_BUFFER(arr);
48-
zend_hash_destroy(&arr->ht);
48+
zend_array_destroy(&arr->ht TSRMLS_CC);
4949
efree_size(arr, sizeof(zend_array));
5050
}
5151
break;
@@ -105,7 +105,7 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
105105
/* break possible cycles */
106106
GC_TYPE(arr) = IS_NULL;
107107
GC_REMOVE_FROM_BUFFER(arr);
108-
zend_hash_destroy(&arr->ht);
108+
zend_array_destroy(&arr->ht TSRMLS_CC);
109109
efree_size(arr, sizeof(zend_array));
110110
}
111111
break;

0 commit comments

Comments
 (0)