Skip to content

Commit

Permalink
Don't force property type resolution for include preloading
Browse files Browse the repository at this point in the history
Having all property types resolved is no longer a hard requirement
for preloading, resolving the types is just an optimization. As
such, drop the special logic that forced loading of property
types when include-based preloading is used. Instead only keep
the code that resolves types based on actually preloaded classes.

Also drop the ZEND_ACC_PROPERTY_TYPES_RESOLVED flag, which is now
nearly useless and takes up flag space...
  • Loading branch information
nikic committed Jul 27, 2021
1 parent 56ef117 commit 70195c3
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 52 deletions.
1 change: 0 additions & 1 deletion Zend/zend.c
Expand Up @@ -1050,7 +1050,6 @@ static void zend_resolve_property_types(void) /* {{{ */
} ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
} ZEND_HASH_FOREACH_END();
}
/* }}} */
Expand Down
5 changes: 1 addition & 4 deletions Zend/zend_compile.h
Expand Up @@ -241,7 +241,7 @@ typedef struct _zend_oparray_context {
/* or IS_CONSTANT_VISITED_MARK | | | */
#define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */
/* | | | */
/* Class Flags (unused: 30...) | | | */
/* Class Flags (unused: 15,30,31) | | | */
/* =========== | | | */
/* | | | */
/* Special class types | | | */
Expand Down Expand Up @@ -270,9 +270,6 @@ typedef struct _zend_oparray_context {
/* User class has methods with static variables | | | */
#define ZEND_HAS_STATIC_IN_METHODS (1 << 14) /* X | | | */
/* | | | */
/* Whether all property types are resolved to CEs | | | */
#define ZEND_ACC_PROPERTY_TYPES_RESOLVED (1 << 15) /* X | | | */
/* | | | */
/* Children must reuse parent get_iterator() | | | */
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 16) /* X | | | */
/* | | | */
Expand Down
51 changes: 5 additions & 46 deletions ext/opcache/ZendAccelerator.c
Expand Up @@ -3787,9 +3787,8 @@ static zend_class_entry *preload_fetch_resolved_ce(zend_string *name) {
return ce;
}

static bool preload_try_resolve_property_types(zend_class_entry *ce)
static void preload_try_resolve_property_types(zend_class_entry *ce)
{
bool ok = 1;
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_property_info *prop;
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
Expand All @@ -3798,20 +3797,13 @@ static bool preload_try_resolve_property_types(zend_class_entry *ce)
if (ZEND_TYPE_HAS_NAME(*single_type)) {
zend_class_entry *p =
preload_fetch_resolved_ce(ZEND_TYPE_NAME(*single_type));
if (!p) {
ok = 0;
continue;
if (p) {
ZEND_TYPE_SET_CE(*single_type, p);
}
ZEND_TYPE_SET_CE(*single_type, p);
}
} ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
if (ok) {
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
}
}

return ok;
}

static bool preload_is_class_type_known(zend_class_entry *ce, zend_string *name) {
Expand Down Expand Up @@ -4009,10 +4001,8 @@ static void preload_link(void)
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);
}
if (!(ce->ce_flags & ZEND_ACC_TRAIT)) {
preload_try_resolve_property_types(ce);
}
} ZEND_HASH_FOREACH_END();

Expand Down Expand Up @@ -4156,18 +4146,6 @@ static inline int preload_update_class_constants(zend_class_entry *ce) {
return result;
}

static zend_class_entry *preload_load_prop_type(zend_property_info *prop, zend_string *name) {
zend_class_entry *ce;
if (zend_string_equals_literal_ci(name, "self")) {
ce = prop->ce;
} else if (zend_string_equals_literal_ci(name, "parent")) {
ce = prop->ce->parent;
} else {
ce = zend_lookup_class(name);
}
return ce;
}

static void preload_ensure_classes_loadable(void) {
/* Run this in a loop, because additional classes may be loaded while updating constants etc. */
uint32_t checked_classes_idx = 0;
Expand All @@ -4192,25 +4170,6 @@ static void preload_ensure_classes_loadable(void) {
if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
preload_update_class_constants(ce);
}

if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) {
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_property_info *prop;
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
zend_type *single_type;
ZEND_TYPE_FOREACH(prop->type, single_type) {
if (ZEND_TYPE_HAS_NAME(*single_type)) {
zend_class_entry *ce = preload_load_prop_type(
prop, ZEND_TYPE_NAME(*single_type));
if (ce) {
ZEND_TYPE_SET_CE(*single_type, ce);
}
}
} ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
}
} ZEND_HASH_FOREACH_END();
checked_classes_idx = num_classes;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/tests/preload_loadable_classes_1.phpt
Expand Up @@ -20,4 +20,4 @@ var_dump(class_exists('Foo'));
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(false)

0 comments on commit 70195c3

Please sign in to comment.