diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-02-05 19:40:06 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-02-05 19:40:06 +0300 |
commit | 3a794d39f081f73b2204aed8b80163a197ab41c3 (patch) | |
tree | 90af4978f502d85b1a1ac1e1e72ebeaf9e65d6bc /ext | |
parent | 7416562ab0c1062722c43c6b55d38e1a79f217cb (diff) | |
download | php-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')
-rw-r--r-- | ext/opcache/Optimizer/optimize_func_calls.c | 16 | ||||
-rw-r--r-- | ext/opcache/Optimizer/sccp.c | 1 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_call_graph.c | 1 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_dfg.c | 1 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_dump.c | 19 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 4 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_ssa.c | 1 |
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: |