summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-05-28 13:35:29 +0300
committerDmitry Stogov <dmitry@zend.com>2019-05-28 13:35:29 +0300
commitc64fe84f8b7abd260adf36074d091ba9d58b2670 (patch)
treebf454b862aa1b90eaf550f8836496d8824d54802
parentd95c15e3717ad909a3e4736c4e26ee7a9331d7e1 (diff)
parentb2cb6a4a275281156b0fedbe3dcd8835be31933a (diff)
downloadphp-git-c64fe84f8b7abd260adf36074d091ba9d58b2670.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: Avoid double copying
-rw-r--r--Zend/zend_builtin_functions.c25
-rw-r--r--Zend/zend_hash.h29
-rw-r--r--Zend/zend_vm_def.h10
-rw-r--r--Zend/zend_vm_execute.h20
-rw-r--r--ext/standard/array.c51
5 files changed, 85 insertions, 50 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 1285865d82..87928e8b2b 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -527,10 +527,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++;
}
@@ -543,10 +544,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++;
}
@@ -1940,10 +1942,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 {
@@ -1952,10 +1955,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++;
}
@@ -1968,10 +1972,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 1fd4a146d6..4f6430c61b 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 6c2cfb7d73..8e3c9e4dfc 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -8646,10 +8646,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++;
}
@@ -8667,10 +8668,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 1f6719b1ca..71487b713d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -9753,10 +9753,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++;
}
@@ -9774,10 +9775,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++;
}
@@ -37706,10 +37708,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++;
}
@@ -37727,10 +37730,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 02f25f175c..ce74f94b1a 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -2779,8 +2779,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;
}
@@ -2795,8 +2795,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;
}
@@ -2819,7 +2819,6 @@ double_str:
RETURN_FALSE;
}
- Z_TYPE_INFO(tmp) = IS_DOUBLE;
if (low > high) { /* Negative steps */
if (low - high < step || step <= 0) {
err = 1;
@@ -2830,8 +2829,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 */
@@ -2844,13 +2843,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 {
@@ -2873,7 +2872,6 @@ long_str:
goto err;
}
- Z_TYPE_INFO(tmp) = IS_LONG;
if (low > high) { /* Negative steps */
if ((zend_ulong)(low - high) < lstep) {
err = 1;
@@ -2884,8 +2882,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 */
@@ -2898,13 +2896,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);
}
}
@@ -3967,19 +3965,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();
@@ -5891,17 +5891,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();