diff options
Diffstat (limited to 'ext/opcache/ZendAccelerator.c')
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 474 |
1 files changed, 348 insertions, 126 deletions
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 088bca6ebf..9819e7acdd 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -118,6 +118,8 @@ bool fallback_process = 0; /* process uses file cache fallback */ #endif static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type); +static zend_class_entry* (*accelerator_orig_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces); +static zend_class_entry* (*accelerator_orig_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies); static zend_result (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle ); static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len); static void (*accelerator_orig_zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message); @@ -2249,6 +2251,269 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return zend_accel_load_script(persistent_script, from_shared_memory); } +static zend_inheritance_cache_entry* zend_accel_inheritance_cache_find(zend_inheritance_cache_entry *entry, zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, bool *needs_autoload_ptr) +{ + uint32_t i; + + ZEND_ASSERT(ce->ce_flags & ZEND_ACC_IMMUTABLE); + ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED)); + + while (entry) { + bool found = 1; + bool needs_autoload = 0; + + if (entry->parent != parent) { + found = 0; + } else { + for (i = 0; i < ce->num_traits + ce->num_interfaces; i++) { + if (entry->traits_and_interfaces[i] != traits_and_interfaces[i]) { + found = 0; + break; + } + } + if (found && entry->dependencies) { + for (i = 0; i < entry->dependencies_count; i++) { + zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); + + if (ce != entry->dependencies[i].ce) { + if (!ce) { + needs_autoload = 1; + } else { + found = 0; + break; + } + } + } + } + } + if (found) { + *needs_autoload_ptr = needs_autoload; + return entry; + } + entry = entry->next; + } + + return NULL; +} + +static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) +{ + uint32_t i; + bool needs_autoload; + zend_inheritance_cache_entry *entry = ce->inheritance_cache; + + while (entry) { + entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); + if (entry) { + if (!needs_autoload) { + zend_map_ptr_extend(ZCSG(map_ptr_last)); + return entry->ce; + } + + for (i = 0; i < entry->dependencies_count; i++) { + zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0); + + if (ce == NULL) { + return NULL; + } + } + } + } + + return NULL; +} + +static bool is_array_cacheable(zval *zv) +{ + zval *p; + + ZEND_HASH_FOREACH_VAL(Z_ARR_P(zv), p) { + if (Z_REFCOUNTED_P(p)) { + if (Z_TYPE_P(p) == IS_ARRAY) { + if (!is_array_cacheable(p)) { + /* Can't cache */ + return 0; + } + } else if (Z_TYPE_P(p) == IS_OBJECT || Z_TYPE_P(p) == IS_RESOURCE || Z_TYPE_P(p) == IS_REFERENCE) { + /* Can't cache */ + return 0; + } + } + } ZEND_HASH_FOREACH_END(); + + return 1; +} + +static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies) +{ + zend_persistent_script dummy; + size_t size; + uint32_t i; + bool needs_autoload; + zend_class_entry *new_ce; + zend_inheritance_cache_entry *entry; + + ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE)); + ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); + + if (!ZCG(accelerator_enabled) || + (ZCSG(restart_in_progress) && accel_restart_is_active())) { + return NULL; + } + + if (traits_and_interfaces && dependencies) { + for (i = 0; i < proto->num_traits + proto->num_interfaces; i++) { + if (traits_and_interfaces[i]) { + zend_hash_del(dependencies, traits_and_interfaces[i]->name); + } + } + } + + if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { + zend_op_array *op_array; + zval *zv; + + ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) { + if (op_array->type == ZEND_USER_FUNCTION + && op_array->static_variables + && !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { + if (UNEXPECTED(GC_REFCOUNT(op_array->static_variables) > 1)) { + GC_DELREF(op_array->static_variables); + op_array->static_variables = zend_array_dup(op_array->static_variables); + } + ZEND_HASH_FOREACH_VAL(op_array->static_variables, zv) { + if (Z_ISREF_P(zv)) { + zend_reference *ref = Z_REF_P(zv); + + ZVAL_COPY_VALUE(zv, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } + } + if (Z_REFCOUNTED_P(zv)) { + if (Z_TYPE_P(zv) == IS_ARRAY) { + if (!is_array_cacheable(zv)) { + /* Can't cache */ + return NULL; + } + SEPARATE_ARRAY(zv); + } else if (Z_TYPE_P(zv) == IS_OBJECT || Z_TYPE_P(zv) == IS_RESOURCE) { + /* Can't cache */ + return NULL; + } + } + } ZEND_HASH_FOREACH_END(); + } + } ZEND_HASH_FOREACH_END(); + } + + SHM_UNPROTECT(); + zend_shared_alloc_lock(); + + entry = ce->inheritance_cache; + while (entry) { + entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); + if (entry) { + if (!needs_autoload) { + zend_shared_alloc_unlock(); + SHM_PROTECT(); + + zend_map_ptr_extend(ZCSG(map_ptr_last)); + return entry->ce; + } + ZEND_ASSERT(0); // entry = entry->next; // This shouldn't be posible ??? + } + } + + zend_shared_alloc_init_xlat_table(); + + memset(&dummy, 0, sizeof(dummy)); + dummy.size = ZEND_ALIGNED_SIZE( + sizeof(zend_inheritance_cache_entry) - + sizeof(void*) + + (sizeof(void*) * (proto->num_traits + proto->num_interfaces))); + if (dependencies) { + dummy.size += ZEND_ALIGNED_SIZE(zend_hash_num_elements(dependencies) * sizeof(zend_class_dependency)); + } + ZCG(current_persistent_script) = &dummy; + zend_persist_class_entry_calc(ce); + size = dummy.size; + + zend_shared_alloc_clear_xlat_table(); + +#if ZEND_MM_ALIGNMENT < 8 + /* Align to 8-byte boundary */ + ZCG(mem) = zend_shared_alloc(size + 8); +#else + ZCG(mem) = zend_shared_alloc(size); +#endif + + if (!ZCG(mem)) { + zend_shared_alloc_destroy_xlat_table(); + zend_shared_alloc_unlock(); + SHM_PROTECT(); + return NULL; + } + +#if ZEND_MM_ALIGNMENT < 8 + /* Align to 8-byte boundary */ + ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 7L) & ~7L); +#endif + + memset(ZCG(mem), 0, size); + entry = (zend_inheritance_cache_entry*)ZCG(mem); + ZCG(mem) = (char*)ZCG(mem) + + ZEND_ALIGNED_SIZE( + (sizeof(zend_inheritance_cache_entry) - + sizeof(void*) + + (sizeof(void*) * (proto->num_traits + proto->num_interfaces)))); + entry->parent = parent; + for (i = 0; i < proto->num_traits + proto->num_interfaces; i++) { + entry->traits_and_interfaces[i] = traits_and_interfaces[i]; + } + if (dependencies && zend_hash_num_elements(dependencies)) { + zend_string *dep_name; + zend_class_entry *dep_ce; + + i = 0; + entry->dependencies_count = zend_hash_num_elements(dependencies); + entry->dependencies = (zend_class_dependency*)ZCG(mem); + ZEND_HASH_FOREACH_STR_KEY_PTR(dependencies, dep_name, dep_ce) { +#if ZEND_DEBUG + ZEND_ASSERT(zend_accel_in_shm(dep_name)); +#endif + entry->dependencies[i].name = dep_name; + entry->dependencies[i].ce = dep_ce; + i++; + } ZEND_HASH_FOREACH_END(); + ZCG(mem) = (char*)ZCG(mem) + zend_hash_num_elements(dependencies) * sizeof(zend_class_dependency); + } + entry->ce = new_ce = zend_persist_class_entry(ce); + zend_update_parent_ce(new_ce); + entry->next = proto->inheritance_cache; + proto->inheritance_cache = entry; + + zend_shared_alloc_destroy_xlat_table(); + + zend_shared_alloc_unlock(); + SHM_PROTECT(); + + /* Consistency check */ + if ((char*)entry + size != (char*)ZCG(mem)) { + zend_accel_error( + ((char*)entry + size < (char*)ZCG(mem)) ? ACCEL_LOG_ERROR : ACCEL_LOG_WARNING, + "Internal error: wrong class size calculation: %s start=" ZEND_ADDR_FMT ", end=" ZEND_ADDR_FMT ", real=" ZEND_ADDR_FMT "\n", + ZSTR_VAL(ce->name), + (size_t)entry, + (size_t)((char *)entry + size), + (size_t)ZCG(mem)); + } + + zend_map_ptr_extend(ZCSG(map_ptr_last)); + + return new_ce; +} + #ifdef ZEND_WIN32 static int accel_gen_uname_id(void) { @@ -3123,7 +3388,19 @@ file_cache_fallback: accel_use_shm_interned_strings(); } - return accel_finish_startup(); + if (accel_finish_startup() != SUCCESS) { + return FAILURE; + } + + if (ZCG(enabled) && accel_startup_ok) { + /* Override inheritance cache callbaks */ + accelerator_orig_inheritance_cache_get = zend_inheritance_cache_get; + accelerator_orig_inheritance_cache_add = zend_inheritance_cache_add; + zend_inheritance_cache_get = zend_accel_inheritance_cache_get; + zend_inheritance_cache_add = zend_accel_inheritance_cache_add; + } + + return SUCCESS; } static void (*orig_post_shutdown_cb)(void); @@ -3170,6 +3447,8 @@ void accel_shutdown(void) } zend_compile_file = accelerator_orig_compile_file; + zend_inheritance_cache_get = accelerator_orig_inheritance_cache_get; + zend_inheritance_cache_add = accelerator_orig_inheritance_cache_add; if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "include_path", sizeof("include_path")-1)) != NULL) { ini_entry->on_modify = orig_include_path_on_modify; @@ -3472,34 +3751,6 @@ try_again: } } -static void get_unresolved_initializer(zend_class_entry *ce, const char **kind, const char **name) { - zend_string *key; - zend_class_constant *c; - zend_property_info *prop; - - *kind = "unknown"; - *name = ""; - - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - if (Z_TYPE(c->value) == IS_CONSTANT_AST) { - *kind = "constant "; - *name = ZSTR_VAL(key); - } - } ZEND_HASH_FOREACH_END(); - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop) { - zval *val; - if (prop->flags & ZEND_ACC_STATIC) { - val = &ce->default_static_members_table[prop->offset]; - } else { - val = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop->offset)]; - } - if (Z_TYPE_P(val) == IS_CONSTANT_AST) { - *kind = (prop->flags & ZEND_ACC_STATIC) ? "static property $" : "property $"; - *name = ZSTR_VAL(key); - } - } ZEND_HASH_FOREACH_END(); -} - static bool preload_needed_types_known(zend_class_entry *ce); static void get_unlinked_dependency(zend_class_entry *ce, const char **kind, const char **name) { zend_class_entry *p; @@ -3515,16 +3766,6 @@ static void get_unlinked_dependency(zend_class_entry *ce, const char **kind, con *name = ZSTR_VAL(ce->parent_name); return; } - if (!(p->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - *kind = "Parent with unresolved initializers "; - *name = ZSTR_VAL(ce->parent_name); - return; - } - if (!(p->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - *kind = "Parent with unresolved property types "; - *name = ZSTR_VAL(ce->parent_name); - return; - } } if (ce->num_interfaces) { @@ -3559,12 +3800,11 @@ static void get_unlinked_dependency(zend_class_entry *ce, const char **kind, con static bool preload_try_resolve_constants(zend_class_entry *ce) { - bool ok, changed; + bool ok, changed, was_changed = 0; zend_class_constant *c; zval *val; EG(exception) = (void*)(uintptr_t)-1; /* prevent error reporting */ - CG(in_compilation) = 1; /* prevent autoloading */ do { ok = 1; changed = 0; @@ -3572,62 +3812,65 @@ static bool preload_try_resolve_constants(zend_class_entry *ce) val = &c->value; if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (EXPECTED(zval_update_constant_ex(val, c->ce) == SUCCESS)) { - changed = 1; + was_changed = changed = 1; } else { ok = 0; } } } ZEND_HASH_FOREACH_END(); + if (ok) { + ce->ce_flags &= ~ZEND_ACC_HAS_AST_CONSTANTS; + } if (ce->default_properties_count) { uint32_t i; + bool resolved = 1; + for (i = 0; i < ce->default_properties_count; i++) { val = &ce->default_properties_table[i]; if (Z_TYPE_P(val) == IS_CONSTANT_AST) { zend_property_info *prop = ce->properties_info_table[i]; if (UNEXPECTED(zval_update_constant_ex(val, prop->ce) != SUCCESS)) { - ok = 0; + resolved = ok = 0; } } } + if (resolved) { + ce->ce_flags &= ~ZEND_ACC_HAS_AST_PROPERTIES; + } } if (ce->default_static_members_count) { uint32_t count = ce->parent ? ce->default_static_members_count - ce->parent->default_static_members_count : ce->default_static_members_count; + bool resolved = 1; val = ce->default_static_members_table + ce->default_static_members_count - 1; while (count) { if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) { - ok = 0; + resolved = ok = 0; } } val--; count--; } + if (resolved) { + ce->ce_flags &= ~ZEND_ACC_HAS_AST_STATICS; + } } } while (changed && !ok); EG(exception) = NULL; CG(in_compilation) = 0; - return ok; + if (ok) { + ce->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED; + } + + return ok || was_changed; } -static zend_class_entry *preload_fetch_resolved_ce(zend_string *name, zend_class_entry *self_ce) { +static zend_class_entry *preload_fetch_resolved_ce(zend_string *name) { zend_string *lcname = zend_string_tolower(name); zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), lcname); zend_string_release(lcname); - if (!ce) { - return NULL; - } - if (ce == self_ce) { - /* Ignore the following requirements if this is the class referring to itself */ - return ce; - } - if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - return NULL; - } - if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - return NULL; - } return ce; } @@ -3641,7 +3884,7 @@ static bool preload_try_resolve_property_types(zend_class_entry *ce) ZEND_TYPE_FOREACH(prop->type, single_type) { if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_class_entry *p = - preload_fetch_resolved_ce(ZEND_TYPE_NAME(*single_type), ce); + preload_fetch_resolved_ce(ZEND_TYPE_NAME(*single_type)); if (!p) { ok = 0; continue; @@ -3650,6 +3893,9 @@ static bool preload_try_resolve_property_types(zend_class_entry *ce) } } ZEND_TYPE_FOREACH_END(); } ZEND_HASH_FOREACH_END(); + if (ok) { + ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED; + } } return ok; @@ -3778,12 +4024,6 @@ static void preload_link(void) parent = zend_hash_find_ptr(EG(class_table), key); zend_string_release(key); if (!parent) continue; - if (!(parent->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - continue; - } - if (!(parent->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - continue; - } } if (ce->num_interfaces) { @@ -3794,10 +4034,6 @@ static void preload_link(void) found = 0; break; } - if (!(p->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - found = 0; - break; - } } if (!found) continue; } @@ -3822,11 +4058,8 @@ static void preload_link(void) continue; } - { - zend_string *key = zend_string_tolower(ce->name); - zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, key); - zend_string_release(key); - } + key = zend_string_tolower(ce->name); + zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, key); if (EXPECTED(zv)) { /* Set filename & lineno information for inheritance errors */ @@ -3842,7 +4075,8 @@ static void preload_link(void) } else { CG(zend_lineno) = ce->info.user.line_start; } - if (zend_do_link_class(ce, NULL) == FAILURE) { + ce = zend_do_link_class(ce, NULL, key); + if (!ce) { ZEND_ASSERT(0 && "Class linking failed?"); } CG(in_compilation) = 0; @@ -3850,22 +4084,41 @@ static void preload_link(void) changed = 1; } + + zend_string_release(key); } - if (ce->ce_flags & ZEND_ACC_LINKED) { - if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if ((ce->ce_flags & ZEND_ACC_TRAIT) /* don't update traits */ - || preload_try_resolve_constants(ce)) { - ce->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED; - changed = 1; - } - } + } ZEND_HASH_FOREACH_END(); + } while (changed); + + /* Resolve property types */ + ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) { + ce = Z_PTR_P(zv); + if (ce->type == ZEND_INTERNAL_CLASS) { + break; + } + if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { + if (!(ce->ce_flags & ZEND_ACC_TRAIT)) { + preload_try_resolve_property_types(ce); + } + } + } ZEND_HASH_FOREACH_END(); + - if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - if ((ce->ce_flags & ZEND_ACC_TRAIT) /* don't update traits */ - || preload_try_resolve_property_types(ce)) { - ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED; + do { + changed = 0; + + ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) { + ce = Z_PTR_P(zv); + if (ce->type == ZEND_INTERNAL_CLASS) { + break; + } + if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (!(ce->ce_flags & ZEND_ACC_TRAIT)) { /* don't update traits */ + CG(in_compilation) = 1; /* prevent autoloading */ + if (preload_try_resolve_constants(ce)) { changed = 1; } + CG(in_compilation) = 0; } } } ZEND_HASH_FOREACH_END(); @@ -3895,18 +4148,6 @@ static void preload_link(void) ZSTR_VAL(ce->name), kind, name); } zend_string_release(key); - } else if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - const char *kind, *name; - get_unresolved_initializer(ce, &kind, &name); - zend_error_at( - E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, - "Can't preload class %s with unresolved initializer for %s%s", - ZSTR_VAL(ce->name), kind, name); - } else if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - zend_error_at( - E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, - "Can't preload class %s with unresolved property types", - ZSTR_VAL(ce->name)); } else { continue; } @@ -3960,7 +4201,7 @@ static inline int preload_update_class_constants(zend_class_entry *ce) { * maybe-uninitialized analysis. */ int result; zend_try { - result = zend_update_class_constants(ce); + result = preload_try_resolve_constants(ce) ? SUCCESS : FAILURE; } zend_catch { result = FAILURE; } zend_end_try(); @@ -3976,13 +4217,6 @@ static zend_class_entry *preload_load_prop_type(zend_property_info *prop, zend_s } else { ce = zend_lookup_class(name); } - if (ce) { - return ce; - } - - zend_error_noreturn(E_ERROR, - "Failed to load class %s used by typed property %s::$%s during preloading", - ZSTR_VAL(name), ZSTR_VAL(prop->ce->name), zend_get_unmangled_property_name(prop->name)); return ce; } @@ -4008,12 +4242,7 @@ static void preload_ensure_classes_loadable() { } if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (preload_update_class_constants(ce) == FAILURE) { - zend_error_noreturn(E_ERROR, - "Failed to resolve initializers of class %s during preloading", - ZSTR_VAL(ce->name)); - } - ZEND_ASSERT(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED); + preload_update_class_constants(ce); } if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { @@ -4025,7 +4254,9 @@ static void preload_ensure_classes_loadable() { if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_class_entry *ce = preload_load_prop_type( prop, ZEND_TYPE_NAME(*single_type)); - ZEND_TYPE_SET_CE(*single_type, ce); + if (ce) { + ZEND_TYPE_SET_CE(*single_type, ce); + } } } ZEND_TYPE_FOREACH_END(); } ZEND_HASH_FOREACH_END(); @@ -4558,15 +4789,8 @@ static int accel_preload(const char *config, bool in_child) ZEND_ASSERT(ce->ce_flags & ZEND_ACC_PRELOADED); if (ce->default_static_members_count) { zend_cleanup_internal_class_data(ce); - if (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) { - int i; - - for (i = 0; i < ce->default_static_members_count; i++) { - if (Z_TYPE(ce->default_static_members_table[i]) == IS_CONSTANT_AST) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - break; - } - } + if (ce->ce_flags & ZEND_ACC_HAS_AST_STATICS) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } } if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { @@ -4701,8 +4925,6 @@ static int accel_preload(const char *config, bool in_child) SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); - ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0); - preload_load(); /* Store individual scripts with unlinked classes */ |