You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Regression: wave-1 codegen changes made mandelbrot time out (0.44 s → > 60 s, 51 s of it in the kernel) and simple 2x slower (0.23 → 0.50 s) — the bench gate exists but has never run because master CI is red (benchmarks/mandelbrot.php, script/bench-gate.sh, lib/JIT.php) #36407
Regression: · generated-code performance, introduced between 4eed6a2785 and 1edb103c34 · child of #36379
Problem (pinned image, same box, outputs verified)
program
Zend
2026-09-01 4eed6a2785
2026-09-02 1edb103c34
benchmarks/mandelbrot.php
0.28 s
0.44 s
> 60 s (timeout), user 7.6 s / sys 51.4 s, plus false warnings (#36405)
benchmarks/simple.php
0.09 s
0.23 s
0.50 s
fibo(30)
0.13 s
0.125 s
0.041 s (improved; July: 0.015 s)
Ack(3,8)
0.16 s
0.16 s
0.066 s (improved)
2M untyped calls
0.09 s
0.575 s
0.643 s
51 s of system time on a float loop means the binary is thrashing the allocator/kernel — allocating and freeing (or faulting) per iteration — which points at the new dtor/{main} ownership path (#36215/#36252, one of which was partly reverted: "Fix AOT function-scoped array append segfault — revert broken delref dtor/GC CFG") or the __value__ layout change (#36214) interacting with float boxes. simple's regression is call overhead (three 1M-call loops).
script/bench-gate.sh (#36196) would have flagged both — it is wired into compiler-gate.yml, which has not had a green run on master in its last 60 attempts (#36377, #36401). A gate that never runs is a gate that does not exist; 131 commits merged over it in 24 h.
Category
Regression:· generated-code performance, introduced between4eed6a2785and1edb103c34· child of #36379Problem (pinned image, same box, outputs verified)
4eed6a27851edb103c34benchmarks/mandelbrot.phpbenchmarks/simple.phpfibo(30)Ack(3,8)51 s of system time on a float loop means the binary is thrashing the allocator/kernel — allocating and freeing (or faulting) per iteration — which points at the new dtor/
{main}ownership path (#36215/#36252, one of which was partly reverted: "Fix AOT function-scoped array append segfault — revert broken delref dtor/GC CFG") or the__value__layout change (#36214) interacting with float boxes.simple's regression is call overhead (three 1M-call loops).script/bench-gate.sh(#36196) would have flagged both — it is wired intocompiler-gate.yml, which has not had a green run on master in its last 60 attempts (#36377, #36401). A gate that never runs is a gate that does not exist; 131 commits merged over it in 24 h.PHP implementation target
{main}scope is O(n²) in time and memory — refcounts never decrement in main, soseparateContainerForWritecopies the whole table on every store (16k appends: 6.1 s in main vs 0.011 s inside a function) (lib/JIT/Builtin/Refcount.php phpc_destruct_delref_allowed, lib/JIT/HashTableWriteLlvm.php:1694) #36252, Runtime:__value__is 9 bytes / align 1 so every i64/double payload access is an over-aligned (UB) load, and packed arrays allocate 16 B/slot but stride 9 (lib/JIT/Builtin/Type/Value.php, lib/JIT/Builtin/Type/HashTable.php) #36214, Codegen: no LLVM pass ever runs at the default level — 40alwaysinlineruntime accessors stay real calls, MCJIT never optimises, and the per-function pass manager is mis-wired to a non-existent symbol (lib/JIT/Context.php runModuleOptimizationPasses, vendor/ircmaxell/php-llvm) #36213, Codegen: every boxed assignment open-codes a 15-block type switch with duplicated error blocks — 111k-line IR module and 51 KB helper functions for a 4-line script (lib/JIT/JitValueBox.php) #36193; name the commit in the PR.perf stat/strace -con the mandelbrot binary to confirm the syscall (brk/mmap/munmapper iteration?) before fixing.bench-gate.shmust be run locally and pasted in every PR touchinglib/JIT*,lib/AOT,ext/standard(CONTRIBUTING rule, enforced by Process: Definition of Done — a PR may say "Closes #N" only when every Done-when box is checked; otherwise "Part of #N"; PR template + a scope-check gate + a weekly "closed but not done" audit (CONTRIBUTING.md, .github/PULL_REQUEST_TEMPLATE.md, script/check-issue-close-scope.php) #36400's template).Repro
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/compile.php -o build/mb benchmarks/mandelbrot.php && time timeout 60 ./build/mb > /dev/null; php bin/compile.php -o build/sp benchmarks/simple.php && time ./build/sp'Done when
mandelbrot≤ 0.3 s andsimple≤ 0.25 s under AOT in the pinned image (bench-gate rows pasted); no stderr outputscript/differential-sweep.sh --aot --repeat 3unchanged