summaryrefslogtreecommitdiff
path: root/ext/opcache/ZendAccelerator.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/ZendAccelerator.c')
-rw-r--r--ext/opcache/ZendAccelerator.c474
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 */