]> granicus.if.org Git - php/commitdiff
Avoid double copying
authorDmitry Stogov <dmitry@zend.com>
Tue, 28 May 2019 10:35:00 +0000 (13:35 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 28 May 2019 10:35:00 +0000 (13:35 +0300)
Zend/zend_builtin_functions.c
Zend/zend_hash.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/standard/array.c

index 5fc69c24bf4b029218b9787bc3d5253893700c68..5333e3e315c8ffea305457a75b4bd922f2c36579 100644 (file)
@@ -540,10 +540,11 @@ ZEND_FUNCTION(func_get_args)
                                                if (Z_OPT_REFCOUNTED_P(q)) {
                                                        Z_ADDREF_P(q);
                                                }
+                                               ZEND_HASH_FILL_SET(q);
                                        } else {
-                                               q = &EG(uninitialized_zval);
+                                               ZEND_HASH_FILL_SET_NULL();
                                        }
-                                       ZEND_HASH_FILL_ADD(q);
+                                       ZEND_HASH_FILL_NEXT();
                                        p++;
                                        i++;
                                }
@@ -556,10 +557,11 @@ ZEND_FUNCTION(func_get_args)
                                        if (Z_OPT_REFCOUNTED_P(q)) {
                                                Z_ADDREF_P(q);
                                        }
+                                       ZEND_HASH_FILL_SET(q);
                                } else {
-                                       q = &EG(uninitialized_zval);
+                                       ZEND_HASH_FILL_SET_NULL();
                                }
-                               ZEND_HASH_FILL_ADD(q);
+                               ZEND_HASH_FILL_NEXT();
                                p++;
                                i++;
                        }
@@ -2093,10 +2095,11 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
                                                        if (Z_OPT_REFCOUNTED_P(arg)) {
                                                                Z_ADDREF_P(arg);
                                                        }
-                                                       ZEND_HASH_FILL_ADD(arg);
+                                                       ZEND_HASH_FILL_SET(arg);
                                                } else {
-                                                       ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
+                                                       ZEND_HASH_FILL_SET_NULL();
                                                }
+                                               ZEND_HASH_FILL_NEXT();
                                                i++;
                                        }
                                } else {
@@ -2105,10 +2108,11 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
                                                        if (Z_OPT_REFCOUNTED_P(p)) {
                                                                Z_ADDREF_P(p);
                                                        }
-                                                       ZEND_HASH_FILL_ADD(p);
+                                                       ZEND_HASH_FILL_SET(p);
                                                } else {
-                                                       ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
+                                                       ZEND_HASH_FILL_SET_NULL();
                                                }
+                                               ZEND_HASH_FILL_NEXT();
                                                p++;
                                                i++;
                                        }
@@ -2121,10 +2125,11 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
                                        if (Z_OPT_REFCOUNTED_P(p)) {
                                                Z_ADDREF_P(p);
                                        }
-                                       ZEND_HASH_FILL_ADD(p);
+                                       ZEND_HASH_FILL_SET(p);
                                } else {
-                                       ZEND_HASH_FILL_ADD(&EG(uninitialized_zval));
+                                       ZEND_HASH_FILL_SET_NULL();
                                }
+                               ZEND_HASH_FILL_NEXT();
                                p++;
                                i++;
                        }
index 3341427428a56233265127c6b4b09114f316e4da..166a9b2d6cdae969fbd0557ef158b32fafe489be 100644 (file)
@@ -1076,14 +1076,39 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
                uint32_t __fill_idx = __fill_ht->nNumUsed; \
                ZEND_ASSERT(HT_FLAGS(__fill_ht) & HASH_FLAG_PACKED);
 
