com php-src: Use simple "one-pass" algorithm.: ext/opcache/Opti mizer/zend_call_graph.c
| From: | Dmitry Stogov | Date: | Mon, 17 Oct 2016 21:06:20 +0000 |
| Subject: | com php-src: Use simple "one-pass" algorithm.: ext/opcache/Opti mizer/zend_call_graph.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-95173@lists.php.net to get a copy of this message | ||
Commit: ed3196ea355b568c50bf8047e322d1b5a426b691
Author: Dmitry Stogov <dmitry@zend.com> Tue, 18 Oct 2016 00:06:20 +0300
Parents: faa2a43d4bef944919602f18caf570308528f22b
Branches: PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=ed3196ea355b568c50bf8047e322d1b5a426b691
Log:
Use simple "one-pass" algorithm..
Changed paths:
M ext/opcache/Optimizer/zend_call_graph.c
Diff:
diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c
index 53eb0a8..0df28eb 100644
--- a/ext/opcache/Optimizer/zend_call_graph.c
+++ b/ext/opcache/Optimizer/zend_call_graph.c
@@ -80,64 +80,6 @@ static int zend_foreach_op_array(zend_call_graph *call_graph, zend_script *scrip
return SUCCESS;
}
-static void zend_collect_args_info(zend_call_info *call_info)
-{
- zend_op *opline = call_info->caller_init_opline;
- zend_op *end = call_info->caller_call_opline;
- uint32_t i;
- int num;
- int level = 0;
-
- ZEND_ASSERT(opline && end);
- if (!opline->extended_value) {
- return;
- }
- for (i = 0; i < opline->extended_value; i++) {
- call_info->arg_info[i].opline = NULL;
- }
- while (opline < end) {
- opline++;
- switch (opline->opcode) {
- case ZEND_SEND_VAL:
- case ZEND_SEND_VAR:
- case ZEND_SEND_VAL_EX:
- 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--;
- }
- if (!level) {
- call_info->arg_info[num].opline = opline;
- }
- break;
- case ZEND_SEND_ARRAY:
- case ZEND_SEND_USER:
- case ZEND_SEND_UNPACK:
- // ???
- break;
- case ZEND_INIT_FCALL:
- 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:
- level++;
- break;
- case ZEND_DO_FCALL:
- case ZEND_DO_ICALL:
- case ZEND_DO_UCALL:
- case ZEND_DO_FCALL_BY_NAME:
- level--;
- break;
- }
- }
-}
-
static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags,
zend_op_array *op_array, zend_func_info *func_info)
{
zend_op *opline = op_array->opcodes;
@@ -149,12 +91,13 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t
ALLOCA_FLAG(use_heap);
call_stack = do_alloca((op_array->last / 2) * sizeof(zend_call_info*), use_heap);
+ call_info = NULL;
while (opline != end) {
- call_info = NULL;
switch (opline->opcode) {
case ZEND_INIT_FCALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
+ call_stack[call] = call_info;
func = zend_optimizer_get_called_func(
script, op_array, opline, (build_flags & ZEND_RT_CONSTANTS) != 0);
if (func) {
@@ -174,13 +117,15 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script,
uint32_t
call_info->next_caller = callee_func_info ? callee_func_info->caller_info : NULL;
}
}
- /* break missing intentionally */
+ call++;
+ break;
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_NEW:
case ZEND_INIT_USER_CALL:
call_stack[call] = call_info;
+ call_info = NULL;
call++;
break;
case ZEND_DO_FCALL:
@@ -188,12 +133,33 @@ static int zend_analyze_calls(zend_arena **arena, zend_script *script,
uint32_t
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
func_info->flags |= ZEND_FUNC_HAS_CALLS;
+ if (call_info) {
+ call_info->caller_call_opline = opline;
+ }
call--;
- if (call_stack[call]) {
- call_stack[call]->caller_call_opline = opline;
- zend_collect_args_info(call_stack[call]);
+ call_info = call_stack[call];
+ break;
+ case ZEND_SEND_VAL:
+ case ZEND_SEND_VAR:
+ case ZEND_SEND_VAL_EX:
+ case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_REF:
+ case ZEND_SEND_VAR_NO_REF:
+ case ZEND_SEND_VAR_NO_REF_EX:
+ if (call_info) {
+ uint32_t num = opline->op2.num;
+
+ if (num > 0) {
+ num--;
+ }
+ call_info->arg_info[num].opline = opline;
}
break;
+ case ZEND_SEND_ARRAY:
+ case ZEND_SEND_USER:
+ case ZEND_SEND_UNPACK:
+ /* TODO: set info about var_arg call ??? */
+ break;
}
opline++;
}