]> granicus.if.org Git - php/commitdiff
Constant duplication optimization
authorDmitry Stogov <dmitry@zend.com>
Thu, 3 Apr 2014 23:55:27 +0000 (03:55 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 3 Apr 2014 23:55:27 +0000 (03:55 +0400)
Argument receiving optimization

Zend/zend_API.c
Zend/zend_ast.c
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/reflection/php_reflection.c

index 36995787dfd1f7bd5dad916fba4344144c7b9a55..104c5b3ed47abbe5250805e6e540893656987d84 100644 (file)
@@ -1112,7 +1112,7 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destro
 static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS_DC) /* {{{ */
 {
        ZVAL_DEREF(pp);
-       if (Z_TYPE_FLAGS_P(pp) & IS_TYPE_CONSTANT) {
+       if (Z_CONSTANT_P(pp)) {
                zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
 
                if ((*scope)->parent) {
index d144a1e6d3f4c8ec69a65b73737c7e609e3696db..d0cd7da102f945c1b1d4581d5c48ca7641658607 100644 (file)
@@ -67,7 +67,7 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
        int i;
 
        if (ast->kind == ZEND_CONST) {
-               return !(Z_TYPE_FLAGS(ast->u.val) & IS_TYPE_CONSTANT);
+               return !Z_CONSTANT(ast->u.val);
        } else {
                for (i = 0; i < ast->children; i++) {
                        if ((&ast->u.child)[i]) {
@@ -223,7 +223,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
                        break;
                case ZEND_CONST:
                        ZVAL_DUP(result, &ast->u.val);
-                       if (Z_TYPE_FLAGS_P(result) & IS_TYPE_CONSTANT) {
+                       if (Z_CONSTANT_P(result)) {
                                zval_update_constant_ex(result, (void *) 1, scope TSRMLS_CC);
                        }
                        break;
index 48007ba9c8f74579f49abddbff55fe69fe4e8316..b6dd50ddf473b1f3c3167c56f08793ace9eec7d0 100644 (file)
@@ -937,7 +937,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 
                /* this is necessary to make it able to work with default array
                 * properties, returned to user */
-               if (Z_TYPE_FLAGS(prop_copy) & IS_TYPE_CONSTANT) {
+               if (Z_CONSTANT(prop_copy)) {
                        zval_update_constant(&prop_copy, 0 TSRMLS_CC);
                }
 
index a132fc4a15044ba60065704132f91f2465dd5f02..e02778f5de1e003befce661af3c3cb60fe5219b1 100644 (file)
@@ -5672,7 +5672,7 @@ static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal
        if (all_internal_constants_substitution &&
            (c->flags & CONST_PERSISTENT) &&
            !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) &&
-           !(Z_TYPE_FLAGS(c->value) & IS_TYPE_CONSTANT)) {
+           !Z_CONSTANT(c->value)) {
                return c;
        }
        return NULL;
index 5a50b37156145e5ca3233f16b11d29e0519ccc4e..8ace69a7db656c41bc77d10fce469beb220bdbc1 100644 (file)
@@ -326,6 +326,9 @@ static inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_OBJ_DEC_APPLY_COUNT_P(zv) Z_OBJ_DEC_APPLY_COUNT(*(zv))
 
 /* All data types < IS_STRING have their constructor/destructors skipped */
+#define Z_CONSTANT(zval)                       ((Z_TYPE_FLAGS(zval) & IS_TYPE_CONSTANT) != 0)
+#define Z_CONSTANT_P(zval_p)           Z_CONSTANT(*(zval_p))
+
 #define Z_REFCOUNTED(zval)                     ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0)
 #define Z_REFCOUNTED_P(zval_p)         Z_REFCOUNTED(*(zval_p))
 
@@ -339,6 +342,9 @@ static inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_OPT_TYPE(zval)                       (Z_TYPE_INFO(zval) & 0xff)
 #define Z_OPT_TYPE_P(zval_p)           Z_OPT_TYPE(*(zval_p))
 
+#define Z_OPT_CONSTANT(zval)           ((Z_TYPE_INFO(zval) & (IS_TYPE_CONSTANT << Z_TYPE_FLAGS_SHIFT)) != 0)
+#define Z_OPT_CONSTANT_P(zval_p)       Z_OPT_CONSTANT(*(zval_p))
+
 #define Z_OPT_REFCOUNTED(zval)         ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)
 #define Z_OPT_REFCOUNTED_P(zval_p)     Z_OPT_REFCOUNTED(*(zval_p))
 
index 3ef75f12796502accd5868c77d136df12ff72740..8c95eaeb5f16464eb9deee9eb1fbb465254c003f 100644 (file)
@@ -3337,7 +3337,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+       zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
 
        SAVE_OPLINE();
        if (UNEXPECTED(param == NULL)) {
@@ -3377,21 +3377,21 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+       zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
        zval *var_ptr;
 
        SAVE_OPLINE();
        var_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
        zval_ptr_dtor(var_ptr);
        if (param == NULL) {
-               if (Z_TYPE_FLAGS_P(opline->op2.zv) & IS_TYPE_CONSTANT) {
-                       zval tmp;
-                                       
-                       ZVAL_COPY_VALUE(&tmp, opline->op2.zv);
-                       zval_update_constant(&tmp, 0 TSRMLS_CC);
-                       ZVAL_COPY_VALUE(var_ptr, &tmp);
+               ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
+               if (Z_OPT_CONSTANT_P(var_ptr)) {
+                       zval_update_constant(var_ptr, 0 TSRMLS_CC);
                } else {
-                       ZVAL_DUP(var_ptr, opline->op2.zv);
+                       /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
+                       if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) {
+                               _zval_copy_ctor_func(var_ptr ZEND_FILE_LINE_CC);
+                       }
                }
        } else {
                ZVAL_COPY(var_ptr, param);
@@ -3407,7 +3407,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C);
+       zend_uint arg_count = zend_vm_stack_get_args_count_ex(EX(prev_execute_data) TSRMLS_CC);
        zval *params;
 
        SAVE_OPLINE();
@@ -3422,7 +3422,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
        }
 
        for (; arg_num <= arg_count; ++arg_num) {
-               zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+               zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, param, opline->extended_value TSRMLS_CC);
                zend_hash_next_index_insert(Z_ARRVAL_P(params), param);
                if (Z_REFCOUNTED_P(param)) {
@@ -3697,7 +3697,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                }
 
                if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
-                       if (Z_TYPE_FLAGS_P(value) & IS_TYPE_CONSTANT) {
+                       if (Z_CONSTANT_P(value)) {
                                zend_class_entry *old_scope = EG(scope);
 
                                EG(scope) = ce;
@@ -5321,14 +5321,17 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
        name  = GET_OP1_ZVAL_PTR(BP_VAR_R);
        val   = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       if (Z_TYPE_FLAGS_P(val) & IS_TYPE_CONSTANT) {
-               ZVAL_COPY_VALUE(&c.value, val);
+       ZVAL_COPY_VALUE(&c.value, val);
+       if (Z_OPT_CONSTANT(c.value)) {
                if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
                        zval_opt_copy_ctor(&c.value);
                }
                zval_update_constant(&c.value, NULL TSRMLS_CC);
        } else {
-               ZVAL_DUP(&c.value, val);
+               /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
+               if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) {
+                       _zval_copy_ctor_func(&c.value ZEND_FILE_LINE_CC);
+               }
        }
        c.flags = CONST_CS; /* non persistent, case sensetive */
        c.name = STR_DUP(Z_STR_P(name), 0);
index 342762b941eec046a79e3c0cbd2d599ba5833fa3..e1c0ee2de4150b3787e5e7febb97ccfdf4637c25 100644 (file)
@@ -853,7 +853,7 @@ static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+       zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
 
        SAVE_OPLINE();
        if (UNEXPECTED(param == NULL)) {
@@ -893,7 +893,7 @@ static int ZEND_FASTCALL  ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C);
+       zend_uint arg_count = zend_vm_stack_get_args_count_ex(EX(prev_execute_data) TSRMLS_CC);
        zval *params;
 
        SAVE_OPLINE();
@@ -908,7 +908,7 @@ static int ZEND_FASTCALL  ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
        }
 
        for (; arg_num <= arg_count; ++arg_num) {
-               zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+               zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, param, opline->extended_value TSRMLS_CC);
                zend_hash_next_index_insert(Z_ARRVAL_P(params), param);
                if (Z_REFCOUNTED_P(param)) {
@@ -1600,21 +1600,21 @@ static int ZEND_FASTCALL  ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
 {
        USE_OPLINE
        zend_uint arg_num = opline->op1.num;
-       zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
+       zval *param = zend_vm_stack_get_arg_ex(EX(prev_execute_data), arg_num TSRMLS_CC);
        zval *var_ptr;
 
        SAVE_OPLINE();
        var_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
        zval_ptr_dtor(var_ptr);
        if (param == NULL) {
-               if (Z_TYPE_FLAGS_P(opline->op2.zv) & IS_TYPE_CONSTANT) {
-                       zval tmp;
-
-                       ZVAL_COPY_VALUE(&tmp, opline->op2.zv);
-                       zval_update_constant(&tmp, 0 TSRMLS_CC);
-                       ZVAL_COPY_VALUE(var_ptr, &tmp);
+               ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
+               if (Z_OPT_CONSTANT_P(var_ptr)) {
+                       zval_update_constant(var_ptr, 0 TSRMLS_CC);
                } else {
-                       ZVAL_DUP(var_ptr, opline->op2.zv);
+                       /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
+                       if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) {
+                               _zval_copy_ctor_func(var_ptr ZEND_FILE_LINE_CC);
+                       }
                }
        } else {
                ZVAL_COPY(var_ptr, param);
@@ -3929,7 +3929,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                }
 
                if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
-                       if (Z_TYPE_FLAGS_P(value) & IS_TYPE_CONSTANT) {
+                       if (Z_CONSTANT_P(value)) {
                                zend_class_entry *old_scope = EG(scope);
 
                                EG(scope) = ce;
@@ -4205,14 +4205,17 @@ static int ZEND_FASTCALL  ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
        name  = opline->op1.zv;
        val   = opline->op2.zv;
 
-       if (Z_TYPE_FLAGS_P(val) & IS_TYPE_CONSTANT) {
-               ZVAL_COPY_VALUE(&c.value, val);
+       ZVAL_COPY_VALUE(&c.value, val);
+       if (Z_OPT_CONSTANT(c.value)) {
                if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
                        zval_opt_copy_ctor(&c.value);
                }
                zval_update_constant(&c.value, NULL TSRMLS_CC);
        } else {
-               ZVAL_DUP(&c.value, val);
+               /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
+               if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) {
+                       _zval_copy_ctor_func(&c.value ZEND_FILE_LINE_CC);
+               }
        }
        c.flags = CONST_CS; /* non persistent, case sensetive */
        c.name = STR_DUP(Z_STR_P(name), 0);
@@ -15337,7 +15340,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                }
 
                if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
-                       if (Z_TYPE_FLAGS_P(value) & IS_TYPE_CONSTANT) {
+                       if (Z_CONSTANT_P(value)) {
                                zend_class_entry *old_scope = EG(scope);
 
                                EG(scope) = ce;
@@ -24664,7 +24667,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                }
 
                if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
-                       if (Z_TYPE_FLAGS_P(value) & IS_TYPE_CONSTANT) {
+                       if (Z_CONSTANT_P(value)) {
                                zend_class_entry *old_scope = EG(scope);
 
                                EG(scope) = ce;
index 1abb471fbc4cab44c420025cb51d59b98d7d031f..ff5d8e2091f858598ed434f2edae30b8070deac3 100644 (file)
@@ -2588,7 +2588,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
 
        ZVAL_COPY_VALUE(return_value, precv->op2.zv);
 //???  INIT_PZVAL(return_value);
-       if (!(Z_TYPE_FLAGS_P(return_value) & IS_TYPE_CONSTANT)) {
+       if (!Z_CONSTANT_P(return_value)) {
                zval_copy_ctor(return_value);
        }
        zval_update_constant_ex(return_value, (void*)0, param->fptr->common.scope TSRMLS_CC);
@@ -3383,7 +3383,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 
                /* this is necessary to make it able to work with default array
                * properties, returned to user */
-               if (Z_TYPE_FLAGS(prop_copy) & IS_TYPE_CONSTANT) {
+               if (Z_CONSTANT(prop_copy)) {
                        zval_update_constant(&prop_copy, (void *) 1 TSRMLS_CC);
                }