summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_call_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/Optimizer/zend_call_graph.c')
-rw-r--r--ext/opcache/Optimizer/zend_call_graph.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c
index 6c1933cfac..53eb0a84ea 100644
--- a/ext/opcache/Optimizer/zend_call_graph.c
+++ b/ext/opcache/Optimizer/zend_call_graph.c
@@ -21,6 +21,8 @@
#include "php.h"
#include "zend_compile.h"
#include "zend_extensions.h"
+#include "Optimizer/zend_optimizer.h"
+#include "zend_optimizer_internal.h"
#include "zend_inference.h"
#include "zend_call_graph.h"
#include "zend_func_info.h"
@@ -102,6 +104,7 @@ static void zend_collect_args_info(zend_call_info *call_info)
case ZEND_SEND_VAR_EX:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
+ case ZEND_SEND_VAR_NO_REF_EX:
num = opline->op2.num;
if (num > 0) {
num--;
@@ -150,39 +153,32 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t
call_info = NULL;
switch (opline->opcode) {
case ZEND_INIT_FCALL:
- if ((func = zend_hash_find_ptr(&script->function_table, Z_STR_P(CRT_CONSTANT(opline->op2)))) != NULL) {
- zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array);
- if (callee_func_info) {
- call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info) + (sizeof(zend_send_arg_info) * ((int)opline->extended_value - 1)));
- call_info->caller_op_array = op_array;
- call_info->caller_init_opline = opline;
- call_info->caller_call_opline = NULL;
- call_info->callee_func = func;
- call_info->num_args = opline->extended_value;
- call_info->next_caller = callee_func_info->caller_info;
- callee_func_info->caller_info = call_info;
- call_info->next_callee = func_info->callee_info;
- func_info->callee_info = call_info;
- }
- } else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(CRT_CONSTANT(opline->op2)))) != NULL &&
- func->type == ZEND_INTERNAL_FUNCTION) {
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ func = zend_optimizer_get_called_func(
+ script, op_array, opline, (build_flags & ZEND_RT_CONSTANTS) != 0);
+ if (func) {
call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info) + (sizeof(zend_send_arg_info) * ((int)opline->extended_value - 1)));
call_info->caller_op_array = op_array;
call_info->caller_init_opline = opline;
call_info->caller_call_opline = NULL;
call_info->callee_func = func;
call_info->num_args = opline->extended_value;
- call_info->next_caller = NULL;
call_info->next_callee = func_info->callee_info;
func_info->callee_info = call_info;
+
+ if (func->type == ZEND_INTERNAL_FUNCTION) {
+ call_info->next_caller = NULL;
+ } else {
+ zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array);
+ call_info->next_caller = callee_func_info ? callee_func_info->caller_info : NULL;
+ }
}
/* break missing intentionally */
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_NEW:
- case ZEND_INIT_METHOD_CALL:
- case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_USER_CALL:
call_stack[call] = call_info;
call++;
@@ -260,6 +256,8 @@ static void zend_analyze_recursion(zend_call_graph *call_graph)
call_info = call_info->next_caller;
}
}
+
+ free_alloca(visited, use_heap);
}
static void zend_sort_op_arrays(zend_call_graph *call_graph)
@@ -277,17 +275,12 @@ int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t buil
if (zend_foreach_op_array(call_graph, script, zend_op_array_calc) != SUCCESS) {
return FAILURE;
}
- call_graph->op_arrays = (zend_op_array**)zend_arena_calloc(arena, call_graph->op_arrays_count, sizeof(zend_op_array*));
+ 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));
- if (!call_graph->op_arrays || !call_graph->func_infos) {
- return FAILURE;
- }
-
call_graph->op_arrays_count = 0;
if (zend_foreach_op_array(call_graph, script, zend_op_array_collect) != SUCCESS) {
return FAILURE;
}
-
for (i = 0; i < call_graph->op_arrays_count; i++) {
zend_analyze_calls(arena, script, build_flags, call_graph->op_arrays[i], call_graph->func_infos + i);
}