From: Dmitry Stogov Date: Thu, 3 Apr 2014 23:55:27 +0000 (+0400) Subject: Constant duplication optimization X-Git-Tag: POST_PHPNG_MERGE~412^2~170 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bc8810b1eb0c0b5f44da4ee1d348053bd98463a;p=php Constant duplication optimization Argument receiving optimization --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 36995787df..104c5b3ed4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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) { diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d144a1e6d3..d0cd7da102 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -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; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 48007ba9c8..b6dd50ddf4 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -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); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a132fc4a15..e02778f5de 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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; diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 5a50b37156..8ace69a7db 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -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)) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3ef75f1279..8c95eaeb5f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 342762b941..e1c0ee2de4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1abb471fbc..ff5d8e2091 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -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); }