Refactor op array loops in JIT (#19335)

Reuse the helper zend_foreach_op_array() that we move to the
zend_optimizer.h header to be usable in opcache.
Note that applying this to other op_array loops is not easy because they either:
- start from EG(persistent_classes_count)
- or only apply to classes
This commit is contained in:
Niels Dossche 2025-07-31 22:10:06 +02:00 committed by GitHub
parent 0afa04a474
commit 15990de89e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 8 additions and 43 deletions

View file

@ -98,6 +98,10 @@ ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass);
ZEND_API void zend_optimizer_unregister_pass(int idx);
zend_result zend_optimizer_startup(void);
zend_result zend_optimizer_shutdown(void);
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
END_EXTERN_C()
#endif

View file

@ -128,7 +128,4 @@ int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zen
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects);
zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
#endif

View file

@ -3928,8 +3928,10 @@ void zend_jit_deactivate(void)
zend_jit_profile_counter = 0;
}
static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array)
static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array, void *context)
{
ZEND_IGNORE_VALUE(context);
zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
if (!func_info) {
@ -3959,49 +3961,11 @@ static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array)
}
#endif
}
if (op_array->num_dynamic_func_defs) {
for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) {
zend_jit_restart_preloaded_op_array(op_array->dynamic_func_defs[i]);
}
}
}
static void zend_jit_restart_preloaded_script(zend_persistent_script *script)
{
zend_class_entry *ce;
zend_op_array *op_array;
zend_jit_restart_preloaded_op_array(&script->script.main_op_array);
ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) {
zend_jit_restart_preloaded_op_array(op_array);
} ZEND_HASH_FOREACH_END();
ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) {
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
if (op_array->type == ZEND_USER_FUNCTION) {
zend_jit_restart_preloaded_op_array(op_array);
}
} ZEND_HASH_FOREACH_END();
if (ce->num_hooked_props > 0) {
zend_property_info *prop;
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
if (prop->hooks) {
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
if (prop->hooks[i]) {
op_array = &prop->hooks[i]->op_array;
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
zend_jit_restart_preloaded_op_array(op_array);
}
}
}
}
} ZEND_HASH_FOREACH_END();
}
} ZEND_HASH_FOREACH_END();
zend_foreach_op_array(&script->script, zend_jit_restart_preloaded_op_array, NULL);
}
void zend_jit_restart(void)