]> granicus.if.org Git - php/commitdiff
Allocate HashTable->arData and HashTable->arHash at once
authorDmitry Stogov <dmitry@zend.com>
Mon, 7 Apr 2014 14:22:03 +0000 (18:22 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 7 Apr 2014 14:22:03 +0000 (18:22 +0400)
Zend/zend_hash.c
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c

index 62b75299a2df92223f533da169e5bd64f56fdf67..88bd2afccd5b5543d12a9ce488057edc11d382bb 100644 (file)
@@ -82,11 +82,12 @@ static void zend_hash_do_resize(HashTable *ht);
 
 #define CHECK_INIT(ht, packed) do {                                                                                            \
        if (UNEXPECTED((ht)->nTableMask == 0)) {                                                        \
-               (ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket), 0, (ht)->flags & HASH_FLAG_PERSISTENT);       \
                if (packed) { \
+                       (ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket), 0, (ht)->flags & HASH_FLAG_PERSISTENT);       \
                        (ht)->flags |= HASH_FLAG_PACKED; \
                } else { \
-                       (ht)->arHash = (zend_uint*) safe_pemalloc((ht)->nTableSize, sizeof(zend_uint), 0, (ht)->flags & HASH_FLAG_PERSISTENT);  \
+                       (ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket) + sizeof(zend_uint), 0, (ht)->flags & HASH_FLAG_PERSISTENT);   \
+                       (ht)->arHash = (zend_uint*)((ht)->arData + (ht)->nTableSize);   \
                        memset((ht)->arHash, INVALID_IDX, (ht)->nTableSize * sizeof(zend_uint));        \
                } \
                (ht)->nTableMask = (ht)->nTableSize - 1;                                                \
@@ -131,7 +132,7 @@ ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor,
 static void zend_hash_packed_grow(HashTable *ht)
 {
        HANDLE_BLOCK_INTERRUPTIONS();
-       ht->arData = (Bucket *) perealloc(ht->arData, (ht->nTableSize << 1) * sizeof(Bucket), ht->flags & HASH_FLAG_PERSISTENT);
+       ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket), 0, ht->flags & HASH_FLAG_PERSISTENT);
        ht->nTableSize = (ht->nTableSize << 1);
        ht->nTableMask = ht->nTableSize - 1;
        HANDLE_UNBLOCK_INTERRUPTIONS();
@@ -148,7 +149,8 @@ ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
 {
        HANDLE_BLOCK_INTERRUPTIONS();
        ht->flags &= ~HASH_FLAG_PACKED;
-       ht->arHash = (zend_uint*) safe_pemalloc(ht->nTableSize, sizeof(zend_uint), 0, ht->flags & HASH_FLAG_PERSISTENT);
+       ht->arData = (Bucket *) safe_perealloc(ht->arData, ht->nTableSize, sizeof(Bucket) + sizeof(zend_uint), 0, ht->flags & HASH_FLAG_PERSISTENT);
+       ht->arHash = (zend_uint*)(ht->arData + ht->nTableSize);
        zend_hash_rehash(ht);
        HANDLE_UNBLOCK_INTERRUPTIONS();
 }
@@ -157,7 +159,8 @@ ZEND_API void zend_hash_to_packed(HashTable *ht)
 {
        HANDLE_BLOCK_INTERRUPTIONS();
        ht->flags |= HASH_FLAG_PACKED;
-       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
+//???  pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
+       ht->arData = erealloc(ht->arData, ht->nTableSize * sizeof(Bucket));
        ht->arHash = (zend_uint*)&uninitialized_bucket;
        HANDLE_UNBLOCK_INTERRUPTIONS();
 }
@@ -463,8 +466,8 @@ static void zend_hash_do_resize(HashTable *ht)
                HANDLE_UNBLOCK_INTERRUPTIONS();
        } else if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
                HANDLE_BLOCK_INTERRUPTIONS();
-               ht->arData = (Bucket *) perealloc(ht->arData, (ht->nTableSize << 1) * sizeof(Bucket), ht->flags & HASH_FLAG_PERSISTENT);
-               ht->arHash = (zend_uint *) perealloc(ht->arHash, (ht->nTableSize << 1) * sizeof(zend_uint), ht->flags & HASH_FLAG_PERSISTENT);
+               ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket) + sizeof(zend_uint), 0, ht->flags & HASH_FLAG_PERSISTENT);
+               ht->arHash = (zend_uint*)(ht->arData + (ht->nTableSize << 1));
                ht->nTableSize = (ht->nTableSize << 1);
                ht->nTableMask = ht->nTableSize - 1;
                zend_hash_rehash(ht);
