]> granicus.if.org Git - php/commitdiff
ZEND_SEND_* optimization
authorDmitry Stogov <dmitry@zend.com>
Tue, 22 Apr 2014 08:33:00 +0000 (12:33 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 22 Apr 2014 08:33:00 +0000 (12:33 +0400)
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index efcbe2b5d37a9409d0af838e3d3c3813d335f2b0..4b7162ec20a8e6a3f21e91391e65ec6d0dc3b971 100644 (file)
@@ -818,11 +818,11 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
 #define ZEND_SEND_PREFER_REF 2
 
 #define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \
-       ((zf)->common.arg_info && \
-       (arg_num <= (zf)->common.num_args \
+       (EXPECTED((zf)->common.arg_info != NULL) && \
+       (EXPECTED(arg_num <= (zf)->common.num_args) \
                ? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \
-               : ((zf)->common.fn_flags & ZEND_ACC_VARIADIC) \
-                       ? ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m)) : 0))
+               : (UNEXPECTED((zf)->common.fn_flags & ZEND_ACC_VARIADIC) != 0) && \
+                  ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m))))
 
 #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
        CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF)
index 63e416566927c402beff272fd56b53b0c448ceec..b80b3adbafdeb5eb7211b83b66430e803fefd097 100644 (file)
@@ -2960,6 +2960,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
 ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
 {
        USE_OPLINE
+       zval *value, *top;
+       zend_free_op free_op1;
 
        SAVE_OPLINE();
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
@@ -2969,20 +2971,12 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
                }
        }
 
-       {
-               zval *top;
-               zval *value;
-               zend_free_op free_op1;
-
-               value = GET_OP1_ZVAL_PTR(BP_VAR_R);
-               top = zend_vm_stack_top_inc(TSRMLS_C);
-               ZVAL_COPY_VALUE(top, value);
-               if (!IS_OP1_TMP_FREE()) {
-                       zval_opt_copy_ctor(top);
-               }
-               FREE_OP1_IF_VAR();
+       value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       ZVAL_COPY_VALUE(top, value);
+       if (OP1_TYPE == IS_CONST) {
+               zval_opt_copy_ctor(top);
        }
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -2998,13 +2992,11 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
                ZVAL_DUP(top, Z_REFVAL_P(varptr));
                FREE_OP1();
        } else {
+               ZVAL_COPY_VALUE(top, varptr);
                if (OP1_TYPE == IS_CV) {
-                       if (Z_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
                }
-               ZVAL_COPY_VALUE(top, varptr);
        }
-
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -3012,7 +3004,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
 {
        USE_OPLINE
        zend_free_op free_op1;
-       zval *varptr;
+       zval *varptr, *top;
        int arg_num;
 
        SAVE_OPLINE();
@@ -3035,31 +3027,23 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
             Z_TYPE_P(varptr) == IS_OBJECT ||
             (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) {
 
-               if (Z_ISREF_P(varptr)) {
-                       if (OP1_TYPE == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
-               } else {
+               if (!Z_ISREF_P(varptr)) {
                        ZVAL_NEW_REF(varptr, varptr);
-                       if (OP1_TYPE == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
+               }
+               if (OP1_TYPE == IS_CV) {
+                       Z_ADDREF_P(varptr);
                }
                zend_vm_stack_push(varptr TSRMLS_CC);
        } else {
-               zval val;
-
                if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
                        !(opline->extended_value & ZEND_ARG_SEND_SILENT) :
                        !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
                        zend_error(E_STRICT, "Only variables should be passed by reference");
                }
-               ZVAL_COPY_VALUE(&val, varptr);
-               if (!IS_OP1_TMP_FREE()) {
-                       zval_opt_copy_ctor(&val);
-               }
+               top = zend_vm_stack_top_inc(TSRMLS_C);
+               ZVAL_COPY_VALUE(top, varptr);
+               zval_opt_copy_ctor(top);
                FREE_OP1_IF_VAR();
-               zend_vm_stack_push(&val TSRMLS_CC);
        }
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -3080,7 +3064,6 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
 
        if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
                zend_vm_stack_push(&EG(uninitialized_zval) TSRMLS_CC);
-               CHECK_EXCEPTION();
                ZEND_VM_NEXT_OPCODE();
        }
 
@@ -3108,13 +3091,14 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
        zend_vm_stack_push(varptr TSRMLS_CC);
 
        FREE_OP1_VAR_PTR();
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
 ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
 {
        USE_OPLINE
+       zval *varptr, *top;
+       zend_free_op free_op1;
 
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
                int arg_num = opline->op2.num + EX(call)->num_additional_args;
@@ -3122,8 +3106,19 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
                        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
                }
        }
-       SAVE_OPLINE();
-       ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
+
+       varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       if (Z_ISREF_P(varptr)) {
+               ZVAL_DUP(top, Z_REFVAL_P(varptr));
+               FREE_OP1();
+       } else {
+               ZVAL_COPY_VALUE(top, varptr);
+               if (OP1_TYPE == IS_CV) {
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+               }
+       }
+       ZEND_VM_NEXT_OPCODE();
 }
 
 ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
index af9b09dfd26ade534d6b6608e59c9f35bb2ba48d..af5aa46aa403a8f2db090076174e1eb0334667a9 100644 (file)
@@ -2656,6 +2656,8 @@ static int ZEND_FASTCALL  ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
+       zval *value, *top;
+
 
        SAVE_OPLINE();
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
@@ -2665,20 +2667,12 @@ static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                }
        }
 
