@@ -91,6 +91,11 @@ PHP_MSHUTDOWN_FUNCTION(array) /* {{{ */
91
91
}
92
92
/* }}} */
93
93
94
+ static zend_always_inline bool zend_may_modify_array_in_place (const zval * arg )
95
+ {
96
+ return !(GC_FLAGS (Z_ARRVAL_P (arg )) & (IS_ARRAY_IMMUTABLE | IS_ARRAY_PERSISTENT )) && Z_REFCOUNT_P (arg ) == 1 ;
97
+ }
98
+
94
99
static zend_never_inline ZEND_COLD int stable_sort_fallback (Bucket * a , Bucket * b ) {
95
100
if (Z_EXTRA (a -> val ) > Z_EXTRA (b -> val )) {
96
101
return 1 ;
@@ -3949,7 +3954,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
3949
3954
/* copy first array if necessary */
3950
3955
if (HT_IS_PACKED (src )) {
3951
3956
/* Note: If it has holes, it might get sequentialized */
3952
- if (HT_IS_WITHOUT_HOLES (src ) && !( GC_FLAGS ( Z_ARRVAL_P ( arg )) & ( IS_ARRAY_IMMUTABLE | IS_ARRAY_PERSISTENT )) && Z_REFCOUNT_P ( arg ) == 1 ) {
3957
+ if (HT_IS_WITHOUT_HOLES (src ) && zend_may_modify_array_in_place ( arg )) {
3953
3958
dest = src ;
3954
3959
in_place = true;
3955
3960
ZVAL_ARR (return_value , dest );
@@ -4001,7 +4006,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
4001
4006
}
4002
4007
4003
4008
if (in_place ) {
4004
- GC_ADDREF (Z_ARRVAL_P ( return_value ) );
4009
+ GC_ADDREF (dest );
4005
4010
}
4006
4011
//fprintf(stderr, "after, in-place %d %d\n", in_place, GC_REFCOUNT(Z_ARRVAL_P(return_value)));
4007
4012
}
@@ -4611,7 +4616,11 @@ PHP_FUNCTION(array_unique)
4611
4616
4612
4617
cmp = php_get_data_compare_func_unstable (sort_type , 0 );
4613
4618
4614
- RETVAL_ARR (zend_array_dup (Z_ARRVAL_P (array )));
4619
+ if (zend_may_modify_array_in_place (array )) {
4620
+ RETVAL_ARR (zend_array_dup (Z_ARRVAL_P (array )));
4621
+ } else {
4622
+ RETVAL_ARR (Z_ARRVAL_P (array ));
4623
+ }
4615
4624
4616
4625
/* create and sort array with pointers to the target_hash buckets */
4617
4626
arTmp = pemalloc ((Z_ARRVAL_P (array )-> nNumOfElements + 1 ) * sizeof (struct bucketindex ), GC_FLAGS (Z_ARRVAL_P (array )) & IS_ARRAY_PERSISTENT );
@@ -4907,8 +4916,12 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
4907
4916
}
4908
4917
}
4909
4918
4910
- /* copy the argument array */
4911
- RETVAL_ARR (zend_array_dup (Z_ARRVAL (args [0 ])));
4919
+ /* copy the argument array if necessary */
4920
+ if (zend_may_modify_array_in_place (& args [0 ])) {
4921
+ RETVAL_ARR (zend_array_dup (Z_ARRVAL_P (& args [0 ])));
4922
+ } else {
4923
+ RETVAL_ARR (Z_ARRVAL_P (& args [0 ]));
4924
+ }
4912
4925
4913
4926
/* go through the lists and look for common values */
4914
4927
while (Z_TYPE (ptrs [0 ]-> val ) != IS_UNDEF ) {
0 commit comments