From 8e3643a8fcf9f901d0990937fa332e22607ce0f1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 5 Mar 2015 14:23:48 +0300 Subject: [PATCH] Avoid useless op_array duplication --- ext/opcache/zend_accelerator_util_funcs.c | 12 ++++++++---- ext/opcache/zend_persist.c | 9 +++++++++ ext/opcache/zend_persist_calc.c | 18 ++++++++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index e4430bf0a2..8c89a8d5d6 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -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); + } } } } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index fdba5069f4..43376ed2a9 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -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); diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index d7fbaa272a..bfc3079aca 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -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) -- 2.40.0