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;
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);
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);
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) {
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)++;
}
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;
}
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);
efree(op_array->run_time_cache);
}
- if (--(*op_array->refcount)>0) {
+ if (!op_array->refcount || --(*op_array->refcount)>0) {
return;
}
#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))
}
}
-/* 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;
/* 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 {
}
}
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;
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) {
return;
}
- if (--(*op_array->refcount) == 0) {
+ if (op_array->refcount && --(*op_array->refcount) == 0) {
efree(op_array->refcount);
}
op_array->refcount = NULL;