]> granicus.if.org Git - php/commitdiff
Extract zend_foreach_op_array()
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 19 May 2020 09:10:19 +0000 (11:10 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 19 May 2020 09:15:54 +0000 (11:15 +0200)
Move this functionality from zend_call_graph into zend_optimizer,
because we use this pattern in a number of places.

ext/opcache/Optimizer/zend_call_graph.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/Optimizer/zend_optimizer_internal.h

index 3b79bc445d53846e1b69e7af949993409ae0bb51..5087527f660e420d9187eb0d7ed3708206d4bf04 100644 (file)
 #include "zend_inference.h"
 #include "zend_call_graph.h"
 
-typedef int (*zend_op_array_func_t)(zend_call_graph *call_graph, zend_op_array *op_array);
-
-static int zend_op_array_calc(zend_call_graph *call_graph, zend_op_array *op_array)
+static void zend_op_array_calc(zend_op_array *op_array, void *context)
 {
-       (void) op_array;
-
+       zend_call_graph *call_graph = context;
        call_graph->op_arrays_count++;
-       return SUCCESS;
 }
 
-static int zend_op_array_collect(zend_call_graph *call_graph, zend_op_array *op_array)
+static void zend_op_array_collect(zend_op_array *op_array, void *context)
 {
+       zend_call_graph *call_graph = context;
     zend_func_info *func_info = call_graph->func_infos + call_graph->op_arrays_count;
 
        ZEND_SET_FUNC_INFO(op_array, func_info);
@@ -47,41 +44,6 @@ static int zend_op_array_collect(zend_call_graph *call_graph, zend_op_array *op_
        func_info->num_args = -1;
        func_info->return_value_used = -1;
        call_graph->op_arrays_count++;
-       return SUCCESS;
-}
-
-static int zend_foreach_op_array(zend_call_graph *call_graph, zend_script *script, zend_op_array_func_t func)
-{
-       zend_class_entry *ce;
-       zend_string *key;
-       zend_op_array *op_array;
-
-       if (func(call_graph, &script->main_op_array) != SUCCESS) {
-               return FAILURE;
-       }
-
-       ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
-               if (func(call_graph, op_array) != SUCCESS) {
-                       return FAILURE;
-               }
-       } ZEND_HASH_FOREACH_END();
-
-       ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) {
-               if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) {
-                       continue;
-               }
-               ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
-                       if (op_array->scope == ce
-                        && op_array->type == ZEND_USER_FUNCTION
-                        && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
-                               if (func(call_graph, op_array) != SUCCESS) {
-                                       return FAILURE;
-                               }
-                       }
-               } ZEND_HASH_FOREACH_END();
-       } ZEND_HASH_FOREACH_END();
-
-       return SUCCESS;
 }
 
 int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info)
@@ -259,15 +221,12 @@ static void zend_sort_op_arrays(zend_call_graph *call_graph)
 int zend_build_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph) /* {{{ */
 {
        call_graph->op_arrays_count = 0;
-       if (zend_foreach_op_array(call_graph, script, zend_op_array_calc) != SUCCESS) {
-               return FAILURE;
-       }
+       zend_foreach_op_array(script, zend_op_array_calc, call_graph);
+
        call_graph->op_arrays = (zend_op_array**)zend_arena_calloc(arena, call_graph->op_arrays_count, sizeof(zend_op_array*));
        call_graph->func_infos = (zend_func_info*)zend_arena_calloc(arena, call_graph->op_arrays_count, sizeof(zend_func_info));
        call_graph->op_arrays_count = 0;
-       if (zend_foreach_op_array(call_graph, script, zend_op_array_collect) != SUCCESS) {
-               return FAILURE;
-       }
+       zend_foreach_op_array(script, zend_op_array_collect, call_graph);
 
        return SUCCESS;
 }
index 061f79d1b3b5f796002ed047d5a7dacf5cc27ddd..2e75ae1fd359b4e2ef252177ca751882f74d3777 100644 (file)
@@ -1333,6 +1333,44 @@ static zend_bool needs_live_range(zend_op_array *op_array, zend_op *def_opline)
        return 1;
 }
 
