]> granicus.if.org Git - php/commitdiff
concat_function() micro optimization
authorDmitry Stogov <dmitry@zend.com>
Wed, 4 Jul 2018 09:05:51 +0000 (12:05 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 4 Jul 2018 09:05:51 +0000 (12:05 +0300)
Zend/zend_operators.c
Zend/zend_variables.h

index cd0e7047d0f5781807326b8353e920bb259c3e53..e10a75679d43c68c7acb61e6edd330bd80c79bfd 100644 (file)
@@ -1744,7 +1744,9 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
 {
     zval *orig_op1 = op1;
        zval op1_copy, op2_copy;
-       int use_copy1 = 0, use_copy2 = 0;
+
+       ZVAL_UNDEF(&op1_copy);
+       ZVAL_UNDEF(&op2_copy);
 
        do {
                if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
@@ -1753,22 +1755,20 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
                                if (Z_TYPE_P(op1) == IS_STRING) break;
                        }
                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
-                       use_copy1 = zend_make_printable_zval(op1, &op1_copy);
-                       if (use_copy1) {
-                               if (UNEXPECTED(EG(exception))) {
-                                       zval_dtor(&op1_copy);
-                                       if (orig_op1 != result) {
-                                               ZVAL_UNDEF(result);
-                                       }
-                                       return FAILURE;
+                       ZVAL_STR(&op1_copy, zval_get_string_func(op1));
+                       if (UNEXPECTED(EG(exception))) {
+                               zval_ptr_dtor_str(&op1_copy);
+                               if (orig_op1 != result) {
+                                       ZVAL_UNDEF(result);
                                }
-                               if (result == op1) {
-                                       if (UNEXPECTED(op1 == op2)) {
-                                               op2 = &op1_copy;
-                                       }
+                               return FAILURE;
+                       }
+                       if (result == op1) {
+                               if (UNEXPECTED(op1 == op2)) {
+                                       op2 = &op1_copy;
                                }
-                               op1 = &op1_copy;
                        }
+                       op1 = &op1_copy;
                }
        } while (0);
        do {
@@ -1778,20 +1778,16 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
                                if (Z_TYPE_P(op2) == IS_STRING) break;
                        }
                        ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
-                       use_copy2 = zend_make_printable_zval(op2, &op2_copy);
-                       if (use_copy2) {
-                               if (UNEXPECTED(EG(exception))) {
-                                       if (UNEXPECTED(use_copy1)) {
-                                               zval_dtor(op1);
-                                       }
-                                       zval_dtor(&op2_copy);
-                                       if (orig_op1 != result) {
-                                               ZVAL_UNDEF(result);
-                                       }
-                                       return FAILURE;
+                       ZVAL_STR(&op2_copy, zval_get_string_func(op2));
+                       if (UNEXPECTED(EG(exception))) {
+                               zval_ptr_dtor_str(&op1_copy);
+                               zval_ptr_dtor_str(&op2_copy);
+                               if (orig_op1 != result) {
+                                       ZVAL_UNDEF(result);
                                }
-                               op2 = &op2_copy;
+                               return FAILURE;
                        }
+                       op2 = &op2_copy;
                }
        } while (0);
 
@@ -1814,12 +1810,8 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
 
                if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) {
                        zend_throw_error(NULL, "String size overflow");
-                       if (UNEXPECTED(use_copy1)) {
-                               zval_dtor(op1);
-                       }
-                       if (UNEXPECTED(use_copy2)) {
-                               zval_dtor(op2);
-                       }
+                       zval_ptr_dtor_str(&op1_copy);
+                       zval_ptr_dtor_str(&op2_copy);
                        if (orig_op1 != result) {
                                ZVAL_UNDEF(result);
                        }
@@ -1846,12 +1838,8 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
                ZSTR_VAL(result_str)[result_len] = '\0';
        }
 
-       if (UNEXPECTED(use_copy1)) {
-               zval_dtor(op1);
-       }
-       if (UNEXPECTED(use_copy2)) {
-               zval_dtor(op2);
-       }
+       zval_ptr_dtor_str(&op1_copy);
+       zval_ptr_dtor_str(&op2_copy);
        return SUCCESS;
 }
 /* }}} */
index 154378d71fc51b5256579b185afd4649ddb36631..ebc6c5b40cdaf5f081d04fe8cc8a5f2c235e5aec 100644 (file)
@@ -71,6 +71,16 @@ static zend_always_inline void _zval_opt_copy_ctor(zval *zvalue ZEND_FILE_LINE_D
        }
 }
 
+static zend_always_inline void zval_ptr_dtor_str(zval *zval_ptr)
+{
+       if (Z_REFCOUNTED_P(zval_ptr) && !Z_DELREF_P(zval_ptr)) {
+               ZEND_ASSERT(Z_TYPE_P(zval_ptr) == IS_STRING);
+               ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zval_ptr)));
+               ZEND_ASSERT(!(GC_FLAGS(Z_STR_P(zval_ptr)) & IS_STR_PERSISTENT));
+               efree(Z_STR_P(zval_ptr));
+       }
+}
+
 ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC);
 ZEND_API void _zval_internal_ptr_dtor(zval *zvalue ZEND_FILE_LINE_DC);
 #define zval_copy_ctor(zvalue) _zval_copy_ctor((zvalue) ZEND_FILE_LINE_CC)