Commit:    540488bf55746a36363c56462e939a56550e3717
Author:    Dmitry Stogov <dmi...@zend.com>         Mon, 10 Jun 2013 11:22:19 
+0400
Parents:   2e9d3e8b39c19ffba559b685f7ed96fee28cba59
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=540488bf55746a36363c56462e939a56550e3717

Log:
Compact HashTables before storing them in shared memory

Changed paths:
  M  ext/opcache/ZendAccelerator.c
  M  ext/opcache/zend_accelerator_util_funcs.c
  M  ext/opcache/zend_accelerator_util_funcs.h


Diff:
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index b62f245..212e1e6 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1126,6 +1126,10 @@ static zend_persistent_script 
*cache_script_in_shared_memory(zend_persistent_scr
                return new_persistent_script;
        }
 
+       if (!compact_persistent_script(new_persistent_script)) {
+               return new_persistent_script;
+       }
+
        /* exclusive lock */
        zend_shared_alloc_lock(TSRMLS_C);
 
diff --git a/ext/opcache/zend_accelerator_util_funcs.c 
b/ext/opcache/zend_accelerator_util_funcs.c
index 33ecf7f..c24d9f1 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) {
diff --git a/ext/opcache/zend_accelerator_util_funcs.h 
b/ext/opcache/zend_accelerator_util_funcs.h
index a926145..ddaae86 100644
--- a/ext/opcache/zend_accelerator_util_funcs.h
+++ b/ext/opcache/zend_accelerator_util_funcs.h
@@ -28,6 +28,7 @@
 void zend_accel_copy_internal_functions(TSRMLS_D);
 
 zend_persistent_script* create_persistent_script(void);
+int compact_persistent_script(zend_persistent_script *script);
 void free_persistent_script(zend_persistent_script *persistent_script, int 
destroy_elements);
 
 void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to