From b06f05bf4782c4c7110f9d974db1b70c4cda36c0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 29 May 2019 13:58:37 +0300 Subject: zend_assign_to_variable() optimization --- Zend/zend_execute.h | 73 ++++++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 48 deletions(-) (limited to 'Zend/zend_execute.h') diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 494a5c999d..b75aa0a2ad 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); @@ -122,22 +129,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval return variable_ptr; } 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 */ @@ -150,22 +142,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; } -- cgit v1.2.1