]> granicus.if.org Git - php/commitdiff
Improved zend_hash_clean() and added new optimized zend_symtable_clean()
authorDmitry Stogov <dmitry@zend.com>
Tue, 25 Nov 2014 11:17:21 +0000 (14:17 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 25 Nov 2014 11:17:21 +0000 (14:17 +0300)
Zend/zend_execute.c
Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_variables.c

index 9ef06d25c18385847fc194c2a1a1b0bff0690316..5274f100e1c8efa5ae34b0ad7281fd927258392d 100644 (file)
@@ -1421,12 +1421,12 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val
 ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table TSRMLS_DC) /* {{{ */
 {
        if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
-               zend_hash_destroy(&symbol_table->ht);
+               zend_array_destroy(&symbol_table->ht TSRMLS_CC);
                efree_size(symbol_table, sizeof(zend_array));
        } else {
                /* clean before putting into the cache, since clean
                   could call dtors, which could use cached hash */
-               zend_hash_clean(&symbol_table->ht);
+               zend_symtable_clean(&symbol_table->ht TSRMLS_CC);
                *(++EG(symtable_cache_ptr)) = symbol_table;
        }
 }
index 2a7cb5a4b8643962a6ed7e4fab334ce1dbfe4d68..0f77ca6048b49bf02ba1b05f6d288cfc24a32f90 100644 (file)
@@ -989,21 +989,71 @@ ZEND_API void zend_array_destroy(HashTable *ht TSRMLS_DC)
 
 ZEND_API void zend_hash_clean(HashTable *ht)
 {
-       uint32_t idx;
-       Bucket *p;
+       Bucket *p, *end;
 
        IS_CONSISTENT(ht);
 
-       for (idx = 0; idx < ht->nNumUsed; idx++) {
-               p = ht->arData + idx;
-               if (Z_TYPE(p->val) == IS_UNDEF) continue;
+       if (ht->nNumUsed) {
+               p = ht->arData;
+               end = p + ht->nNumUsed;
                if (ht->pDestructor) {
-                       ht->pDestructor(&p->val);
+                       if (ht->u.flags & HASH_FLAG_PACKED) {
+                               do {
+                                       if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
+                                               ht->pDestructor(&p->val);
+                                       }
+                               } while (++p != end);
+                       } else {
+                               do {
+                                       if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
+                                               ht->pDestructor(&p->val);
+                                               if (EXPECTED(p->key)) {
+                                                       zend_string_release(p->key);
+                                               }
+                                       }
+                               } while (++p != end);
+                       }
+               } else {
+                       if (!(ht->u.flags & HASH_FLAG_PACKED)) {
+                               do {
+                                       if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
+                                               if (EXPECTED(p->key)) {
+                                                       zend_string_release(p->key);
+                                               }
+                                       }
+                               } while (++p != end);
+                       }
                }
-               if (p->key) {
-                       zend_string_release(p->key);
+       }
+       ht->nNumUsed = 0;
+       ht->nNumOfElements = 0;
+       ht->nNextFreeElement = 0;
+       ht->nInternalPointer = INVALID_IDX;
+       if (ht->nTableMask) {
+               if (!(ht->u.flags & HASH_FLAG_PACKED)) {
+                       memset(ht->arHash, INVALID_IDX, ht->nTableSize * sizeof(uint32_t));     
                }
        }
+}
+
+ZEND_API void zend_symtable_clean(HashTable *ht TSRMLS_DC)
+{
+       Bucket *p, *end;
+
+       IS_CONSISTENT(ht);
+
+       if (ht->nNumUsed) {
+               p = ht->arData;
+               end = p + ht->nNumUsed;
+               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);
+       }
        ht->nNumUsed = 0;
        ht->nNumOfElements = 0;
        ht->nNextFreeElement = 0;
index 435e92494c41062c574d8f5c8ef08f456b3d8c07..8f12b0e66e12ebeca6df11e850a69caec8b06c05 100644 (file)
@@ -217,6 +217,7 @@ 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);
+ZEND_API void zend_symtable_clean(HashTable *ht TSRMLS_DC);
 
 #if ZEND_DEBUG
 /* debug */
index 1d3c0d2dcb2fbb8ef5d55184df6f0e60ee869bb8..548d191cfd4792ba28def203f413e97158cd43b7 100644 (file)
@@ -298,7 +298,7 @@ ZEND_API void _zval_ptr_dtor_wrapper(zval *zval_ptr)
 {
        TSRMLS_FETCH();
 
-       i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
+       i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_CC TSRMLS_CC);
 }