diff options
Diffstat (limited to 'ext/opcache/zend_accelerator_util_funcs.c')
-rw-r--r-- | ext/opcache/zend_accelerator_util_funcs.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 33ecf7f18..c24d9f130 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -86,6 +86,53 @@ zend_persistent_script* create_persistent_script(void) return persistent_script; } +static int compact_hash_table(HashTable *ht) +{ + uint i = 3; + uint nSize; + Bucket **t; + + if (!ht->nNumOfElements) { + /* Empty tables don't allocate space for Buckets */ + return 1; + } + + if (ht->nNumOfElements >= 0x80000000) { + /* prevent overflow */ + nSize = 0x80000000; + } else { + while ((1U << i) < ht->nNumOfElements) { + i++; + } + nSize = 1 << i; + } + + if (nSize >= ht->nTableSize) { + /* Keep the size */ + return 1; + } + + t = (Bucket **)pemalloc(nSize * sizeof(Bucket *), ht->persistent); + if (!t) { + return 0; + } + + pefree(ht->arBuckets, ht->persistent); + + ht->arBuckets = t; + ht->nTableSize = nSize; + ht->nTableMask = ht->nTableSize - 1; + zend_hash_rehash(ht); + + return 1; +} + +int compact_persistent_script(zend_persistent_script *persistent_script) +{ + return compact_hash_table(&persistent_script->function_table) && + compact_hash_table(&persistent_script->class_table); +} + void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements) { if (destroy_elements) { |