@@ -797,9 +800,6 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
        }
        if (ht->nTableMask) {
                pefree(ht->arData, ht->flags & HASH_FLAG_PERSISTENT);
-               if (!(ht->flags & HASH_FLAG_PACKED)) {
-                       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
-               }
        }
 
        SET_INCONSISTENT(HT_DESTROYED);
@@ -865,9 +865,6 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
        }
        if (ht->nTableMask) {
                pefree(ht->arData, ht->flags & HASH_FLAG_PERSISTENT);
-               if (!(ht->flags & HASH_FLAG_PACKED)) {
-                       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
-               }
        }
 
        SET_INCONSISTENT(HT_DESTROYED);
@@ -890,9 +887,6 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
 
        if (ht->nTableMask) {
                pefree(ht->arData, ht->flags & HASH_FLAG_PERSISTENT);
-               if (!(ht->flags & HASH_FLAG_PACKED)) {
-                       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
-               }
        }
 
        SET_INCONSISTENT(HT_DESTROYED);
@@ -1653,7 +1647,8 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
        } else {
                if (renumber) {
                        ht->flags |= HASH_FLAG_PACKED;
-                       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
+//???                  pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
+                       ht->arData = erealloc(ht->arData, ht->nTableSize * sizeof(Bucket));
                        ht->arHash = (zend_uint*)&uninitialized_bucket;
                } else {
                        zend_hash_rehash(ht);
index 6e5c420769e28fc2339f66489c09a771e5b42e4e..6df81e6ee6d1720b6e76ff4b6bc968d89be2e9b7 100644 (file)
@@ -93,7 +93,6 @@ static int compact_hash_table(HashTable *ht)
        uint j;
        uint nSize;
        Bucket *d;
-       zend_uint *h;
        Bucket *p;
 
        if (!ht->nNumOfElements || (ht->flags & HASH_FLAG_PACKED)) {
@@ -116,9 +115,8 @@ static int compact_hash_table(HashTable *ht)
                return 1;
        }
 
-       d = (Bucket *)pemalloc(nSize * sizeof(Bucket), ht->flags & HASH_FLAG_PERSISTENT);
-       h = (zend_uint *)pemalloc(nSize * sizeof(zend_uint), ht->flags & HASH_FLAG_PERSISTENT);
-       if (!d || !h) {
+       d = (Bucket *)pemalloc(nSize * (sizeof(Bucket) + sizeof(zend_uint)), ht->flags & HASH_FLAG_PERSISTENT);
+       if (!d) {
                return 0;
        }
 
@@ -131,10 +129,9 @@ static int compact_hash_table(HashTable *ht)
        ht->nNumUsed = j;
 
        pefree(ht->arData, ht->flags & HASH_FLAG_PERSISTENT);
-       pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
 
        ht->arData = d;
-       ht->arHash = h;
+       ht->arHash = (zend_uint *)(d + nSize);
        ht->nTableSize = nSize;
        ht->nTableMask = ht->nTableSize - 1;
        zend_hash_rehash(ht);
@@ -373,12 +370,13 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
        }
 #endif
 
-       ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
        if (source->flags & HASH_FLAG_PACKED) {
                ht->flags |= HASH_FLAG_PACKED;
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * sizeof(Bucket));
                ht->arHash = (zend_uint*)&uninitialized_bucket;
        } else {
-               ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint));
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(zend_uint)));
+               ht->arHash = (zend_uint*)(ht->arData + ht->nTableSize);
                memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize);
        }
 
@@ -389,7 +387,12 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
 
                /* Insert into hash collision list */
                if (source->flags & HASH_FLAG_PACKED) {
+                       Bucket *r = ht->arData + ht->nNumUsed;
                        q = ht->arData + p->h;
+                       while (r != q) {
+                               ZVAL_UNDEF(&r->val);
+                               r++;
+                       }
                        ht->nNumUsed = p->h + 1;
                } else {
                        q = ht->arData + ht->nNumUsed;
@@ -441,12 +444,13 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
        }
 #endif
 
-       ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
        if (source->flags & HASH_FLAG_PACKED) {
                ht->flags |= HASH_FLAG_PACKED;
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * sizeof(Bucket));
                ht->arHash = (zend_uint*)&uninitialized_bucket;
        } else {
-               ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint));
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(zend_uint)));
+               ht->arHash = (zend_uint *)(ht->arData + ht->nTableSize);
                memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize);
        }
 