-#define ZEND_HASH_FILL_ADD(_val) do { \
-               ZVAL_COPY_VALUE(&__fill_bkt->val, _val); \
+#define ZEND_HASH_FILL_SET(_val) \
+               ZVAL_COPY_VALUE(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_SET_NULL() \
+               ZVAL_NULL(&__fill_bkt->val)
+
+#define ZEND_HASH_FILL_SET_LONG(_val) \
+               ZVAL_LONG(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_SET_DOUBLE(_val) \
+               ZVAL_DOUBLE(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_SET_STR(_val) \
+               ZVAL_STR(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_SET_STR_COPY(_val) \
+               ZVAL_STR_COPY(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_SET_INTERNED_STR(_val) \
+               ZVAL_INTERNED_STR(&__fill_bkt->val, _val)
+
+#define ZEND_HASH_FILL_NEXT() do {\
                __fill_bkt->h = (__fill_idx); \
                __fill_bkt->key = NULL; \
                __fill_bkt++; \
                __fill_idx++; \
        } while (0)
 
+#define ZEND_HASH_FILL_ADD(_val) do { \
+               ZEND_HASH_FILL_SET(_val); \
+               ZEND_HASH_FILL_NEXT(); \
+       } while (0)
+
 #define ZEND_HASH_FILL_END() \
                __fill_ht->nNumUsed = __fill_idx; \
                __fill_ht->nNumOfElements = __fill_idx; \
index 50ce8c1e9299c944c06c024f1cc7bc03b1a89f69..6a57beccb146676134328d5d258e5815af6913c9 100644 (file)
@@ -8584,10 +8584,11 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
                                                if (Z_OPT_REFCOUNTED_P(q)) {
                                                        Z_ADDREF_P(q);
                                                }
+                                               ZEND_HASH_FILL_SET(q);
                                        } else {
-                                               q = &EG(uninitialized_zval);
+                                               ZEND_HASH_FILL_SET_NULL();
                                        }
-                                       ZEND_HASH_FILL_ADD(q);
+                                       ZEND_HASH_FILL_NEXT();
                                        p++;
                                        i++;
                                }
@@ -8605,10 +8606,11 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
                                        if (Z_OPT_REFCOUNTED_P(q)) {
                                                Z_ADDREF_P(q);
                                        }
+                                       ZEND_HASH_FILL_SET(q);
                                } else {
-                                       q = &EG(uninitialized_zval);
+                                       ZEND_HASH_FILL_SET_NULL();
                                }
-                               ZEND_HASH_FILL_ADD(q);
+                               ZEND_HASH_FILL_NEXT();
                                p++;
                                i++;
                        }
index 26bd027f3fc4ba8052022ca5334cba73514e207b..89b36bde88e689bf7a2a86c28cdcce8c6fbdf7b9 100644 (file)
@@ -9757,10 +9757,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
                                                if (Z_OPT_REFCOUNTED_P(q)) {
                                                        Z_ADDREF_P(q);
                                                }
+                                               ZEND_HASH_FILL_SET(q);
                                        } else {
-                                               q = &EG(uninitialized_zval);
+                                               ZEND_HASH_FILL_SET_NULL();
                                        }
-                                       ZEND_HASH_FILL_ADD(q);
+                                       ZEND_HASH_FILL_NEXT();
                                        p++;
                                        i++;
                                }
@@ -9778,10 +9779,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
                                        if (Z_OPT_REFCOUNTED_P(q)) {
                                                Z_ADDREF_P(q);
                                        }
+                                       ZEND_HASH_FILL_SET(q);
                                } else {
-                                       q = &EG(uninitialized_zval);
+                                       ZEND_HASH_FILL_SET_NULL();
                                }
-                               ZEND_HASH_FILL_ADD(q);
+                               ZEND_HASH_FILL_NEXT();
                                p++;
                                i++;
                        }
@@ -37107,10 +37109,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
                                                if (Z_OPT_REFCOUNTED_P(q)) {
                                                        Z_ADDREF_P(q);
                                                }
+                                               ZEND_HASH_FILL_SET(q);
                                        } else {
-                                               q = &EG(uninitialized_zval);
+                                               ZEND_HASH_FILL_SET_NULL();
                                        }
-                                       ZEND_HASH_FILL_ADD(q);
+                                       ZEND_HASH_FILL_NEXT();
                                        p++;
                                        i++;
                                }
@@ -37128,10 +37131,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
                                        if (Z_OPT_REFCOUNTED_P(q)) {
                                                Z_ADDREF_P(q);
                                        }
+                                       ZEND_HASH_FILL_SET(q);
                                } else {
-                                       q = &EG(uninitialized_zval);
+                                       ZEND_HASH_FILL_SET_NULL();
                                }
-                               ZEND_HASH_FILL_ADD(q);
+                               ZEND_HASH_FILL_NEXT();
                                p++;
                                i++;
                        }
index 652a6598770c24c7434bf0ae7879aabdf8c4ab9f..5448a1815d33fbf9e23475efa40f2410a4873b27 100644 (file)
@@ -2790,8 +2790,8 @@ PHP_FUNCTION(range)
                        zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (; low >= high; low -= (unsigned int)lstep) {
-                                       ZVAL_INTERNED_STR(&tmp, ZSTR_CHAR(low));
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low));
+                                       ZEND_HASH_FILL_NEXT();
                                        if (((signed int)low - lstep) < 0) {
                                                break;
                                        }
@@ -2806,8 +2806,8 @@ PHP_FUNCTION(range)
                        zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (; low <= high; low += (unsigned int)lstep) {
-                                       ZVAL_INTERNED_STR(&tmp, ZSTR_CHAR(low));
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low));
+                                       ZEND_HASH_FILL_NEXT();
                                        if (((signed int)low + lstep) > 255) {
                                                break;
                                        }
@@ -2830,7 +2830,6 @@ double_str:
                        RETURN_FALSE;
                }
 
