summaryrefslogtreecommitdiff
path: root/ext/opcache/zend_accelerator_util_funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/zend_accelerator_util_funcs.c')
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c453
1 files changed, 201 insertions, 252 deletions
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
index 1b2247f9ce..0ccd882c0b 100644
--- a/ext/opcache/zend_accelerator_util_funcs.c
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Zend OPcache |
+----------------------------------------------------------------------+
- | Copyright (c) 1998-2018 The PHP Group |
+ | Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -34,58 +34,34 @@
# define accel_xlat_get(old) zend_hash_str_find_ptr(&ZCG(bind_hash), (char*)&(old), sizeof(void*))
#endif
+#define IN_ARENA(ptr) \
+ ((void*)(ptr) >= ZCG(current_persistent_script)->arena_mem && \
+ (void*)(ptr) < (void*)((char*)ZCG(current_persistent_script)->arena_mem + ZCG(current_persistent_script)->arena_size))
+
#define ARENA_REALLOC(ptr) \
(void*)(((char*)(ptr)) + ((char*)ZCG(arena_mem) - (char*)ZCG(current_persistent_script)->arena_mem))
typedef int (*id_function_t)(void *, void *);
typedef void (*unique_copy_ctor_func_t)(void *pElement);
-static void zend_accel_destroy_zend_function(zval *zv)
-{
- zend_function *function = Z_PTR_P(zv);
-
- if (function->type == ZEND_USER_FUNCTION) {
- if (function->op_array.static_variables) {
- if (!(GC_FLAGS(function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
- if (GC_DELREF(function->op_array.static_variables) == 0) {
- FREE_HASHTABLE(function->op_array.static_variables);
- }
- }
- function->op_array.static_variables = NULL;
- }
- }
-
- zend_function_dtor(zv);
-}
-
-static void zend_accel_destroy_zend_class(zval *zv)
-{
- zend_class_entry *ce = Z_PTR_P(zv);
- ce->function_table.pDestructor = zend_accel_destroy_zend_function;
- destroy_zend_class(zv);
-}
-
zend_persistent_script* create_persistent_script(void)
{
zend_persistent_script *persistent_script = (zend_persistent_script *) emalloc(sizeof(zend_persistent_script));
memset(persistent_script, 0, sizeof(zend_persistent_script));
- zend_hash_init(&persistent_script->script.function_table, 128, NULL, ZEND_FUNCTION_DTOR, 0);
+ zend_hash_init(&persistent_script->script.function_table, 0, NULL, ZEND_FUNCTION_DTOR, 0);
/* class_table is usually destroyed by free_persistent_script() that
* overrides destructor. ZEND_CLASS_DTOR may be used by standard
* PHP compiler
*/
- zend_hash_init(&persistent_script->script.class_table, 16, NULL, ZEND_CLASS_DTOR, 0);
+ zend_hash_init(&persistent_script->script.class_table, 0, NULL, ZEND_CLASS_DTOR, 0);
return persistent_script;
}
void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
{
- if (destroy_elements) {
- persistent_script->script.function_table.pDestructor = zend_accel_destroy_zend_function;
- persistent_script->script.class_table.pDestructor = zend_accel_destroy_zend_class;
- } else {
+ if (!destroy_elements) {
persistent_script->script.function_table.pDestructor = NULL;
persistent_script->script.class_table.pDestructor = NULL;
}
@@ -100,231 +76,170 @@ void free_persistent_script(zend_persistent_script *persistent_script, int destr
efree(persistent_script);
}
-static int is_not_internal_function(zval *zv)
-{
- zend_function *function = Z_PTR_P(zv);
- return(function->type != ZEND_INTERNAL_FUNCTION);
-}
-
-void zend_accel_free_user_functions(HashTable *ht)
+void zend_accel_move_user_functions(HashTable *src, uint32_t count, zend_script *script)
{
- dtor_func_t orig_dtor = ht->pDestructor;
-
- ht->pDestructor = NULL;
- zend_hash_apply(ht, (apply_func_t) is_not_internal_function);
- ht->pDestructor = orig_dtor;
-}
+ Bucket *p, *end;
+ HashTable *dst;
+ zend_string *filename;
+ dtor_func_t orig_dtor;
+ zend_function *function;
-void zend_accel_move_user_functions(HashTable *src, HashTable *dst)
-{
- Bucket *p;
- dtor_func_t orig_dtor = src->pDestructor;
+ if (!count) {
+ return;
+ }
+ dst = &script->function_table;
+ filename = script->main_op_array.filename;
+ orig_dtor = src->pDestructor;
src->pDestructor = NULL;
- zend_hash_extend(dst, dst->nNumUsed + src->nNumUsed, 0);
- ZEND_HASH_REVERSE_FOREACH_BUCKET(src, p) {
- zend_function *function = Z_PTR(p->val);
-
- if (EXPECTED(function->type == ZEND_USER_FUNCTION)) {
+ zend_hash_extend(dst, count, 0);
+ end = src->arData + src->nNumUsed;
+ p = end - count;
+ for (; p != end; p++) {
+ if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
+ function = Z_PTR(p->val);
+ if (EXPECTED(function->type == ZEND_USER_FUNCTION)
+ && EXPECTED(function->op_array.filename == filename)) {
_zend_hash_append_ptr(dst, p->key, function);
zend_hash_del_bucket(src, p);
- } else {
- break;
}
- } ZEND_HASH_FOREACH_END();
+ }
src->pDestructor = orig_dtor;
}
-void zend_accel_copy_internal_functions(void)
+void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *script)
{
- zend_string *key;
- zval *val;
-
- ZEND_HASH_FOREACH_STR_KEY_VAL(CG(function_table), key, val) {
- zend_internal_function *function = Z_PTR_P(val);
- if (function->type == ZEND_INTERNAL_FUNCTION) {
- zend_hash_add_new_ptr(&ZCG(function_table), key, function);
- }
- } ZEND_HASH_FOREACH_END();
- ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
-}
+ Bucket *p, *end;
+ HashTable *dst;
+ zend_string *filename;
+ dtor_func_t orig_dtor;
+ zend_class_entry *ce;
-static inline void zend_clone_zval(zval *src)
-{
- void *ptr;
+ if (!count) {
+ return;
+ }
- if (Z_TYPE_P(src) == IS_REFERENCE) {
- ptr = accel_xlat_get(Z_REF_P(src));
- if (ptr != NULL) {
- Z_REF_P(src) = ptr;
- return;
- } else {
- zend_reference *old = Z_REF_P(src);
- ZVAL_NEW_REF(src, &old->val);
- Z_REF_P(src)->gc = old->gc;
- accel_xlat_set(old, Z_REF_P(src));
- src = Z_REFVAL_P(src);
+ dst = &script->class_table;
+ filename = script->main_op_array.filename;
+ orig_dtor = src->pDestructor;
+ src->pDestructor = NULL;
+ zend_hash_extend(dst, count, 0);
+ end = src->arData + src->nNumUsed;
+ p = end - count;
+ for (; p != end; p++) {
+ if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
+ ce = Z_PTR(p->val);
+ if (EXPECTED(ce->type == ZEND_USER_CLASS)
+ && EXPECTED(ce->info.user.filename == filename)) {
+ _zend_hash_append_ptr(dst, p->key, ce);
+ zend_hash_del_bucket(src, p);
}
}
+ src->pDestructor = orig_dtor;
}
-static void zend_hash_clone_constants(HashTable *ht, HashTable *source)
+static void zend_hash_clone_constants(HashTable *ht)
{
- Bucket *p, *q, *end;
- zend_ulong nIndex;
+ Bucket *p, *end;
zend_class_constant *c;
- ht->nTableSize = source->nTableSize;
- ht->nTableMask = source->nTableMask;
- ht->nNumUsed = 0;
- ht->nNumOfElements = source->nNumOfElements;
- ht->nNextFreeElement = source->nNextFreeElement;
- ht->pDestructor = NULL;
- HT_FLAGS(ht) = (HT_FLAGS(source) & (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS));
- ht->nInternalPointer = 0;
-
- if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
- ht->arData = source->arData;
+ if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}
- ZEND_ASSERT((HT_FLAGS(source) & HASH_FLAG_PACKED) == 0);
- HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht)));
- HT_HASH_RESET(ht);
+ p = emalloc(HT_SIZE(ht));
+ memcpy(p, HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht));
+ HT_SET_DATA_ADDR(ht, p);
- p = source->arData;
- end = p + source->nNumUsed;
+ p = ht->arData;
+ end = p + ht->nNumUsed;
for (; p != end; p++) {
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
- nIndex = p->h | ht->nTableMask;
-
- /* Insert into hash collision list */
- q = ht->arData + ht->nNumUsed;
- Z_NEXT(q->val) = HT_HASH(ht, nIndex);
- HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(ht->nNumUsed++);
-
- /* Initialize key */
- q->h = p->h;
- q->key = p->key;
+ c = Z_PTR(p->val);
+ if (IN_ARENA(c)) {
+ c = ARENA_REALLOC(c);
+ Z_PTR(p->val) = c;
- /* Copy data */
- c = ARENA_REALLOC(Z_PTR(p->val));
- ZVAL_PTR(&q->val, c);
-
- zend_clone_zval(&c->value);
- if ((void*)c->ce >= ZCG(current_persistent_script)->arena_mem &&
- (void*)c->ce < (void*)((char*)ZCG(current_persistent_script)->arena_mem + ZCG(current_persistent_script)->arena_size)) {
- c->ce = ARENA_REALLOC(c->ce);
+ if (IN_ARENA(c->ce)) {
+ c->ce = ARENA_REALLOC(c->ce);
+ }
}
}
}
-static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce)
+static void zend_hash_clone_methods(HashTable *ht)
{
- Bucket *p, *q, *end;
- zend_ulong nIndex;
+ Bucket *p, *end;
zend_op_array *new_entry;
- ht->nTableSize = source->nTableSize;
- ht->nTableMask = source->nTableMask;
- ht->nNumUsed = 0;
- ht->nNumOfElements = source->nNumOfElements;
- ht->nNextFreeElement = source->nNextFreeElement;
ht->pDestructor = ZEND_FUNCTION_DTOR;
- HT_FLAGS(ht) = (HT_FLAGS(source) & (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS));
- ht->nInternalPointer = 0;
- if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
- ht->arData = source->arData;
+ if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}
- ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_PACKED));
- HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht)));
- HT_HASH_RESET(ht);
+ p = emalloc(HT_SIZE(ht));
+ memcpy(p, HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht));
+ HT_SET_DATA_ADDR(ht, p);
- p = source->arData;
- end = p + source->nNumUsed;
+ p = ht->arData;
+ end = p + ht->nNumUsed;
for (; p != end; p++) {
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
+ new_entry = Z_PTR(p->val);
+ if (IN_ARENA(new_entry)) {
+ new_entry = ARENA_REALLOC(new_entry);
+ Z_PTR(p->val) = new_entry;
- nIndex = p->h | ht->nTableMask;
-
- /* Insert into hash collision list */
- q = ht->arData + ht->nNumUsed;
- Z_NEXT(q->val) = HT_HASH(ht, nIndex);
- HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(ht->nNumUsed++);
-
- /* Initialize key */
- q->h = p->h;
- ZEND_ASSERT(p->key != NULL);
- q->key = p->key;
-
- /* Copy data */
- ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val)));
- new_entry = (zend_op_array*)Z_PTR(q->val);
+ if (IN_ARENA(new_entry->scope)) {
+ 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)) {
-
- new_entry->scope = ARENA_REALLOC(new_entry->scope);
-
- /* update prototype */
- if (new_entry->prototype) {
- new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
+ /* update prototype */
+ if (IN_ARENA(new_entry->prototype)) {
+ new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
+ }
}
+ if (IN_ARENA(ZEND_MAP_PTR(new_entry->run_time_cache))) {
+ ZEND_MAP_PTR_INIT(new_entry->run_time_cache, ARENA_REALLOC(ZEND_MAP_PTR(new_entry->run_time_cache)));
+ }
+ ZEND_MAP_PTR_INIT(new_entry->static_variables_ptr, &new_entry->static_variables);
}
}
}
-static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce)
+static void zend_hash_clone_prop_info(HashTable *ht)
{
- Bucket *p, *q, *end;
- zend_ulong nIndex;
+ Bucket *p, *end;
zend_property_info *prop_info;
- ht->nTableSize = source->nTableSize;
- ht->nTableMask = source->nTableMask;
- ht->nNumUsed = 0;
- ht->nNumOfElements = source->nNumOfElements;
- ht->nNextFreeElement = source->nNextFreeElement;
- ht->pDestructor = NULL;
- HT_FLAGS(ht) = (HT_FLAGS(source) & (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS));
- ht->nInternalPointer = 0;
-
- if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
- ht->arData = source->arData;
+ if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}
- ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_PACKED));
- HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht)));
- HT_HASH_RESET(ht);
+ p = emalloc(HT_SIZE(ht));
+ memcpy(p, HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht));
+ HT_SET_DATA_ADDR(ht, p);
- p = source->arData;
- end = p + source->nNumUsed;
+ p = ht->arData;
+ end = p + ht->nNumUsed;
for (; p != end; p++) {
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
+ prop_info = Z_PTR(p->val);
+ if (IN_ARENA(prop_info)) {
+ prop_info = ARENA_REALLOC(prop_info);
+ Z_PTR(p->val) = prop_info;
- nIndex = p->h | ht->nTableMask;
-
- /* Insert into hash collision list */
- q = ht->arData + ht->nNumUsed;
- Z_NEXT(q->val) = HT_HASH(ht, nIndex);
- HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(ht->nNumUsed++);
-
- /* Initialize key */
- q->h = p->h;
- ZEND_ASSERT(p->key != NULL);
- q->key = p->key;
-
- /* Copy data */
- prop_info = ARENA_REALLOC(Z_PTR(p->val));
- ZVAL_PTR(&q->val, prop_info);
+ if (IN_ARENA(prop_info->ce)) {
+ prop_info->ce = ARENA_REALLOC(prop_info->ce);
+ }
- if ((void*)prop_info->ce >= ZCG(current_persistent_script)->arena_mem &&
- (void*)prop_info->ce < (void*)((char*)ZCG(current_persistent_script)->arena_mem + ZCG(current_persistent_script)->arena_size)) {
- prop_info->ce = ARENA_REALLOC(prop_info->ce);
+ if (ZEND_TYPE_IS_CE(prop_info->type)) {
+ zend_class_entry *ce = ZEND_TYPE_CE(prop_info->type);
+ if (IN_ARENA(ce)) {
+ ce = ARENA_REALLOC(ce);
+ prop_info->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
+ }
+ }
}
}
}
@@ -340,70 +255,93 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
static void zend_class_copy_ctor(zend_class_entry **pce)
{
zend_class_entry *ce = *pce;
- zend_class_entry *old_ce = ce;
zval *src, *dst, *end;
- *pce = ce = ARENA_REALLOC(old_ce);
+ *pce = ce = ARENA_REALLOC(ce);
ce->refcount = 1;
- if (ce->parent) {
+ if ((ce->ce_flags & ZEND_ACC_LINKED) && IN_ARENA(ce->parent)) {
ce->parent = ARENA_REALLOC(ce->parent);
}
- if (old_ce->default_properties_table) {
- ce->default_properties_table = emalloc(sizeof(zval) * old_ce->default_properties_count);
- src = old_ce->default_properties_table;
- end = src + old_ce->default_properties_count;
- dst = ce->default_properties_table;
+ if (ce->default_properties_table) {
+ dst = emalloc(sizeof(zval) * ce->default_properties_count);
+ src = ce->default_properties_table;
+ end = src + ce->default_properties_count;
+ ce->default_properties_table = dst;
for (; src != end; src++, dst++) {
ZVAL_COPY_VALUE(dst, src);
- zend_clone_zval(dst);
}
}
- zend_hash_clone_methods(&ce->function_table, &old_ce->function_table, old_ce, ce);
+ zend_hash_clone_methods(&ce->function_table);
/* static members */
- if (old_ce->default_static_members_table) {
+ if (ce->default_static_members_table) {
int i, end;
- zend_class_entry *parent = ce->parent;
+ zend_class_entry *parent = !(ce->ce_flags & ZEND_ACC_LINKED) ? NULL : ce->parent;
- ce->default_static_members_table = emalloc(sizeof(zval) * old_ce->default_static_members_count);
+ dst = emalloc(sizeof(zval) * ce->default_static_members_count);
+ src = ce->default_static_members_table;
+ ce->default_static_members_table = dst;
i = ce->default_static_members_count - 1;
/* Copy static properties in this class */
end = parent ? parent->default_static_members_count : 0;
for (; i >= end; i--) {
- zval *p = &ce->default_static_members_table[i];
- ZVAL_COPY_VALUE(p, &old_ce->default_static_members_table[i]);
- zend_clone_zval(p);
+ zval *p = &dst[i];
+ ZVAL_COPY_VALUE(p, &src[i]);
}
/* Create indirections to static properties from parent classes */
while (parent && parent->default_static_members_table) {
end = parent->parent ? parent->parent->default_static_members_count : 0;
for (; i >= end; i--) {
- zval *p = &ce->default_static_members_table[i];
+ zval *p = &dst[i];
ZVAL_INDIRECT(p, &parent->default_static_members_table[i]);
}
parent = parent->parent;
}
}
- ce->static_members_table = ce->default_static_members_table;
+ ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
/* properties_info */
- zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce);
+ zend_hash_clone_prop_info(&ce->properties_info);
/* constants table */
- zend_hash_clone_constants(&ce->constants_table, &old_ce->constants_table);
+ zend_hash_clone_constants(&ce->constants_table);
+
+ if (ce->properties_info_table) {
+ int i;
+ ce->properties_info_table = ARENA_REALLOC(ce->properties_info_table);
+ for (i = 0; i < ce->default_properties_count; i++) {
+ if (IN_ARENA(ce->properties_info_table[i])) {
+ ce->properties_info_table[i] = ARENA_REALLOC(ce->properties_info_table[i]);
+ }
+ }
+ }
- /* interfaces aren't really implemented, so we create a new table */
if (ce->num_interfaces) {
- ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces);
- memset(ce->interfaces, 0, sizeof(zend_class_entry *) * ce->num_interfaces);
- } else {
- ce->interfaces = NULL;
+ zend_class_name *interface_names;
+
+ if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
+ interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
+ memcpy(interface_names, ce->interface_names, sizeof(zend_class_name) * ce->num_interfaces);
+ ce->interface_names = interface_names;
+ } else {
+ zend_class_entry **interfaces = emalloc(sizeof(zend_class_entry*) * ce->num_interfaces);
+ uint32_t i;
+
+ for (i = 0; i < ce->num_interfaces; i++) {
+ if (IN_ARENA(ce->interfaces[i])) {
+ interfaces[i] = ARENA_REALLOC(ce->interfaces[i]);
+ } else {
+ interfaces[i] = ce->interfaces[i];
+ }
+ }
+ ce->interfaces = interfaces;
+ }
}
zend_update_inherited_handler(constructor);
@@ -425,40 +363,47 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
zend_update_inherited_handler(__debugInfo);
/* 5.4 traits */
- if (ce->trait_aliases) {
- zend_trait_alias **trait_aliases;
- int i = 0;
+ if (ce->num_traits) {
+ zend_class_name *trait_names = emalloc(sizeof(zend_class_name) * ce->num_traits);
- while (ce->trait_aliases[i]) {
- i++;
- }
- trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
- i = 0;
- while (ce->trait_aliases[i]) {
- trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
- memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
- i++;
- }
- trait_aliases[i] = NULL;
- ce->trait_aliases = trait_aliases;
- }
+ memcpy(trait_names, ce->trait_names, sizeof(zend_class_name) * ce->num_traits);
+ ce->trait_names = trait_names;
- if (ce->trait_precedences) {
- zend_trait_precedence **trait_precedences;
- int i = 0;
+ if (ce->trait_aliases) {
+ zend_trait_alias **trait_aliases;
+ int i = 0;
- while (ce->trait_precedences[i]) {
- i++;
+ while (ce->trait_aliases[i]) {
+ i++;
+ }
+ trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
+ i = 0;
+ while (ce->trait_aliases[i]) {
+ trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
+ memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
+ i++;
+ }
+ trait_aliases[i] = NULL;
+ ce->trait_aliases = trait_aliases;
}
- trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
- i = 0;
- while (ce->trait_precedences[i]) {
- trait_precedences[i] = emalloc(sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
- memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
- i++;
+
+ if (ce->trait_precedences) {
+ zend_trait_precedence **trait_precedences;
+ int i = 0;
+
+ while (ce->trait_precedences[i]) {
+ i++;
+ }
+ trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
+ i = 0;
+ while (ce->trait_precedences[i]) {
+ trait_precedences[i] = emalloc(sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
+ memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
+ i++;
+ }
+ trait_precedences[i] = NULL;
+ ce->trait_precedences = trait_precedences;
}
- trait_precedences[i] = NULL;
- ce->trait_precedences = trait_precedences;
}
}
@@ -618,7 +563,9 @@ static void zend_accel_class_hash_copy_from_shm(HashTable *target, HashTable *so
}
} else {
t = _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1);
- zend_class_copy_ctor((zend_class_entry**)&Z_PTR_P(t));
+ if (!(((zend_class_entry*)Z_PTR_P(t))->ce_flags & ZEND_ACC_IMMUTABLE)) {
+ zend_class_copy_ctor((zend_class_entry**)&Z_PTR_P(t));
+ }
}
}
target->nInternalPointer = 0;
@@ -779,6 +726,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
*op_array = persistent_script->script.main_op_array;
+ ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
if (EXPECTED(from_shared_memory)) {
zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);
@@ -823,6 +771,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
zend_hash_destroy(&ZCG(bind_hash));
ZCG(current_persistent_script) = NULL;
+ zend_map_ptr_extend(ZCSG(map_ptr_last));
} else /* if (!from_shared_memory) */ {
if (zend_hash_num_elements(&persistent_script->script.function_table) > 0) {
zend_accel_function_hash_copy(CG(function_table), &persistent_script->script.function_table);