summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-11-18 14:37:36 +0300
committerDmitry Stogov <dmitry@zend.com>2014-11-18 14:37:36 +0300
commite20a727430713cc4ab81bc8faad64d616837c787 (patch)
tree5c6030cbee9313a644a72c3ed8b3cd9eba74e033
parentd86b5e2b082d6edcb6c92bf59ef56576d07da180 (diff)
downloadphp-git-e20a727430713cc4ab81bc8faad64d616837c787.tar.gz
SEND_VAR_NO_REF optimization
-rw-r--r--Zend/zend_compile.c7
-rw-r--r--Zend/zend_vm_def.h19
-rw-r--r--Zend/zend_vm_execute.h38
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c2
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c8
5 files changed, 35 insertions, 39 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index c3a572a04d..d15b85fc0b 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2478,7 +2478,12 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc TSRMLS_DC) /* {{{ *
if (fbc) {
flags |= ZEND_ARG_COMPILE_TIME_BOUND;
}
- opline->extended_value = flags;
+ if ((flags & ZEND_ARG_COMPILE_TIME_BOUND) && !(flags & ZEND_ARG_SEND_BY_REF)) {
+ opline->opcode = ZEND_SEND_VAR;
+ opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
+ } else {
+ opline->extended_value = flags;
+ }
} else if (fbc) {
opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 7ea7929a69..f0ebac44ef 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -3062,11 +3062,8 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
zval *varptr, *arg;
SAVE_OPLINE();
- if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
- if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
- ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
- }
- } else {
+
+ if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) {
if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
}
@@ -3081,20 +3078,18 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
if (OP1_TYPE == IS_CV) {
Z_ADDREF_P(varptr);
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY_VALUE(arg, varptr);
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY(arg, varptr);
- FREE_OP1_IF_VAR();
}
+
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 6680da3458..fc563b40a8 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -16482,11 +16482,8 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
zval *varptr, *arg;
SAVE_OPLINE();
- if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
- if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
- return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- } else {
+
+ if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) {
if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -16501,20 +16498,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_CV) {
Z_ADDREF_P(varptr);
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY_VALUE(arg, varptr);
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY(arg, varptr);
- zval_ptr_dtor_nogc(free_op1);
}
+
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -34276,11 +34271,8 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
zval *varptr, *arg;
SAVE_OPLINE();
- if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
- if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
- return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- } else {
+
+ if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) {
if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -34295,20 +34287,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_CV) {
Z_ADDREF_P(varptr);
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY_VALUE(arg, varptr);
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY(arg, varptr);
-
}
+
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index aa62a4542d..9031a38f56 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -143,8 +143,6 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS
if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) {
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND | ZEND_ARG_SEND_BY_REF;
- } else if (opline->extended_value) {
- opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND;
} else {
opline->opcode = ZEND_SEND_VAR;
opline->extended_value = 0;
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 1a6d0b675a..589028368f 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -283,6 +283,14 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
case ZEND_ASSIGN_DIM:
case ZEND_SEPARATE:
return 0;
+ case ZEND_SEND_VAR:
+ opline->extended_value = 0;
+ opline->opcode = ZEND_SEND_VAL;
+ break;
+ case ZEND_SEND_VAR_EX:
+ opline->extended_value = 0;
+ opline->opcode = ZEND_SEND_VAL_EX;
+ break;
case ZEND_SEND_VAR_NO_REF:
if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) {
if (opline->extended_value & ZEND_ARG_SEND_BY_REF) {