-               Z_TYPE_INFO(tmp) = IS_DOUBLE;
                if (low > high) {               /* Negative steps */
                        if (low - high < step || step <= 0) {
                                err = 1;
@@ -2841,8 +2840,8 @@ double_str:
 
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (i = 0, element = low; i < size && element >= high; ++i, element = low - (i * step)) {
-                                       Z_DVAL(tmp) = element;
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_DOUBLE(element);
+                                       ZEND_HASH_FILL_NEXT();
                                }
                        } ZEND_HASH_FILL_END();
                } else if (high > low) {        /* Positive steps */
@@ -2855,13 +2854,13 @@ double_str:
 
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (i = 0, element = low; i < size && element <= high; ++i, element = low + (i * step)) {
-                                       Z_DVAL(tmp) = element;
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_DOUBLE(element);
+                                       ZEND_HASH_FILL_NEXT();
                                }
                        } ZEND_HASH_FILL_END();
                } else {
                        array_init(return_value);
-                       Z_DVAL(tmp) = low;
+                       ZVAL_DOUBLE(&tmp, low);
                        zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                }
        } else {
@@ -2884,7 +2883,6 @@ long_str:
                        goto err;
                }
 
-               Z_TYPE_INFO(tmp) = IS_LONG;
                if (low > high) {               /* Negative steps */
                        if ((zend_ulong)(low - high) < lstep) {
                                err = 1;
@@ -2895,8 +2893,8 @@ long_str:
 
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (i = 0; i < size; ++i) {
-                                       Z_LVAL(tmp) = low - (i * lstep);
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_LONG(low - (i * lstep));
+                                       ZEND_HASH_FILL_NEXT();
                                }
                        } ZEND_HASH_FILL_END();
                } else if (high > low) {        /* Positive steps */
@@ -2909,13 +2907,13 @@ long_str:
 
                        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                                for (i = 0; i < size; ++i) {
-                                       Z_LVAL(tmp) = low + (i * lstep);
-                                       ZEND_HASH_FILL_ADD(&tmp);
+                                       ZEND_HASH_FILL_SET_LONG(low + (i * lstep));
+                                       ZEND_HASH_FILL_NEXT();
                                }
                        } ZEND_HASH_FILL_END();
                } else {
                        array_init(return_value);
-                       Z_LVAL(tmp) = low;
+                       ZVAL_LONG(&tmp, low);
                        zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                }
        }
@@ -3980,19 +3978,21 @@ PHP_FUNCTION(array_keys)
                ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
                        if (HT_IS_PACKED(arrval) && HT_IS_WITHOUT_HOLES(arrval)) {
                                /* Optimistic case: range(0..n-1) for vector-like packed array */
-                               ZVAL_LONG(&new_val, 0);
-                               for (; (zend_ulong)Z_LVAL(new_val) < elem_count; ++Z_LVAL(new_val)) {
-                                       ZEND_HASH_FILL_ADD(&new_val);
+                               zend_ulong lval = 0;
+
+                               for (; lval < elem_count; ++lval) {
+                                       ZEND_HASH_FILL_SET_LONG(lval);
+                                       ZEND_HASH_FILL_NEXT();
                                }
                        } else {
                                /* Go through input array and add keys to the return array */
                                ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(input), num_idx, str_idx, entry) {
                                        if (str_idx) {
-                                               ZVAL_STR_COPY(&new_val, str_idx);
+                                               ZEND_HASH_FILL_SET_STR_COPY(str_idx);
                                        } else {
-                                               ZVAL_LONG(&new_val, num_idx);
+                                               ZEND_HASH_FILL_SET_LONG(num_idx);
                                        }
-                                       ZEND_HASH_FILL_ADD(&new_val);
+                                       ZEND_HASH_FILL_NEXT();
                                } ZEND_HASH_FOREACH_END();
                        }
                } ZEND_HASH_FILL_END();
@@ -5900,17 +5900,16 @@ PHP_FUNCTION(array_rand)
 
        zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
        ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
-               zval zv;
                /* We can't use zend_hash_index_find()
                 * because the array may have string keys or gaps. */
                ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(input), num_key, string_key) {
                        if (zend_bitset_in(bitset, i) ^ negative_bitset) {
                                if (string_key) {
-                                       ZVAL_STR_COPY(&zv, string_key);
+                                       ZEND_HASH_FILL_SET_STR_COPY(string_key);
                                } else {
-                                       ZVAL_LONG(&zv, num_key);
+                                       ZEND_HASH_FILL_SET_LONG(num_key);
                                }
-                               ZEND_HASH_FILL_ADD(&zv);
+                               ZEND_HASH_FILL_NEXT();
                        }
                        i++;
                } ZEND_HASH_FOREACH_END();