-       {
-               zval *top;
-               zval *value;
-
-
-               value = opline->op1.zv;
-               top = zend_vm_stack_top_inc(TSRMLS_C);
-               ZVAL_COPY_VALUE(top, value);
-               if (!0) {
-                       zval_opt_copy_ctor(top);
-               }
-
+       value = opline->op1.zv;
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       ZVAL_COPY_VALUE(top, value);
+       if (IS_CONST == IS_CONST) {
+               zval_opt_copy_ctor(top);
        }
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -7604,6 +7598,8 @@ static int ZEND_FASTCALL  ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
+       zval *value, *top;
+       zend_free_op free_op1;
 
        SAVE_OPLINE();
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
@@ -7613,20 +7609,12 @@ static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
                }
        }
 
-       {
-               zval *top;
-               zval *value;
-               zend_free_op free_op1;
-
-               value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               top = zend_vm_stack_top_inc(TSRMLS_C);
-               ZVAL_COPY_VALUE(top, value);
-               if (!1) {
-                       zval_opt_copy_ctor(top);
-               }
-
+       value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       ZVAL_COPY_VALUE(top, value);
+       if (IS_TMP_VAR == IS_CONST) {
+               zval_opt_copy_ctor(top);
        }
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -12511,13 +12499,11 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR
                ZVAL_DUP(top, Z_REFVAL_P(varptr));
                zval_ptr_dtor_nogc(free_op1.var);
        } else {
+               ZVAL_COPY_VALUE(top, varptr);
                if (IS_VAR == IS_CV) {
-                       if (Z_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
                }
-               ZVAL_COPY_VALUE(top, varptr);
        }
-
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -12525,7 +12511,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
 {
        USE_OPLINE
        zend_free_op free_op1;
-       zval *varptr;
+       zval *varptr, *top;
        int arg_num;
 
        SAVE_OPLINE();
@@ -12548,31 +12534,23 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
             Z_TYPE_P(varptr) == IS_OBJECT ||
             (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) {
 
-               if (Z_ISREF_P(varptr)) {
-                       if (IS_VAR == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
-               } else {
+               if (!Z_ISREF_P(varptr)) {
                        ZVAL_NEW_REF(varptr, varptr);
-                       if (IS_VAR == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
+               }
+               if (IS_VAR == IS_CV) {
+                       Z_ADDREF_P(varptr);
                }
                zend_vm_stack_push(varptr TSRMLS_CC);
        } else {
-               zval val;
-
                if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
                        !(opline->extended_value & ZEND_ARG_SEND_SILENT) :
                        !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
                        zend_error(E_STRICT, "Only variables should be passed by reference");
                }
-               ZVAL_COPY_VALUE(&val, varptr);
-               if (!0) {
-                       zval_opt_copy_ctor(&val);
-               }
+               top = zend_vm_stack_top_inc(TSRMLS_C);
+               ZVAL_COPY_VALUE(top, varptr);
+               zval_opt_copy_ctor(top);
                zval_ptr_dtor_nogc(free_op1.var);
-               zend_vm_stack_push(&val TSRMLS_CC);
        }
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -12593,7 +12571,6 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
        if (IS_VAR == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
                zend_vm_stack_push(&EG(uninitialized_zval) TSRMLS_CC);
-               CHECK_EXCEPTION();
                ZEND_VM_NEXT_OPCODE();
        }
 
@@ -12621,13 +12598,14 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
        zend_vm_stack_push(varptr TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
+       zval *varptr, *top;
+       zend_free_op free_op1;
 
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
                int arg_num = opline->op2.num + EX(call)->num_additional_args;
@@ -12635,8 +12613,19 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                }
        }
-       SAVE_OPLINE();
-       return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+
+       varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       if (Z_ISREF_P(varptr)) {
+               ZVAL_DUP(top, Z_REFVAL_P(varptr));
+               zval_ptr_dtor_nogc(free_op1.var);
+       } else {
+               ZVAL_COPY_VALUE(top, varptr);
+               if (IS_VAR == IS_CV) {
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+               }
+       }
+       ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -29160,13 +29149,11 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG
                ZVAL_DUP(top, Z_REFVAL_P(varptr));
 
        } else {
+               ZVAL_COPY_VALUE(top, varptr);
                if (IS_CV == IS_CV) {
-                       if (Z_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
                }
-               ZVAL_COPY_VALUE(top, varptr);
        }
-
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -29174,7 +29161,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
 {
        USE_OPLINE
 
-       zval *varptr;
+       zval *varptr, *top;
        int arg_num;
 
        SAVE_OPLINE();
@@ -29197,31 +29184,23 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
             Z_TYPE_P(varptr) == IS_OBJECT ||
             (Z_REFCOUNTED_P(varptr) && Z_REFCOUNT_P(varptr) == 1))) {
 
-               if (Z_ISREF_P(varptr)) {
-                       if (IS_CV == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
-               } else {
+               if (!Z_ISREF_P(varptr)) {
                        ZVAL_NEW_REF(varptr, varptr);
-                       if (IS_CV == IS_CV) {
-                               Z_ADDREF_P(varptr);
-                       }
+               }
+               if (IS_CV == IS_CV) {
+                       Z_ADDREF_P(varptr);
                }
                zend_vm_stack_push(varptr TSRMLS_CC);
        } else {
-               zval val;
-
                if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
                        !(opline->extended_value & ZEND_ARG_SEND_SILENT) :
                        !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
                        zend_error(E_STRICT, "Only variables should be passed by reference");
                }
-               ZVAL_COPY_VALUE(&val, varptr);
-               if (!0) {
-                       zval_opt_copy_ctor(&val);
-               }
+               top = zend_vm_stack_top_inc(TSRMLS_C);
+               ZVAL_COPY_VALUE(top, varptr);
+               zval_opt_copy_ctor(top);
 
-               zend_vm_stack_push(&val TSRMLS_CC);
        }
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -29242,7 +29221,6 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
        if (IS_CV == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
                zend_vm_stack_push(&EG(uninitialized_zval) TSRMLS_CC);
-               CHECK_EXCEPTION();
                ZEND_VM_NEXT_OPCODE();
        }
 
@@ -29269,13 +29247,14 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
        zend_vm_stack_push(varptr TSRMLS_CC);
 
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
+       zval *varptr, *top;
+
 
        if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
                int arg_num = opline->op2.num + EX(call)->num_additional_args;
@@ -29283,8 +29262,19 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                        return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                }
        }
-       SAVE_OPLINE();
-       return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+
+       varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+       top = zend_vm_stack_top_inc(TSRMLS_C);
+       if (Z_ISREF_P(varptr)) {
+               ZVAL_DUP(top, Z_REFVAL_P(varptr));
+
+       } else {
+               ZVAL_COPY_VALUE(top, varptr);
+               if (IS_CV == IS_CV) {
+                       if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+               }
+       }
+       ZEND_VM_NEXT_OPCODE();
 }
 
 static int ZEND_FASTCALL  ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)