]> granicus.if.org Git - php/commitdiff
Use light version of zend_array_destroy() to free arrays without refcounted elements...
authorDmitry Stogov <dmitry@zend.com>
Tue, 19 May 2020 21:12:24 +0000 (00:12 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 19 May 2020 21:12:24 +0000 (00:12 +0300)
ext/opcache/jit/zend_jit_helpers.c
ext/opcache/jit/zend_jit_x86.dasc

index ed7708126ca8a78a801b06ab5e9fcd49b6622a56..29f5d5f68e4862fe75304731c924e4a6292542f6 100644 (file)
@@ -1537,3 +1537,30 @@ static void ZEND_FASTCALL zend_jit_pre_dec(zval *var_ptr, zval *ret)
        decrement_function(var_ptr);
        ZVAL_COPY(ret, var_ptr);
 }
+
+#define HT_POISONED_PTR ((HashTable *) (intptr_t) -1)
+
+static zend_never_inline void ZEND_FASTCALL _zend_hash_iterators_remove(HashTable *ht)
+{
+       HashTableIterator *iter = EG(ht_iterators);
+       HashTableIterator *end  = iter + EG(ht_iterators_used);
+
+       while (iter != end) {
+               if (iter->ht == ht) {
+                       iter->ht = HT_POISONED_PTR;
+               }
+               iter++;
+       }
+}
+
+static void ZEND_FASTCALL zend_jit_array_free(HashTable *ht)
+{
+       GC_REMOVE_FROM_BUFFER(ht);
+       if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
+               _zend_hash_iterators_remove(ht);
+       }
+       if (!(EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED))) {
+               efree(HT_GET_DATA_ADDR(ht));
+       }
+       FREE_HASHTABLE(ht);
+}
index 87b10f7122b130dba1691c5803ee655c27590031..217c5d141aaa2b77cabaf09da0ce02f0f086a8da 100644 (file)
@@ -1316,10 +1316,14 @@ static void* dasm_labels[zend_lb_MAX];
 |                              EXT_CALL _efree, r0
 ||                             break;
 ||                     } else if (type == IS_ARRAY) {
-||                             if (opline) {
-|                                      SAVE_VALID_OPLINE opline, r0
+||                             if ((var_info) & (MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF)) {
+||                                     if (opline && ((var_info) & (MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF))) {
+|                                              SAVE_VALID_OPLINE opline, r0
+||                                     }
+|                                      EXT_CALL zend_array_destroy, r0
+||                             } else {
+|                                      EXT_CALL zend_jit_array_free, r0|
 ||                             }
-|                              EXT_CALL zend_array_destroy, r0
 ||                             break;
 ||                     } else if (type == IS_OBJECT) {
 ||                             if (opline) {