From ab7b38e33617c1364529b600f5ea74a2004c497f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 25 Nov 2014 12:58:29 +0300 Subject: [PATCH] Added new optimized zend_array_destroy() function --- Zend/zend_hash.c | 42 ++++++++++++++++++++++++++++++++++++++++++ Zend/zend_hash.h | 1 + Zend/zend_objects.c | 2 +- Zend/zend_variables.c | 4 ++-- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 24be94f0d9..2a7cb5a4b8 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -21,6 +21,7 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_variables.h" #if ZEND_DEBUG /* @@ -944,6 +945,47 @@ ZEND_API void zend_hash_destroy(HashTable *ht) pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT); } +ZEND_API void zend_array_destroy(HashTable *ht TSRMLS_DC) +{ + Bucket *p, *end; + + IS_CONSISTENT(ht); + + if (ht->nNumUsed) { + + /* In some rare cases destructors of regular arrays may be changed */ + if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) { + zend_hash_destroy(ht); + return; + } + + p = ht->arData; + end = p + ht->nNumUsed; + SET_INCONSISTENT(HT_IS_DESTROYING); + + if (ht->u.flags & HASH_FLAG_PACKED) { + do { + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) { + i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC TSRMLS_CC); + } + } while (++p != end); + } else { + do { + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) { + i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC TSRMLS_CC); + if (EXPECTED(p->key)) { + zend_string_release(p->key); + } + } + } while (++p != end); + } + + SET_INCONSISTENT(HT_DESTROYED); + } else if (EXPECTED(!ht->nTableMask)) { + return; + } + pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT); +} ZEND_API void zend_hash_clean(HashTable *ht) { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 0ed47b424d..435e92494c 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -216,6 +216,7 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint ZEND_API int zend_hash_rehash(HashTable *ht); ZEND_API void zend_array_dup(HashTable *target, HashTable *source); +ZEND_API void zend_array_destroy(HashTable *ht TSRMLS_DC); #if ZEND_DEBUG /* debug */ diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 9068dceb8b..2778b168ee 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -54,7 +54,7 @@ ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC) FREE_HASHTABLE(object->guards); } if (object->properties) { - zend_hash_destroy(object->properties); + zend_array_destroy(object->properties TSRMLS_CC); FREE_HASHTABLE(object->properties); } count = object->ce->default_properties_count; diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index aae8465791..11d035e85c 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -45,7 +45,7 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC) /* break possible cycles */ GC_TYPE(arr) = IS_NULL; GC_REMOVE_FROM_BUFFER(arr); - zend_hash_destroy(&arr->ht); + zend_array_destroy(&arr->ht TSRMLS_CC); efree_size(arr, sizeof(zend_array)); } break; @@ -105,7 +105,7 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC) /* break possible cycles */ GC_TYPE(arr) = IS_NULL; GC_REMOVE_FROM_BUFFER(arr); - zend_hash_destroy(&arr->ht); + zend_array_destroy(&arr->ht TSRMLS_CC); efree_size(arr, sizeof(zend_array)); } break; -- 2.40.0