]> granicus.if.org Git - php/commitdiff
don't count op_arrays stored in opcache SHM
authorDmitry Stogov <dmitry@zend.com>
Fri, 20 Feb 2015 11:59:30 +0000 (14:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 20 Feb 2015 11:59:30 +0000 (14:59 +0300)
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_closures.c
Zend/zend_compile.c
Zend/zend_generators.c
Zend/zend_opcode.c
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c

index fe6ae338027224576f5537f9c4fbe43bf77865b2..693a8340f8ccce25f59c4485b60a46ee0a574d7f 100644 (file)
@@ -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;
index da90e4c98d94b477d901f02bde661bcf5208c7ca..035a4c6c88604d6ddecd02553f0870a60c2a911e 100644 (file)
@@ -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);
index fb37bf2705a480ed4c0e4adddedcfb9c34173763..967cb6acc62004f9befac0f02d6b85b09193d7db 100644 (file)
@@ -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) {
index 67b61831598e2f6d4e2c689315ffdb9997f3d2be..2608cf150a438bd44ce59fd3396871e5febf9882 100644 (file)
@@ -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;
        }
index 971d4e7bc8c6ce91cdab8cb6e2cf5d14a18b14f5..a8c589964b5a1874965f81518b0542fc7773c711 100644 (file)
@@ -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);
index 999ee659571a59e7e595f38cfd9144b38b838b0b..9e79697589c33d288bb77827a7617b1d5469f4bc 100644 (file)
@@ -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;
        }
 
index f3c68246679b07bbacd809e602c9c7ec9f8857e9..afe3c4e421adc081128e5d63a5d7beb088112a5b 100644 (file)
 #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) {
index 634dbda4f54e5b0d34f9798c528d3cdab9ba37cf..5fb5ab2d36d5a09aa19e6420c17ffdbf5e65b377 100644 (file)
@@ -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;