]> granicus.if.org Git - php/commitdiff
Avoid useless op_array duplication
authorDmitry Stogov <dmitry@zend.com>
Thu, 5 Mar 2015 11:23:48 +0000 (14:23 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 5 Mar 2015 11:23:48 +0000 (14:23 +0300)
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c

index e4430bf0a26444029d6b660eb44767db4e358d38..8c89a8d5d6ac47565ce7f9f98aa2b88692303f25 100644 (file)
@@ -401,11 +401,15 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
                ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val)));
                new_entry = (zend_op_array*)Z_PTR(q->val);
 
-               new_entry->scope = ARENA_REALLOC(new_entry->scope);
+               if ((void*)new_entry->scope >= ZCG(current_persistent_script)->arena_mem &&
+                   (void*)new_entry->scope < (void*)((char*)ZCG(current_persistent_script)->arena_mem + ZCG(current_persistent_script)->arena_size)) {
 
-               /* update prototype */
-               if (new_entry->prototype) {
-                       new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
+                       new_entry->scope = ARENA_REALLOC(new_entry->scope);
+
+                       /* update prototype */
+                       if (new_entry->prototype) {
+                               new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
+                       }
                }
        }
 }
index fdba5069f4b47371c9612816a261b73dd3f84b29..43376ed2a99e36ba82e51cfd12ac9b72c520f7ad 100644 (file)
@@ -572,6 +572,15 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
 
 static void zend_persist_op_array(zval *zv)
 {
+       zend_op_array *op_array = Z_PTR_P(zv);
+       zend_op_array *old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
+       if (old_op_array) {
+               Z_PTR_P(zv) = old_op_array;
+               if (op_array->refcount && --(*op_array->refcount) == 0) {
+                       efree(op_array->refcount);
+               }
+               return;
+       }
        memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_op_array));
        zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem));
        Z_PTR_P(zv) = ZCG(arena_mem);
index d7fbaa272a596855e6b00519b6cc2156c0083968..bfc3079aca9212d8f231c1e431d6b18a92ccd557 100644 (file)
@@ -247,8 +247,22 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
 
 static void zend_persist_op_array_calc(zval *zv)
 {
-       ADD_ARENA_SIZE(sizeof(zend_op_array));
-       zend_persist_op_array_calc_ex(Z_PTR_P(zv));
+       zend_op_array *op_array = Z_PTR_P(zv);
+
+       if (op_array->type == ZEND_USER_FUNCTION/* &&
+           (!op_array->refcount || *(op_array->refcount) > 1)*/) {
+               zend_op_array *old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
+               if (old_op_array) {
+                       Z_PTR_P(zv) = old_op_array;
+               } else {
+                       ADD_ARENA_SIZE(sizeof(zend_op_array));
+                       zend_persist_op_array_calc_ex(Z_PTR_P(zv));
+                       zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv));
+               }
+       } else {
+               ADD_ARENA_SIZE(sizeof(zend_op_array));
+               zend_persist_op_array_calc_ex(Z_PTR_P(zv));
+       }
 }
 
 static void zend_persist_property_info_calc(zval *zv)