Repository navigation
AOT: default-on helper-runtime TU cache for user phpc build (#15889) - #16948
Merged
Merged
Conversation
Enable split helper-unit compilation for user-script AOT builds: warm the per-unit cache once per core fingerprint, bind cached helpers via JitVmHelperLink, and log cache hits on stderr. Remove stray var_dump in JIT Context type resolution. Refresh examples benchmark table (~3s → ~1s bin/compile.php column). Co-authored-by: Cursor <cursoragent@cursor.com>
PurHur
added a commit
that referenced
this pull request
Jul 6, 2026
…helper cache (#16075 step 4) (#16992) * AOT: localize cached-unit declaration types + call-site-lazy sprintf link; document workflows in skills (#15642, #15889). Cache-machinery fixes (each independently load-bearing): - HelperRuntimeCache::tryProvide rebuilds extern declaration types against the LOCAL context's named structs. LLVM re-suffixes named structs on bitcode parse (__string__ -> __string__.12) and suffixed declaration types fail module verify at every call site — a latent correctness bug for ANY consumer whose module defines the structs before binding (getStringFromType cannot stringify suffixed structs, so the fallback read struct names via LLVMGetStructName). - StringFormat gains implementIfDeclared(): user-standalone builds skip ensureLinked at init (#13571), so printf()/sprintf()/ number_format() died at link with undefined __compiler_sprintf (#15642). JitSprintf::format now links on first call-site lowering (builder insert-point saved/restored), and ensureJitHelperCompiled consults the helper cache first — with PHP_COMPILER_HELPER_RUNTIME_O=1 the corpus binds as externs instead of a nested compile that OOMs a default-memory build. Remaining gap: cached units lack their init chains, so the sprintf unit crashes at runtime in user builds until per-unit llvm.global_ctors lands (epic #16075 step 4/5) — the link error is fixed, the runtime story is documented on #15642. - PackArgvSerialize memcpy calls adapt to WHATEVER signature the module already declares (main-script i8* vs runtime void* ordering flip). Spine sync to 4181/4182 (3 new fleet DOM files) + sidecar refresh (stamp d8ba2365). M5 fast green, AOT smoke green cache-on and -off, full unit sweep 119 fresh / 0 failed. Skills: phpc-verify gains the LLVM-assert debugging recipe, battery babysitter, and gate-order notes; phpc-fix-loop gains merge-race protocol, worktree-docker and vendor-patch guidance; phpc-selfhost gains spine-sync flags, dedup check, and the deferral workflow; new phpc-helper-cache skill documents the split-compilation cache end-to-end; phpc-setup documents the committed cold-start caches. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Merge follow-up: inventory regen. * AOT: per-unit init chains + runtime-safety guards for the default-on helper cache (#16075 step 4, #15889, #15642). The fleet flipped the helper cache default-on (#16948) while two latent hazards were live; this lands the missing infrastructure and contains the known-unsafe path: - Unit emission suffixes __init__/__shutdown__/__header_pre_flush__ per unit (PHP_COMPILER_INIT_SYMBOL_SUFFIX, recorded in the unit manifest). The colliding __init__ was -z muldefs-discarded and unit module state NEVER INITIALIZED — the root of the cached-unit runtime crash class. The consuming script's __init__ now calls each used unit's init explicitly (emitInInit at bind time). - Unit __shutdown__ is deliberately NOT wired: muldefs unifies part of the unit's globals with the script's, and running both shutdowns double-frees (SIGABRT at exit — caught by the AOT smoke). - Consumers skip units without an init symbol (pre-init-era manifests, including all previously committed prelinked units) and units marked runtime_safe=false. SprintfJitHelper is blocklisted: it constructs VM objects with class ids baked from the emitter process's registry, and the consuming script numbers classes differently — segfault in variablesFromPackedArgv (gdb data on #15642). Class-id unification is #16075 step 5. - JitSprintf's call-site StringFormat link (from #16965) is gated OFF during unit emission: the emitter guards the cache, so the hook was dragging a full nested corpus compile into every sprintf-adjacent unit (user builds spun ~10 min in auto-warm; Opendir unit hit it hardest). - prelinked/helper-runtime republished: 121 units with init symbols (34.8 MB). Verified: AOT smoke green (was SIGABRT 134 with shutdown wiring / spin before the gate), scalar+strlen differential AOT == VM with cache default-on, M5 fast green, sprintf unit emits in seconds again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: PurHur <tedyyyyy@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15889
Summary
phpc build(PHP_COMPILER_HELPER_RUNTIME_O=1when unset).build/helper-runtime-cache/once per core fingerprint before lowering the user script.phpc build: helper-runtime cache hit (...)on stderr when cached helpers bind.var_dump($type->getKind())inJIT\Context::getStringFromType()(was spammingint(10)during AOT builds).examples/README.mdbenchmark table (bin/compile.phpcolumn ~2.8–3.6s → ~0.99–1.23s).C runtime
No new C — reuses existing
HelperRuntimeCache+Linkermerge path. PHP-in-PHP helpers stay inlib//ext/; C remains thin ABI (lib/AOT/runtime/phpc_progress.c).Verification
Opt-out:
PHP_COMPILER_HELPER_RUNTIME_O=0.Made with Cursor