diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-05-29 13:59:01 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-05-29 13:59:01 +0300 |
commit | 207d928da8514e1ad30bd9aa47b3a26b6a89c8d9 (patch) | |
tree | 1c5efd3d1dcce8a2380baa3573843b8dfacac890 /Zend/zend_execute.h | |
parent | c7a67c6dcef5c1d07f2cdbdf11ba25166da2d5f0 (diff) | |
parent | b06f05bf4782c4c7110f9d974db1b70c4cda36c0 (diff) | |
download | php-git-207d928da8514e1ad30bd9aa47b3a26b6a89c8d9.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
zend_assign_to_variable() optimization
Diffstat (limited to 'Zend/zend_execute.h')
-rw-r--r-- | Zend/zend_execute.h | 73 |
1 files changed, 25 insertions, 48 deletions
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index e34c56def2..053d22afd0 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -78,10 +78,31 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(zend_property_info *prop1 ZEND_API void ZEND_FASTCALL zend_ref_add_type_source(zend_property_info_source_list *source_list, zend_property_info *prop); ZEND_API void ZEND_FASTCALL zend_ref_del_type_source(zend_property_info_source_list *source_list, zend_property_info *prop); +ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, zend_uchar value_type, zend_bool strict, zend_refcounted *ref); + +static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type, zend_refcounted *ref) +{ + ZVAL_COPY_VALUE(variable_ptr, value); + if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } else if (value_type & (IS_CONST|IS_CV)) { + if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); + } + } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); + } + } +} + static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type, zend_bool strict) { zend_refcounted *ref = NULL; - zval tmp; if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && Z_ISREF_P(value)) { ref = Z_COUNTED_P(value); @@ -94,21 +115,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval if (Z_ISREF_P(variable_ptr)) { if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) { - zend_bool need_copy = ZEND_CONST_COND(value_type & (IS_CONST|IS_CV), 1) || - ((value_type & IS_VAR) && UNEXPECTED(ref) && GC_REFCOUNT(ref) > 1); - zend_bool ret; - if (need_copy) { - ZVAL_COPY(&tmp, value); - value = &tmp; - } - ret = zend_verify_ref_assignable_zval(Z_REF_P(variable_ptr), value, strict); - if (need_copy) { - Z_TRY_DELREF_P(value); - } - if (!ret) { - zval_ptr_dtor(value); - return Z_REFVAL_P(variable_ptr); - } + return zend_assign_to_typed_ref(variable_ptr, value, value_type, strict, ref); } variable_ptr = Z_REFVAL_P(variable_ptr); @@ -117,22 +124,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval } } garbage = Z_COUNTED_P(variable_ptr); - ZVAL_COPY_VALUE(variable_ptr, value); - if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } else if (value_type & (IS_CONST|IS_CV)) { - if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } + zend_copy_to_variable(variable_ptr, value, value_type, ref); if (GC_DELREF(garbage) == 0) { rc_dtor_func(garbage); } else { /* we need to split */ @@ -145,22 +137,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval } } while (0); - ZVAL_COPY_VALUE(variable_ptr, value); - if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } else if (value_type & (IS_CONST|IS_CV)) { - if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } + zend_copy_to_variable(variable_ptr, value, value_type, ref); return variable_ptr; } |