summaryrefslogtreecommitdiff
path: root/ext/opcache
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-02-05 19:40:06 +0300
committerDmitry Stogov <dmitry@zend.com>2018-02-05 19:40:06 +0300
commit3a794d39f081f73b2204aed8b80163a197ab41c3 (patch)
tree90af4978f502d85b1a1ac1e1e72ebeaf9e65d6bc /ext/opcache
parent7416562ab0c1062722c43c6b55d38e1a79f217cb (diff)
downloadphp-git-3a794d39f081f73b2204aed8b80163a197ab41c3.tar.gz
Avoid repeatable ARG_SHOULD_BE_SENT_BY_REF() checks in FETCH_*FUNC_ARG and following SEND_VAR_EX. Perform the check once in a new CHECK_FUNC_ARG opcode and reuse in the following FETCH_*FUNC_ARG and SEND_FUNC_ARG (SEND_VAR_EX replacement).
Diffstat (limited to 'ext/opcache')
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c16
-rw-r--r--ext/opcache/Optimizer/sccp.c1
-rw-r--r--ext/opcache/Optimizer/zend_call_graph.c1
-rw-r--r--ext/opcache/Optimizer/zend_dfg.c1
-rw-r--r--ext/opcache/Optimizer/zend_dump.c19
-rw-r--r--ext/opcache/Optimizer/zend_inference.c4
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c2
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c1
8 files changed, 29 insertions, 16 deletions
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index 2696a64879..32de6ba35c 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -40,6 +40,7 @@ typedef struct _optimizer_call_info {
zend_function *func;
zend_op *opline;
zend_bool try_inline;
+ uint32_t func_arg_num;
} optimizer_call_info;
static void zend_delete_call_instructions(zend_op *opline)
@@ -176,6 +177,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
call_stack[call].opline = opline;
+ call_stack[call].func_arg_num = (uint32_t)-1;
call++;
break;
case ZEND_DO_FCALL:
@@ -219,14 +221,15 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
call_stack[call].func = NULL;
call_stack[call].opline = NULL;
call_stack[call].try_inline = 0;
+ call_stack[call].func_arg_num = (uint32_t)-1;
break;
case ZEND_FETCH_FUNC_ARG:
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_FETCH_DIM_FUNC_ARG:
if (call_stack[call - 1].func) {
- if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- opline->extended_value &= ZEND_FETCH_TYPE_MASK;
+ ZEND_ASSERT(call_stack[call - 1].func_arg_num != (uint32_t)-1);
+ if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, call_stack[call - 1].func_arg_num)) {
if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) {
opline->opcode -= 9;
} else {
@@ -241,7 +244,6 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
break;
}
- opline->extended_value &= ZEND_FETCH_TYPE_MASK;
if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) {
opline->opcode -= 12;
} else {
@@ -260,8 +262,16 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
}
break;
+ case ZEND_CHECK_FUNC_ARG:
+ if (call_stack[call - 1].func) {
+ call_stack[call - 1].func_arg_num = opline->op2.num;
+ MAKE_NOP(opline);
+ }
+ break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
if (call_stack[call - 1].func) {
+ call_stack[call - 1].func_arg_num = (uint32_t)-1;
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
opline->opcode = ZEND_SEND_REF;
} else {
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index bf6d57f030..1b2623c307 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -228,6 +228,7 @@ static zend_bool can_replace_op1(
case ZEND_UNSET_OBJ:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_UNPACK:
case ZEND_SEND_ARRAY:
case ZEND_SEND_USER:
diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c
index 886a793971..a23e9ead63 100644
--- a/ext/opcache/Optimizer/zend_call_graph.c
+++ b/ext/opcache/Optimizer/zend_call_graph.c
@@ -152,6 +152,7 @@ int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_f
case ZEND_SEND_VAR:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c
index d750c136a2..224ea56167 100644
--- a/ext/opcache/Optimizer/zend_dfg.c
+++ b/ext/opcache/Optimizer/zend_dfg.c
@@ -95,6 +95,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_BIND_GLOBAL:
case ZEND_BIND_STATIC:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index 0724dd52e2..22e149ae55 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -563,16 +563,12 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
}
} else {
if (ZEND_VM_EXT_VAR_FETCH & flags) {
- switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
- case ZEND_FETCH_GLOBAL:
- fprintf(stderr, " (global)");
- break;
- case ZEND_FETCH_LOCAL:
- fprintf(stderr, " (local)");
- break;
- case ZEND_FETCH_GLOBAL_LOCK:
- fprintf(stderr, " (global+lock)");
- break;
+ if (opline->extended_value & ZEND_FETCH_GLOBAL) {
+ fprintf(stderr, " (global)");
+ } else if (opline->extended_value & ZEND_FETCH_LOCAL) {
+ fprintf(stderr, " (local)");
+ } else if (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK) {
+ fprintf(stderr, " (global+lock)");
}
}
if (ZEND_VM_EXT_ISSET & flags) {
@@ -582,9 +578,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
fprintf(stderr, " (empty)");
}
}
- if (ZEND_VM_EXT_ARG_NUM & flags) {
- fprintf(stderr, " %u", opline->extended_value & ZEND_FETCH_ARG_MASK);
- }
if (ZEND_VM_EXT_ARRAY_INIT & flags) {
fprintf(stderr, " %u", opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT);
if (!(opline->extended_value & ZEND_ARRAY_NOT_PACKED)) {
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index fef99bc053..26ef8b82a9 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -2721,6 +2721,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
}
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
if (ssa_ops[i].op1_def >= 0) {
tmp = (t1 & MAY_BE_UNDEF)|MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
@@ -3093,6 +3094,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
tmp |= MAY_BE_ARRAY_OF_OBJECT;
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_REF:
@@ -4042,6 +4044,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_REF:
@@ -4091,6 +4094,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
case ZEND_SEND_VAL:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_FREE:
case ZEND_SEPARATE:
case ZEND_TYPE_CHECK:
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index a7d463030f..f9b21ff19e 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -265,6 +265,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
zval_ptr_dtor_nogc(val);
return 1;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_FUNC_ARG:
@@ -593,6 +594,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
opline->opcode = ZEND_SEND_VAL;
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
opline->extended_value = 0;
opline->opcode = ZEND_SEND_VAL_EX;
break;
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index 45e6721216..a18f4a875c 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -680,6 +680,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_UNPACK:
case ZEND_FE_RESET_RW: