summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.h
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-05-29 13:59:01 +0300
committerDmitry Stogov <dmitry@zend.com>2019-05-29 13:59:01 +0300
commit207d928da8514e1ad30bd9aa47b3a26b6a89c8d9 (patch)
tree1c5efd3d1dcce8a2380baa3573843b8dfacac890 /Zend/zend_execute.h
parentc7a67c6dcef5c1d07f2cdbdf11ba25166da2d5f0 (diff)
parentb06f05bf4782c4c7110f9d974db1b70c4cda36c0 (diff)
downloadphp-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.h73
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;
}