diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-04-07 18:22:03 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-04-07 18:22:03 +0400 |
commit | 3167b49ce9533a344cb2f16fa5c815f9f81bb434 (patch) | |
tree | a52203a8e76b44bed12c24b63eebafcea17f87d9 | |
parent | 66b3b907c2702a8c9bb4e31db1273442280f6288 (diff) | |
download | php-git-3167b49ce9533a344cb2f16fa5c815f9f81bb434.tar.gz |
Allocate HashTable->arData and HashTable->arHash at once
-rw-r--r-- | Zend/zend_hash.c | 29 | ||||
-rw-r--r-- | ext/opcache/zend_accelerator_util_funcs.c | 42 | ||||
-rw-r--r-- | ext/opcache/zend_persist.c | 9 | ||||
-rw-r--r-- | ext/opcache/zend_persist_calc.c | 7 |
4 files changed, 49 insertions, 38 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 62b75299a2..88bd2afccd 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -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); diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 6e5c420769..6df81e6ee6 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -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); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index c4b10264bb..20f57525cd 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -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; diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 14f971f87b..f0fdd6281e 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -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++) { |