From: Dmitry Stogov Date: Tue, 28 May 2019 10:35:00 +0000 (+0300) Subject: Avoid double copying X-Git-Tag: php-7.4.0alpha1~175 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2cb6a4a275281156b0fedbe3dcd8835be31933a;p=php Avoid double copying --- diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 5fc69c24bf..5333e3e315 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -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++; } diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 3341427428..166a9b2d6c 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -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; \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 50ce8c1e92..6a57beccb1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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++; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 26bd027f3f..89b36bde88 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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++; } diff --git a/ext/standard/array.c b/ext/standard/array.c index 652a659877..5448a1815d 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -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();