[php-src] PR #24331: zend_alloc: read the in-place limit of a small realloc from a table
| From: | marc-mabe | Date: | Wed, 14 Oct 2026 16:23:00 +0000 |
| Subject: | [php-src] PR #24331: zend_alloc: read the in-place limit of a small realloc from a table | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39429@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24331
Author: marc-mabe
Whether reallocating a small block keeps it in place was decided by old_bin_num > 0 &&
size <= bin_data_size[old_bin_num - 1], which needs a test of the bin number, an index
computation and a compare on every in-place reallocation.
Store the smallest size a block of each bin keeps in a table, bin_keep_size[], which is one more
than the size of the bin below, and 0 for the first bin, so the check becomes a single load and
compare. The behavior is unchanged.
As each entry comes from the row of the bin below, the table has one entry more than there are bins,
and the last one is unused. This does not grow the binary: the table is aligned to at least 16
bytes, so 30 entries (120 bytes) would be padded to 128 bytes anyway, and the extra 4 bytes fit into
that padding.
Mark the truncation as unexpected: a block reallocated to a smaller size usually stays in its bin.
Without the hint, GCC merges the epilogue of the in-place return with another return path, which
adds a branch to every in-place reallocation of a large run.
| Benchmark | arm64 | amd64 (emulated) | i386 (emulated) | arm32 (emulated) |
|---|---:|---:|---:|---:|
| Zend/bench.php | +0.000% (−0.0000%) | **−0.002%** (−0.0000%) | −0.000% (+0.0000%) |
−0.000% (+0.0000%) |
| Zend/bench.php JIT | +0.000% (+0.0000%) | **−0.008%** (−0.0000%) | not run | not run |
| Symfony Demo | **−0.023%** (+0.0000%) | **−0.019%** (+0.0000%) | **−0.003%** (+0.0000%) |
not run |
| Symfony Demo JIT | **−0.025%** (+0.0001%) | **−0.022%** (−0.0000%) | not run | not run |
| WordPress 6.2 | **−0.009%** (−0.0000%) | **−0.007%** (−0.0000%) | +0.001% (**−0.0047%**)
| not run |
| WordPress 6.2 JIT | **−0.007%** (+0.0085%) | **−0.007%** (+0.0010%) | not run | not run |
Instructions per request (callgrind) vs. master (first run).
in parentheses master vs. master as a run-to-run control.