]> granicus.if.org Git - php/commitdiff
SEND_VAR_NO_REF optimization
authorDmitry Stogov <dmitry@zend.com>
Tue, 18 Nov 2014 11:37:36 +0000 (14:37 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 18 Nov 2014 11:37:36 +0000 (14:37 +0300)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/optimize_func_calls.c
ext/opcache/Optimizer/zend_optimizer.c

index c3a572a04d5dffdc8acae45c2a16877879cd3d4e..d15b85fc0ba28dec863fa8d4d22b1b5f4d9c2dd1 100644 (file)
@@ -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;
                }
index 7ea7929a6964508bfa8175909c5301654774d4d9..f0ebac44efe36e3b53a69f90cc74016a200630de 100644 (file)
@@ -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();
 }
index 6680da3458e440947e220d29674b9c9102fb36e7..fc563b40a824d3742162cb18d8e5b4eb26b80e82 100644 (file)
@@ -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();
 }
index aa62a4542ddadb1e33a43ad916e9fff78974b232..9031a38f56ba5fe9e5d052e819d9eeec91b543e7 100644 (file)
@@ -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;
index 1a6d0b675afa510c5c5ddd5bc83a184cfaf8c99d..589028368f1988f67f355da3c4c22b660933fdf8 100644 (file)
@@ -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) {