Skip to content

Release blocker: committed helper-runtime cache is stale, so a clean checkout cannot compile hello world in 2 minutes #24302

Description

@PurHur

Summary

prelinked/helper-runtime/x86_64-linux/manifest.json carries a core_fingerprint that no longer
matches the live one. On mismatch every one of the 257 committed units is skipped, so a clean
checkout emits the whole helper corpus live on the first compile.

Measured on master today:

committed core_fingerprint: 34d6fd38281359f382b3
live coreFingerprint():     63e161964d00f30ff8c9

How it surfaced

The new compiler gate (#24275) failed on a GitHub runner, and the failure is informative:

=== nikic spine preflight (~18s) ===
bootstrap-spine-nikic-preflight: OK 6618/6618 spine PHP files parse
=== AOT smoke ===
FAIL  echo      compile failed (rc=124)
FAIL  arith     compile failed (rc=124)
...  (all 8 cases, rc=124 = timeout, 120s each)

rc=124 is my 120-second per-case timeout, not a compiler error. A GitHub runner starting from a
clean checkout cannot compile <?php echo "hi\n"; inside two minutes.

This is a real defect, not just a tight timeout

On this dev box the same script passes 8/8 in ~90 s total — because build/helper-runtime-cache is
warm here. That made my local timings unrepresentative of a clean checkout, which is the case a
user actually encounters.

What a fresh clone gets today: the committed cache exists, is skipped wholesale on the fingerprint
mismatch, and the first compile of any script pays for emitting the full corpus. This repo has
measured that cold path at >30 minutes for a trivial script before.

For a project heading to release, "clone and compile hello world" is close to the minimum bar, and
it is currently not met from a clean checkout.

Why it goes stale

The fingerprint covers the lowering machinery (lib/JIT.php, lib/Runtime.php, patches/, …) and
master merges roughly 4 commits/hour with ~56% touching those inputs. So the committed cache is
invalidated within hours of any refresh unless refreshing is part of the routine.

That is the same treadmill RELEASE-PLAN.md Phase 3 describes for gen-0 — an artifact keyed on a
fingerprint that changes several times a day. The difference is that refreshing this one is cheap:
the emit is parallel (PHP_COMPILER_EMIT_JOBS, ~4–5 min for the corpus) rather than the multi-hour
gen-0 rebuild, so it is tractable to keep current.

Suggested fixes

  1. Refresh the committed cache (make helper-runtime-prelink-refresh) — I am running this now
    and will PR the result with before/after timings.
  2. Gate on it. script/check-helper-runtime-prelink.php already exists but is report-only, and
    per its own comment an empty glob counts as clean. A fingerprint mismatch should be visible in
    release-readiness output rather than silently costing every user a full corpus emit.
  3. Consider making cold-build time a release criterion — "time to compile hello world from a
    clean checkout" is a number worth having in release-readiness --json, because it is exactly
    what a new user experiences and nothing currently measures it.

Environment: php-compiler:22.04-dev, PHP 8.2.32, LLVM 9, master 72c379a77.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions