Added new optimized zend_array_destroy() function

This commit is contained in:
Dmitry Stogov 2014-11-25 12:58:29 +03:00
parent 8319f59722
commit ab7b38e336
4 changed files with 46 additions and 3 deletions

View file

@ -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)
{

View file

@ -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 */

View file

@ -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;

View file

@ -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;