@@ -458,7 +462,12 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
 
                /* Insert into hash collision list */
                if (source->flags & HASH_FLAG_PACKED) {
+                       Bucket *r = ht->arData + ht->nNumUsed;
                        q = ht->arData + p->h;
+                       while (r != q) {
+                               ZVAL_UNDEF(&r->val);
+                               r++;
+                       }
                        ht->nNumUsed = p->h + 1;
                } else {
                        q = ht->arData + ht->nNumUsed;
@@ -536,12 +545,13 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
        }
 #endif
 
-       ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
        if (source->flags & HASH_FLAG_PACKED) {
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * sizeof(Bucket));
                ht->flags |= HASH_FLAG_PACKED;
                ht->arHash = (zend_uint*)&uninitialized_bucket;
        } else {
-               ht->arHash = (zend_uint *) ecalloc(ht->nTableSize, sizeof(zend_uint));
+               ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(zend_uint)));
+               ht->arHash = (zend_uint*)(ht->arData + ht->nTableSize);
                memset(ht->arHash, INVALID_IDX, sizeof(zend_uint) * ht->nTableSize);
        }
 
@@ -553,7 +563,12 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
 
                /* Insert into hash collision list */
                if (source->flags & HASH_FLAG_PACKED) {
+                       Bucket *r = ht->arData + ht->nNumUsed;
                        q = ht->arData + p->h;
+                       while (r != q) {
+                               ZVAL_UNDEF(&r->val);
+                               r++;
+                       }
                        ht->nNumUsed = p->h + 1;
                } else {
                        q = ht->arData + ht->nNumUsed;
@@ -872,7 +887,7 @@ failure:
 
 static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC)
 {
-       zend_class_entry *ce1, *ce2;
+       zend_class_entry *ce1;
        uint idx;
        Bucket *p;
        zval *t;
@@ -909,7 +924,6 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, uni
 
 failure:
        ce1 = Z_PTR(p->val);
-       ce2 = Z_PTR_P(t);
        CG(in_compilation) = 1;
 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
        zend_set_compiled_filename(ce1->info.user.filename TSRMLS_CC);
index c4b10264bbff091db0e8ed0ed8ab988626f42ac7..20f57525cdae422efc774b40e3f533a68154bf53 100644 (file)
@@ -67,11 +67,12 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement
                ht->arHash = (zend_uint*)&uninitialized_bucket;
                return;
        }
-       zend_accel_store(ht->arData, sizeof(Bucket) * ht->nTableSize);
-       if (!(ht->flags & HASH_FLAG_PACKED)) {
-               zend_accel_store(ht->arHash, sizeof(zend_uint) * ht->nTableSize);
-       } else {
+       if (ht->flags & HASH_FLAG_PACKED) {
+               zend_accel_store(ht->arData, sizeof(Bucket) * ht->nTableSize);
                ht->arHash = (zend_uint*)&uninitialized_bucket;
+       } else {
+               zend_accel_store(ht->arData, (sizeof(Bucket) + sizeof(zend_uint)) * ht->nTableSize);
+               ht->arHash = (zend_uint*)(ht->arData + ht->nTableSize);
        }
        for (idx = 0; idx < ht->nNumUsed; idx++) {
                p = ht->arData + idx;
index 14f971f87b4f05cf5943353ae7b1175954139b6c..f0fdd6281eb1d6a24bd8c238d9a24d3de8ae5783 100644 (file)
@@ -62,9 +62,10 @@ static uint zend_hash_persist_calc(HashTable *ht, uint (*pPersistElement)(zval *
        if (!ht->nTableMask) {
                RETURN_SIZE();
        }
-       ADD_DUP_SIZE(ht->arData, sizeof(Bucket) * ht->nTableSize);
-       if (!(ht->flags & HASH_FLAG_PACKED)) {
-               ADD_DUP_SIZE(ht->arHash, sizeof(zend_uint) * ht->nTableSize);
+       if (ht->flags & HASH_FLAG_PACKED) {
+               ADD_DUP_SIZE(ht->arData, sizeof(Bucket) * ht->nTableSize);
+       } else {
+               ADD_DUP_SIZE(ht->arData, (sizeof(Bucket) + sizeof(zend_uint)) * ht->nTableSize);
        }
 
        for (idx = 0; idx < ht->nNumUsed; idx++) {