]> granicus.if.org Git - php/commitdiff
Better fix for bug #72854 (avoid extra copy and creating reference to stack variable)
authorDmitry Stogov <dmitry@zend.com>
Thu, 29 Sep 2016 07:56:01 +0000 (10:56 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 29 Sep 2016 07:56:01 +0000 (10:56 +0300)
Zend/zend_execute.c

index 2882f3dc33de5e69d7aaec4ec8b8c69def71fcde..326c719c65b318c6209b06f3c2916db5a4a97150 100644 (file)
@@ -576,7 +576,6 @@ static inline zval *_get_obj_zval_ptr_ptr(int op_type, znode_op node, zend_execu
 static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr)
 {
        zend_reference *ref;
-       zval garbage;
 
        if (EXPECTED(!Z_ISREF_P(value_ptr))) {
                ZVAL_NEW_REF(value_ptr, value_ptr);
@@ -586,9 +585,18 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v
 
        ref = Z_REF_P(value_ptr);
        GC_REFCOUNT(ref)++;
-       ZVAL_COPY_VALUE(&garbage, variable_ptr);
+       if (Z_REFCOUNTED_P(variable_ptr)) {
+               zend_refcounted *garbage = Z_COUNTED_P(variable_ptr);
+
+               if (--GC_REFCOUNT(garbage) == 0) {
+                       ZVAL_REF(variable_ptr, ref);
+                       zval_dtor_func_for_ptr(garbage);
+                       return;
+               } else {
+                       GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
+               }
+       }
        ZVAL_REF(variable_ptr, ref);
-       zval_ptr_dtor(&garbage);
 }
 
 /* this should modify object only if it's empty */