summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-04-07 18:22:03 +0400
committerDmitry Stogov <dmitry@zend.com>2014-04-07 18:22:03 +0400
commit3167b49ce9533a344cb2f16fa5c815f9f81bb434 (patch)
treea52203a8e76b44bed12c24b63eebafcea17f87d9
parent66b3b907c2702a8c9bb4e31db1273442280f6288 (diff)
downloadphp-git-3167b49ce9533a344cb2f16fa5c815f9f81bb434.tar.gz
Allocate HashTable->arData and HashTable->arHash at once
-rw-r--r--Zend/zend_hash.c29
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c42
-rw-r--r--ext/opcache/zend_persist.c9
-rw-r--r--ext/opcache/zend_persist_calc.c7
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++) {