]> granicus.if.org Git - php/commitdiff
Added new optimized zend_array_destroy() function
authorDmitry Stogov <dmitry@zend.com>
Tue, 25 Nov 2014 09:58:29 +0000 (12:58 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 25 Nov 2014 09:58:29 +0000 (12:58 +0300)
Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_objects.c
Zend/zend_variables.c

index 24be94f0d98ba7a2c3657c430e764a890d0b6ec8..2a7cb5a4b8643962a6ed7e4fab334ce1dbfe4d68 100644 (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)
 {
index 0ed47b424d53ee0b83a90b6135057b39ee5a4de8..435e92494c41062c574d8f5c8ef08f456b3d8c07 100644 (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 */
index 9068dceb8b1a00b130c5f4d9df3e4d5b86bec0c2..2778b168ee60319ccf97e66a94fcbe747e009092 100644 (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;
index aae84657914f1cb70aa5d3f71208ec96e82091f6..11d035e85c27223337cf3f8d86cf17df119a934f 100644 (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;