+void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context)
+{
+       zend_class_entry *ce;
+       zend_string *key;
+       zend_op_array *op_array;
+
+       func(&script->main_op_array, context);
+
+       ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
+               func(op_array, context);
+       } ZEND_HASH_FOREACH_END();
+
+       ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) {
+               if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) {
+                       continue;
+               }
+               ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
+                       if (op_array->scope == ce
+                                       && op_array->type == ZEND_USER_FUNCTION
+                                       && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+                               func(op_array, context);
+                       }
+               } ZEND_HASH_FOREACH_END();
+       } ZEND_HASH_FOREACH_END();
+}
+
+static void step_optimize_op_array(zend_op_array *op_array, void *context) {
+       zend_optimize_op_array(op_array, (zend_optimizer_ctx *) context);
+}
+
+static void step_adjust_fcall_stack_size(zend_op_array *op_array, void *context) {
+       zend_adjust_fcall_stack_size(op_array, (zend_optimizer_ctx *) context);
+}
+
+static void step_dump_after_optimizer(zend_op_array *op_array, void *context) {
+       zend_dump_op_array(op_array, ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
+}
+
 int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
 {
        zend_class_entry *ce;
@@ -1441,44 +1479,10 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
                        ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
                }
        } else {
-               zend_optimize_op_array(&script->main_op_array, &ctx);
-
-               ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
-                       zend_optimize_op_array(op_array, &ctx);
-               } ZEND_HASH_FOREACH_END();
-
-               ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) {
-                       if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) {
-                               continue;
-                       }
-                       ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) {
-                               if (op_array->scope == ce
-                                && op_array->type == ZEND_USER_FUNCTION
-                                && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
-                                       zend_optimize_op_array(op_array, &ctx);
-                               }
-                       } ZEND_HASH_FOREACH_END();
-               } ZEND_HASH_FOREACH_END();
+               zend_foreach_op_array(script, step_optimize_op_array, &ctx);
 
                if (ZEND_OPTIMIZER_PASS_12 & optimization_level) {
-                       zend_adjust_fcall_stack_size(&script->main_op_array, &ctx);
-
-                       ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
-                               zend_adjust_fcall_stack_size(op_array, &ctx);
-                       } ZEND_HASH_FOREACH_END();
-
-                       ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) {
-                               if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) {
-                                       continue;
-                               }
-                               ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) {
-                                       if (op_array->scope == ce
-                                        && op_array->type == ZEND_USER_FUNCTION
-                                        && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
-                                               zend_adjust_fcall_stack_size(op_array, &ctx);
-                                       }
-                               } ZEND_HASH_FOREACH_END();
-                       } ZEND_HASH_FOREACH_END();
+                       zend_foreach_op_array(script, step_adjust_fcall_stack_size, &ctx);
                }
        }
 
@@ -1507,25 +1511,8 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
        } ZEND_HASH_FOREACH_END();
 
        if ((debug_level & ZEND_DUMP_AFTER_OPTIMIZER) &&
-           (ZEND_OPTIMIZER_PASS_7 & optimization_level)) {
-               zend_dump_op_array(&script->main_op_array,
-                       ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
-
-               ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
-                       zend_dump_op_array(op_array,
-                               ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
-               } ZEND_HASH_FOREACH_END();
-
-               ZEND_HASH_FOREACH_PTR(&script->class_table, ce) {
-                       ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) {
-                               if (op_array->scope == ce
-                                && op_array->type == ZEND_USER_FUNCTION
-                                && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
-                                       zend_dump_op_array(op_array,
-                                               ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
-                               }
-                       } ZEND_HASH_FOREACH_END();
-               } ZEND_HASH_FOREACH_END();
+                       (ZEND_OPTIMIZER_PASS_7 & optimization_level)) {
+               zend_foreach_op_array(script, step_dump_after_optimizer, NULL);
        }
 
        if (ctx.constants) {
index a525b668bfd0ec2ae4883d050d77962f6431478f..0c8c2fe4c739951c255742ae45e842f905e2b063 100644 (file)
@@ -117,4 +117,7 @@ int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_arrya, zen
 int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reorder_dtor_effects);
 int 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