1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Commit Graph

1222 Commits

Author SHA1 Message Date
Gina Peter Banyard
31bd92d2dc ext/standard/array.c: refactor sort functions (#20462)
Consolidate userland functions to rely on a single implementation
Split get_comparison functions into a reverse and a normal one
Use bool type when applicable
2025-11-13 01:34:45 +00:00
Niels Dossche
b9562adff6 standard: Simplify array_chunk() (#20423) 2025-11-12 17:20:41 +01:00
Niels Dossche
5185d46ccc Fix zero-extension on range() char parameters 2025-11-11 00:01:38 +01:00
Niels Dossche
aafb8a6623 standard: Use booleans in array_merge() 2025-11-10 22:41:23 +01:00
Niels Dossche
e32c2c3e0b standard: Use RETURN_COPY()/RETVAL_ARR() in array_merge() 2025-11-10 22:41:23 +01:00
Niels Dossche
15b996348a standard: Use specialised macro in array_merge() 2025-11-10 22:41:23 +01:00
Niels Dossche
3e982a8d9d standard: Remove redundant code in range() (#20432)
If we use signed integers (which fit the unsigned chars), then we can
avoid the extra checks. Also move an exception check to the proper
place.
2025-11-10 22:41:14 +01:00
Niels Dossche
79adb01bfc array_map: Avoid allocation by using Z_EXTRA storage of parameters 2025-11-08 23:29:24 +01:00
Niels Dossche
60a0f107a4 array_map: Rely on VM to clean up in case of an exception
This makes the code more compact, and less weird: the stub doesn't
indicate that this function can return NULL.
2025-11-08 23:29:24 +01:00
Niels Dossche
9bf1240d9f array_map: Delay allocation of array_pos 2025-11-08 23:29:24 +01:00
Niels Dossche
080cf10268 array_map: Move fci configuration outside of loop 2025-11-08 23:29:24 +01:00
Niels Dossche
f4c3097059 array_map: Avoid needing refcounted copies and cleanup
Since this will be copied on the call frame, a refcounted copy is not
necessary.
2025-11-08 23:29:24 +01:00
Niels Dossche
376fdd7afa Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix memory leak in array_diff() with custom type checks
2025-11-08 22:42:33 +01:00
Niels Dossche
a0b918d3ee Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix memory leak in array_diff() with custom type checks
2025-11-08 22:42:26 +01:00
Niels Dossche
43b232a654 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix memory leak in array_diff() with custom type checks
2025-11-08 22:42:11 +01:00
Niels Dossche
80b731659a Fix memory leak in array_diff() with custom type checks
Closes GH-20428.
2025-11-08 22:41:44 +01:00
Niels Dossche
bc458e5d08 [ci skip] Remove misleading comment 2025-11-08 17:19:55 +01:00
Niels Dossche
877e758a3b array_unshift: Use specialised iteration macro (#20410)
Forgot this while working on GH-20353, but this could avoid some
checks depending on the compiler optimizations.
2025-11-06 23:36:43 +01:00
Niels Dossche
db8c331d07 array_unshift: Add fast optimized case for packed arrays (#20353)
Packed arrays are likely common in this case, as with array_shift which
already has a similar optimization.

For the following benchmark:
```php
<?php

for ($i = 0; $i < 10000000; $i++) {
    $a = [0, 1, 2, 3, 4, 5];
    array_unshift($a, -3, -2, -1);
}
```

On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
  Time (mean ± σ):     753.8 ms ±  23.8 ms    [User: 749.8 ms, System: 2.1 ms]
  Range (min … max):   734.3 ms … 818.6 ms    10 runs

Benchmark 2: ./sapi/cli/php_old x.php
  Time (mean ± σ):     972.5 ms ±   5.0 ms    [User: 968.8 ms, System: 1.4 ms]
  Range (min … max):   967.8 ms … 984.3 ms    10 runs

Summary
  ./sapi/cli/php x.php  ran
    1.29 ± 0.04 times faster than ./sapi/cli/php_old x.php
```
2025-11-06 18:49:23 +01:00
Niels Dossche
3f8dc377a3 Improve performance of array_walk() (#20322)
We never need to use refcounted copies for arguments because the copy to
the call frame already increments the refcount.

For the following benchmark:
```php
$a = range(0, 10);
for ($i = 0; $i < 1000000; $i++)
    array_walk($a, fn ($val, $idx, $arg) => $val + $arg, 2);
```

On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
  Time (mean ± σ):     593.0 ms ±   5.4 ms    [User: 589.8 ms, System: 1.7 ms]
  Range (min … max):   583.3 ms … 600.9 ms    10 runs

Benchmark 2: ./sapi/cli/php_old x.php
  Time (mean ± σ):     637.8 ms ±   4.6 ms    [User: 633.9 ms, System: 2.2 ms]
  Range (min … max):   633.4 ms … 649.2 ms    10 runs

Summary
  ./sapi/cli/php x.php ran
    1.08 ± 0.01 times faster than ./sapi/cli/php_old x.php
```

On an i7-1185G7:
```
Benchmark 1: ./sapi/cli/php x.php
  Time (mean ± σ):     362.3 ms ±   2.0 ms    [User: 359.9 ms, System: 1.9 ms]
  Range (min … max):   359.6 ms … 367.1 ms    10 runs

Benchmark 2: ./sapi/cli/php_old x.php
  Time (mean ± σ):     385.5 ms ±   1.8 ms    [User: 383.2 ms, System: 1.9 ms]
  Range (min … max):   381.5 ms … 387.2 ms    10 runs

Summary
  ./sapi/cli/php x.php ran
    1.06 ± 0.01 times faster than ./sapi/cli/php_old x.php
```
2025-11-04 21:38:38 +01:00
Niels Dossche
7b6b233ce8 Optimize array_fill_keys() (#20347)
Move the refcount update outside of the loop.

For the following benchmark:
```php
$r = range(0, 1000);
$v = new stdClass();

for ($i = 0; $i < 100000; $i++) {
    array_fill_keys($r, $v);
}
```

On an i7-4790:
```
Benchmark 1: ./sapi/cli/php_old ../x.php
  Time (mean ± σ):     507.5 ms ±   4.8 ms    [User: 505.1 ms, System: 1.2 ms]
  Range (min … max):   501.2 ms … 518.4 ms    10 runs

Benchmark 2: ./sapi/cli/php ../x.php
  Time (mean ± σ):     479.8 ms ±   3.1 ms    [User: 476.8 ms, System: 1.8 ms]
  Range (min … max):   475.0 ms … 486.7 ms    10 runs

Summary
  ./sapi/cli/php ../x.php ran
    1.06 ± 0.01 times faster than ./sapi/cli/php_old ../x.php
```

On an i7-1185G7:
```
Benchmark 1: ./sapi/cli/php x.php
  Time (mean ± σ):     343.9 ms ±   3.1 ms    [User: 341.1 ms, System: 2.3 ms]
  Range (min … max):   337.9 ms … 347.8 ms    10 runs

Benchmark 2: ./sapi/cli/php_old x.php
  Time (mean ± σ):     357.8 ms ±   2.3 ms    [User: 355.7 ms, System: 1.6 ms]
  Range (min … max):   355.0 ms … 362.6 ms    10 runs

Summary
  ./sapi/cli/php x.php ran
    1.04 ± 0.01 times faster than ./sapi/cli/php_old x.php
```
2025-11-03 22:35:26 +01:00
Alexandre Daubois
4858cfa9ca Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-19926: reset internal pointer earlier while splicing array while COW violation flag is still set (#19929)
2025-10-06 16:54:37 +02:00
Alexandre Daubois
b40e479e39 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-19926: reset internal pointer earlier while splicing array while COW violation flag is still set (#19929)
2025-10-06 16:53:45 +02:00
Alexandre Daubois
2cc4532865 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-19926: reset internal pointer earlier while splicing array while COW violation flag is still set (#19929)
2025-10-06 16:52:50 +02:00
Alexandre Daubois
64c1d43b68 Fix GH-19926: reset internal pointer earlier while splicing array while COW violation flag is still set (#19929) 2025-10-06 16:51:23 +02:00
Niels Dossche
6cde784838 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-20043: array_unique assertion failure with RC1 array causing an exception on sort
2025-10-05 20:16:18 +02:00
Niels Dossche
1f809a55cf Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-20043: array_unique assertion failure with RC1 array causing an exception on sort
2025-10-05 20:16:12 +02:00
Niels Dossche
f2f84e36eb Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-20043: array_unique assertion failure with RC1 array causing an exception on sort
2025-10-05 20:15:55 +02:00
Niels Dossche
4fed57e746 Fix GH-20043: array_unique assertion failure with RC1 array causing an exception on sort
The reason this happens is because the array_unique operation happens in-place
because the input array is RC1.
At one point during comparison an exception is thrown which will capture the
arguments in the backtrace, which will increment the refcount of the RC1 array
to 2. Then a modification happens after the throw on the RC2 array causing the
assertion failure.
We shouldn't try continue work after an exception happened during the sort.

Closes GH-20059.
2025-10-05 20:15:28 +02:00
Tim Düsterhus
827c24b33f standard: Use true / false instead of 1 / 0 for bool parameters
Changes done with Coccinelle:

    @r1@
    identifier F;
    identifier p;
    typedef bool;
    parameter list [n1] PL1;
    parameter list [n2] PL2;
    @@

    F(PL1, bool p, PL2) {
    ...
    }

    @r2@
    identifier r1.F;
    expression list [r1.n1] EL1;
    expression list [r1.n2] EL2;
    @@

    F(EL1,
    (
    - 1
    + true
    |
    - 0
    + false
    )
    , EL2)
2025-09-24 18:51:40 +02:00
Tim Düsterhus
220d7a84b5 standard: Use true / false instead of 1 / 0 when assigning to bool
Changes done with Coccinelle:

    @@
    bool b;
    @@

    - b = 0
    + b = false

    @@
    bool b;
    @@

    - b = 1
    + b = true
2025-09-24 18:51:40 +02:00
Gina Peter Banyard
b4ed215299 core: Warn when non-representable floats are coerced to int (#19760)
RFC: https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int
2025-09-21 23:53:16 +01:00
Alexandre Daubois
49e3956b70 core: Deprecate using null as an array offset and when calling array_key_exists() (#19511)
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_using_values_null_as_an_array_offset_and_when_calling_array_key_exists
2025-09-04 22:12:24 +01:00
Ilija Tovilo
fd8dfe1bfd Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix GH-16649: Avoid UAF when using array_splice
2025-08-13 14:16:50 +02:00
Ilija Tovilo
7e01cf59bb Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-16649: Avoid UAF when using array_splice
2025-08-13 14:16:12 +02:00
Alexandre Daubois
c8774f9e61 Fix GH-16649: Avoid UAF when using array_splice
Closes GH-19399
2025-08-13 14:15:34 +02:00
Niels Dossche
cee8ed235a Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix GH-19300: Nested array_multisort invocation with error breaks
2025-07-31 19:01:28 +02:00
Niels Dossche
b82c8ba7fe Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-19300: Nested array_multisort invocation with error breaks
2025-07-31 19:01:13 +02:00
Niels Dossche
a96b05e63f Fix GH-19300: Nested array_multisort invocation with error breaks
There are 2 issues:
1. When a MULTISORT_ABORT happens, it frees func, but func may point to
   ARRAYG(multisort_func), which would be a problem with nested
   invocations as it can destroy that of the "parent" invocation.
   To solve this, delay assigning to the globals.
2. The old globals were not restored which means that nested invocations
   with different flags will cause a wrong sorting function to be used.

Closes GH-19319.
2025-07-31 19:00:45 +02:00
Niels Dossche
1b169bf28e Allocate array eagerly in array_chunk
By preallocating it as a packed array, we save the initial
initialization overhead.
Gives a few extra percentage points improvement.
2025-07-21 22:59:55 +02:00
Niels Dossche
4762d46427 Avoid modulo operation in loop in array_chunk
For this benchmark:
```php
$length = 25;
for ($i=0;$i<1000;$i++)
  array_chunk(range(0, 10000), $length);
```

On an i7-4790, length=25 speeds up by 1.8x and length=1 by 1.27x.
On an i7-1185G7, length=25 speeds up by 1.08x and length=1 by 1.02x.
2025-07-21 22:59:55 +02:00
Niels Dossche
168343d2e8 [RFC] Implement array_first() and array_last() (#18210) 2025-05-07 08:15:50 +02:00
David Carlier
e80d9535d7 Merge branch 'PHP-8.4' 2025-05-04 14:15:32 +01:00
David Carlier
2e2077172d Merge branch 'PHP-8.3' into PHP-8.4 2025-05-04 14:15:05 +01:00
David Carlier
8a585856d1 Fix GH-18480: array_splice overflow on array length with offset.
close GH-18483
2025-05-04 14:14:22 +01:00
Niels Dossche
ea387fcfb7 Avoid useless initializations of fci/fcc in array functions (#18273)
These cause cache misses due to global access, in phpstan
(notably the array_map).
Initializing these isn't necessary because ZPP initializes it for us.
Only for optional arguments do we need to be careful; for `array_filter`
we still reset the `fci` but not `fci_cache` because `fci` is not
necessarily set by ZPP but is conditionally used to access `fci_cache`.
2025-04-15 23:08:12 +02:00
Ilija Tovilo
e4e663ced4 Merge branch 'PHP-8.4'
* PHP-8.4:
  Use-after-free in extract() with EXTR_REFS
2025-04-01 16:34:41 +02:00
Ilija Tovilo
3ffb310fbd Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Use-after-free in extract() with EXTR_REFS
2025-04-01 16:34:33 +02:00
Ilija Tovilo
a21065e6eb Use-after-free in extract() with EXTR_REFS
Fixes GH-18209
Closes GH-18211
2025-04-01 16:33:30 +02:00
Niels Dossche
d456d25a1c Get rid of temporary in array_push (#18181)
This only makes a very very small improvement in performance, but the
code size on x86-64 decreases from 357 bytes to 296 bytes.
2025-03-29 22:46:08 +01:00