summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-11-25 12:58:29 +0300
committerDmitry Stogov <dmitry@zend.com>2014-11-25 12:58:29 +0300
commitab7b38e33617c1364529b600f5ea74a2004c497f (patch)
tree8dcc0742e81e667c60c86c0c90357b4a2154d320
parent8319f597229bee1d01e1c88a3a1f08de70cd8900 (diff)
downloadphp-git-ab7b38e33617c1364529b600f5ea74a2004c497f.tar.gz
Added new optimized zend_array_destroy() function
-rw-r--r--Zend/zend_hash.c42
-rw-r--r--Zend/zend_hash.h1
-rw-r--r--Zend/zend_objects.c2
-rw-r--r--Zend/zend_variables.c4
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;