From: Dmitry Stogov Date: Fri, 20 Feb 2015 11:59:30 +0000 (+0300) Subject: don't count op_arrays stored in opcache SHM X-Git-Tag: PRE_PHP7_EREG_MYSQL_REMOVALS~106 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f76eed14e7981a5e4361364dd0fdd2bf9d531a8;p=php don't count op_arrays stored in opcache SHM --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index fe6ae33802..693a8340f8 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3915,7 +3915,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi zend_string *name; if (f->common.type != ZEND_USER_FUNCTION || - *(f->op_array.refcount) < 2 || + (f->op_array.refcount && *(f->op_array.refcount) < 2) || !f->common.scope || !f->common.scope->trait_aliases) { return f->common.function_name; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index da90e4c98d..035a4c6c88 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1227,7 +1227,7 @@ ZEND_FUNCTION(get_class_methods) zend_binary_strcasecmp(key->val, key->len, mptr->common.function_name->val, len) == 0) { if (mptr->type == ZEND_USER_FUNCTION && - *mptr->op_array.refcount > 1 && + (!mptr->op_array.refcount || *mptr->op_array.refcount > 1) && !same_name(key, mptr->common.function_name)) { ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key)); zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); @@ -1936,7 +1936,9 @@ ZEND_FUNCTION(create_function) zend_error(E_ERROR, "Unexpected inconsistency in create_function()"); RETURN_FALSE; } - (*func->refcount)++; + if (func->refcount) { + (*func->refcount)++; + } static_variables = func->static_variables; func->static_variables = NULL; zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index fb37bf2705..967cb6acc6 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -499,7 +499,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables); } closure->func.op_array.run_time_cache = NULL; - (*closure->func.op_array.refcount)++; + if (closure->func.op_array.refcount) { + (*closure->func.op_array.refcount)++; + } } else { /* verify that we aren't binding internal function to a wrong scope */ if(func->common.scope != NULL) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 67b6183159..2608cf150a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -863,7 +863,9 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ if (function->type == ZEND_USER_FUNCTION) { zend_op_array *op_array = &function->op_array; - (*op_array->refcount)++; + if (op_array->refcount) { + (*op_array->refcount)++; + } if (op_array->static_variables) { if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { GC_REFCOUNT(op_array->static_variables)++; @@ -910,7 +912,9 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli } return FAILURE; } else { - (*function->op_array.refcount)++; + if (function->op_array.refcount) { + (*function->op_array.refcount)++; + } function->op_array.static_variables = NULL; /* NULL out the unbound function */ return SUCCESS; } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 971d4e7bc8..a8c589964b 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -236,7 +236,9 @@ ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array)); *op_array_copy = *op_array; - (*op_array->refcount)++; + if (op_array->refcount) { + (*op_array->refcount)++; + } op_array->run_time_cache = NULL; if (op_array->static_variables) { ALLOC_HASHTABLE(op_array_copy->static_variables); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 999ee65957..9e79697589 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -330,7 +330,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) efree(op_array->run_time_cache); } - if (--(*op_array->refcount)>0) { + if (!op_array->refcount || --(*op_array->refcount)>0) { return; } diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index f3c6824667..afe3c4e421 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -25,10 +25,6 @@ #include "zend_persist.h" #include "zend_shared_alloc.h" -#define ZEND_PROTECTED_REFCOUNT (1<<30) - -static uint32_t zend_accel_refcount = ZEND_PROTECTED_REFCOUNT; - #if SIZEOF_SIZE_T <= SIZEOF_ZEND_LONG /* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */ # define accel_xlat_set(old, new) zend_hash_index_update_ptr(&ZCG(bind_hash), (zend_ulong)(zend_uintptr_t)(old), (new)) @@ -369,14 +365,6 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) } } -/* protects reference count, creates copy of statics */ -static zend_always_inline void zend_prepare_function_for_execution(zend_op_array *op_array) -{ - /* protect reference count */ - op_array->refcount = &zend_accel_refcount; - (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT; -} - static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce) { uint idx; @@ -429,10 +417,9 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class /* we use refcount to show that op_array is referenced from several places */ if (new_entry->refcount != NULL) { accel_xlat_set(Z_PTR(p->val), new_entry); + new_entry->refcount = NULL; } - zend_prepare_function_for_execution(new_entry); - if (old_ce == new_entry->scope) { new_entry->scope = ce; } else { @@ -765,7 +752,6 @@ static void zend_accel_function_hash_copy_from_shm(HashTable *target, HashTable } } Z_PTR_P(t) = ARENA_REALLOC(Z_PTR(p->val)); - zend_prepare_function_for_execution((zend_op_array*)Z_PTR_P(t)); } target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX; return; @@ -850,8 +836,6 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, zend_accel_function_hash_copy_from_shm(CG(function_table), &persistent_script->function_table); } - zend_prepare_function_for_execution(op_array); - /* Register __COMPILER_HALT_OFFSET__ constant */ if (persistent_script->compiler_halt_offset != 0 && persistent_script->full_path) { diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 634dbda4f5..5fb5ab2d36 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -297,7 +297,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc return; } - if (--(*op_array->refcount) == 0) { + if (op_array->refcount && --(*op_array->refcount) == 0) { efree(op_array->refcount); } op_array->refcount = NULL;