diff options
-rw-r--r-- | ext/opcache/Optimizer/dfa_pass.c | 9 | ||||
-rw-r--r-- | ext/opcache/Optimizer/sccp.c | 3 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_call_graph.c | 8 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 2 |
4 files changed, 16 insertions, 6 deletions
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 3474649e3e..033f2df2c0 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -267,8 +267,10 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op while (call_info) { call_info->caller_init_opline -= shiftlist[call_info->caller_init_opline - op_array->opcodes]; - call_info->caller_call_opline -= - shiftlist[call_info->caller_call_opline - op_array->opcodes]; + if (call_info->caller_call_opline) { + call_info->caller_call_opline -= + shiftlist[call_info->caller_call_opline - op_array->opcodes]; + } call_info = call_info->next_callee; } } @@ -367,7 +369,8 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) zend_call_info *call_info = func_info->callee_info; do { - if (call_info->caller_call_opline->opcode == ZEND_DO_ICALL + if (call_info->caller_call_opline + && call_info->caller_call_opline->opcode == ZEND_DO_ICALL && call_info->callee_func && ZSTR_LEN(call_info->callee_func->common.function_name) == sizeof("in_array")-1 && memcmp(ZSTR_VAL(call_info->callee_func->common.function_name), "in_array", sizeof("in_array")-1) == 0 diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index fd83424f09..60ddd9f508 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1277,7 +1277,8 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o } call = ctx->call_map[opline - ctx->scdf.op_array->opcodes]; - if (IS_TOP(op1) || !call || call->caller_call_opline->opcode != ZEND_DO_ICALL) { + if (IS_TOP(op1) || !call || !call->caller_call_opline + || call->caller_call_opline->opcode != ZEND_DO_ICALL) { return; } diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c index 6bfbfc049d..51b307bf5e 100644 --- a/ext/opcache/Optimizer/zend_call_graph.c +++ b/ext/opcache/Optimizer/zend_call_graph.c @@ -177,6 +177,10 @@ int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_f call_info->num_args = -1; } break; + case ZEND_EXIT: + /* In this case the DO_CALL opcode may have been dropped + * and caller_call_opline will be NULL. */ + break; } opline++; } @@ -291,7 +295,9 @@ zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, c for (call = info->callee_info; call; call = call->next_callee) { int i; map[call->caller_init_opline - op_array->opcodes] = call; - map[call->caller_call_opline - op_array->opcodes] = call; + if (call->caller_call_opline) { + map[call->caller_call_opline - op_array->opcodes] = call; + } for (i = 0; i < call->num_args; i++) { if (call->arg_info[i].opline) { map[call->arg_info[i].opline - op_array->opcodes] = call; diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index cb02e58673..0c22f9b384 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -4207,7 +4207,7 @@ void zend_inference_check_recursive_dependencies(zend_op_array *op_array) memset(worklist, 0, sizeof(zend_ulong) * worklist_len); call_info = info->callee_info; while (call_info) { - if (call_info->recursive && + if (call_info->recursive && call_info->caller_call_opline && info->ssa.ops[call_info->caller_call_opline - op_array->opcodes].result_def >= 0) { zend_bitset_incl(worklist, info->ssa.ops[call_info->caller_call_opline - op_array->opcodes].result_def); } |