diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 791c26bc..12db728d 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -125,25 +125,31 @@ items 8-9. Run on **BOTH Mac AND Ubuntu x86_64**. No skipping. 9. **versions.lock ↔ flake.nix consistency**: `bash scripts/sync-versions.sh` exits 0. Run automatically by `gate-merge.sh` and by the CI `versions-lock-sync` job. -10. **Local bench record on Mac, every merge**: after the PR is squash-merged +10. **Local bench record, every merge**: after the PR is squash-merged and main is checked out (`git checkout main && git pull --ff-only`), `bash scripts/record-merge-bench.sh` appends one row to - `bench/history.yaml` keyed on the merge commit SHA. Always full - hyperfine (5 runs + 3 warmup, ~5 min) — `bench/history.yaml` is the - canonical Mac M4 Pro absolute-time baseline used at tag time, so - every entry must be measurement-grade. Lower run/warmup counts are - only for `bench/run_bench.sh --quick`'s interactive smoke tests, not - for durable history. Skipped automatically on Linux/Windows because - the file's `env:` block is Darwin-only. Commit the resulting + `bench/history.yaml` keyed on the (merge SHA, target triple) pair. + Always full hyperfine (5 runs + 3 warmup, ~5 min) — + `bench/history.yaml` is the canonical absolute-time baseline used + at tag time, so every entry must be measurement-grade. Lower + run/warmup counts are only for `bench/run_bench.sh --quick`'s + interactive smoke tests, not for durable history. Multi-arch + (C-g, 2026-04-29): the script auto-detects `aarch64-darwin` / + `x86_64-linux` / `x86_64-windows` from `uname -s -m` and tags the + entry's `arch:` field accordingly; aarch64-darwin remains the + primary tag-time baseline, but Linux/Windows rows are encouraged + so cross-platform regressions surface early. Commit the resulting `history.yaml` change directly to main as a follow-up - `Record benchmark for ` commit; CI runs but is not gating - for that small commit. + `Record benchmark for ` commit; CI runs but is not + gating for that small commit. CI Linux runners separately enforce a soft regression check (`bench/ci_compare.sh --base=origin/main --threshold=20 --runs=3 ---warmup=1` on PR, `continue-on-error: true`) — Ubuntu-vs-Ubuntu, never -mixed with the Mac history. Treat the two baselines as independent -artefacts, not as values to compare against each other. +--warmup=1` on PR, `continue-on-error: true`) — Ubuntu-vs-Ubuntu only, +the comparison is fresh-measured on the same runner. Compare entries +in `bench/history.yaml` only within a single `arch:` series; the three +target triples are independent artefacts, not values to compare +against each other. Items 1-6 must pass on BOTH platforms before merge. Run them in parallel: Mac items can run locally, Ubuntu items via `orb run -m my-ubuntu-amd64`. diff --git a/bench/history.yaml b/bench/history.yaml index c97febc4..0f506d5e 100644 --- a/bench/history.yaml +++ b/bench/history.yaml @@ -6,11 +6,13 @@ env: ram: 48 GB os: Darwin 25.2.0 tool: hyperfine + arch: aarch64-darwin entries: - id: "3.6" date: "2026-02-11" reason: "Baseline with all shootout (excl ed25519)" commit: "634f6e0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 430.2} @@ -33,6 +35,7 @@ entries: date: "2026-02-11" reason: "ARM64 function-level JIT: division, memory, rotation, CLZ/CTZ, select, sign-ext" commit: "cb82f94" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 338.8} @@ -55,6 +58,7 @@ entries: date: "2026-02-11" reason: "Tiered execution: back-edge counting + lower call threshold" commit: "2e9fb74" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 331.0} @@ -77,6 +81,7 @@ entries: date: "2026-02-11" reason: "JIT call optimization: fast JIT-to-JIT path" commit: "d6fecb7" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 234.4} @@ -99,6 +104,7 @@ entries: date: "2026-02-11" reason: "JIT code quality: direct dest reg, selective reload, shared error epilogue" commit: "8e47ed0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 223.6} @@ -121,6 +127,7 @@ entries: date: "2026-02-11" reason: "Inline self-call with cached reg_ptr addr" commit: "377a73e" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 119.3} @@ -143,6 +150,7 @@ entries: date: "2026-02-11" reason: "Spill-only-needed: caller-saved + arg vregs only" commit: "6db9491" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 103.0} @@ -165,6 +173,7 @@ entries: date: "2026-02-11" reason: "Inline self-call for memory functions" commit: "a3722b1" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 102.7} @@ -187,6 +196,7 @@ entries: date: "2026-02-11" reason: "doCallDirectIR regIR/JIT fast path for shootout callees" commit: "f5cc138" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 103.2} @@ -209,6 +219,7 @@ entries: date: "2026-02-11" reason: "f64 ARM64 JIT codegen" commit: "24b3820" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 103.3} @@ -231,6 +242,7 @@ entries: date: "2026-02-11" reason: "Stage 5 final — f64 JIT, regIR expansion" commit: "4dbb26e" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 115.8} @@ -253,6 +265,7 @@ entries: date: "2026-02-11" reason: "Benchmark expansion (21 benchmarks)" commit: "9863277" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 110.5} @@ -280,6 +293,7 @@ entries: date: "2026-02-12" reason: "Reg reuse, 14 phys regs, const-addr elision, write-tracked spills" commit: "093c524" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 98.4} @@ -307,6 +321,7 @@ entries: date: "2026-02-12" reason: "SCRATCH/FP caches, inline call opts, peephole" commit: "6e9568a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 97.2} @@ -334,6 +349,7 @@ entries: date: "2026-02-12" reason: "Stage 7 start: limits i64 decoding" commit: "b80674c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 95.2} @@ -361,6 +377,7 @@ entries: date: "2026-02-12" reason: "Stage 7 complete: memory64 table operations" commit: "b081800" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 94.1} @@ -388,6 +405,7 @@ entries: date: "2026-02-12" reason: "Stage 12 complete: WAT parser + validateBodyEnd + E2E 100%" commit: "c467105" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 97.7} @@ -415,6 +433,7 @@ entries: date: "2026-02-12" reason: "Stage 13 complete" commit: "76c0540" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 97.0} @@ -442,6 +461,7 @@ entries: date: "2026-02-12" reason: "Stage 14 complete" commit: "ece72a9" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 96.9} @@ -469,6 +489,7 @@ entries: date: "2026-02-12" reason: "Stage 15 baseline (multi-memory)" commit: "c886849" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 93.9} @@ -496,6 +517,7 @@ entries: date: "2026-02-12" reason: "Stage 15 complete (multi-memory)" commit: "accb90c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 94.3} @@ -523,6 +545,7 @@ entries: date: "2026-02-12" reason: "Stage 16 relaxed SIMD complete" commit: "5054aee" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 95.9} @@ -550,6 +573,7 @@ entries: date: "2026-02-12" reason: "Release v0.13.0" commit: "c383d45" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 90.9} @@ -577,6 +601,7 @@ entries: date: "2026-02-13" reason: "Stage 16V complete: spec validation coverage" commit: "2c1011f" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 88.4} @@ -604,6 +629,7 @@ entries: date: "2026-02-13" reason: "Stage 17 (Function References) complete" commit: "9b7a6be" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 92.9} @@ -631,6 +657,7 @@ entries: date: "2026-02-13" reason: "Stage 18 GC complete" commit: "1dd02fe" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 95.6} @@ -658,6 +685,7 @@ entries: date: "2026-02-13" reason: "Pre-v0.1.0 full benchmark" commit: "bf326f0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 88.7} @@ -685,6 +713,7 @@ entries: date: "2026-02-14" reason: "Stage 22 complete" commit: "f2a6dc0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 96.4} @@ -712,6 +741,7 @@ entries: date: "2026-02-14" reason: "Pre-v0.2.0 tag: Stages 20-22 complete" commit: "58cbb58" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 93.0} @@ -739,6 +769,7 @@ entries: date: "2026-02-14" reason: "Liveness-aware spill/reload" commit: "6efe779" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 93.4} @@ -766,6 +797,7 @@ entries: date: "2026-02-14" reason: "Guard pages for bounds check elimination" commit: "853fbe3" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 96.1} @@ -793,6 +825,7 @@ entries: date: "2026-02-14" reason: "Stage 23.5 measure and tune complete" commit: "16f9a18" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 90.6} @@ -820,6 +853,7 @@ entries: date: "2026-02-14" reason: "lightweight self-call" commit: "5effc85" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.5} @@ -847,6 +881,7 @@ entries: date: "2026-02-15" reason: "Stage 26 peephole (fusion+MOVN, OP_MOV reverted)" commit: "162d84c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 59.0} @@ -874,6 +909,7 @@ entries: date: "2026-02-16" reason: "Stage 28 complete: spec fix batch + x86 JIT call spill" commit: "086779c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.7} @@ -901,6 +937,7 @@ entries: date: "2026-02-16" reason: "Stage 29 complete: threads" commit: "8dcc1f3" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.0} @@ -928,6 +965,7 @@ entries: date: "2026-02-16" reason: "Stage 30 complete: perf gap analysis + u16 regs + MAX_PHYS_REGS 23" commit: "90de63e" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.1} @@ -955,6 +993,7 @@ entries: date: "2026-02-16" reason: "Add GC benchmarks (gc_alloc, gc_tree)" commit: "97b2332" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.5} @@ -984,6 +1023,7 @@ entries: date: "2026-02-16" reason: "GC arena + adaptive threshold (D121)" commit: "87f3a1f" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.1} @@ -1013,6 +1053,7 @@ entries: date: "2026-02-16" reason: "v1.0.0 release baseline" commit: "1f4b215" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.9} @@ -1042,6 +1083,7 @@ entries: date: "2026-02-18" reason: "Stage 44 complete" commit: "3784802" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.2} @@ -1071,6 +1113,7 @@ entries: date: "2026-02-18" reason: "Stage 45 complete: SIMD performance engineering" commit: "1b90d00" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.9} @@ -1100,6 +1143,7 @@ entries: date: "2026-02-18" reason: "v1.1.0 release" commit: "318365a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 52.7} @@ -1129,6 +1173,7 @@ entries: date: "2026-02-26" reason: "Add real-world benchmark layer and fair benchmark defaults" commit: "b39b828" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 59.7} @@ -1164,6 +1209,7 @@ entries: date: "2026-02-26" reason: "Revise reliability plan: zero tolerance, experiment-first, context efficiency" commit: "7531200" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 55.1} @@ -1199,6 +1245,7 @@ entries: date: "2026-02-26" reason: "Add validation + import type checking to E2E runner (I.1, I.2)" commit: "b658a41" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 60.1} @@ -1234,6 +1281,7 @@ entries: date: "2026-02-26" reason: "Fix memory64 bulk ops and import is_64 checking (I.3, I.6)" commit: "eec6fa4" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 64.3} @@ -1269,6 +1317,7 @@ entries: date: "2026-02-26" reason: "Fix GC array alloc limit and externref encoding in E2E runner (I.4, I.5)" commit: "589a4db" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 59.3} @@ -1304,6 +1353,7 @@ entries: date: "2026-02-26" reason: "Add thread/wait command support to E2E runner (I.7)" commit: "9dc57c0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.2} @@ -1339,6 +1389,7 @@ entries: date: "2026-02-26" reason: "Update handover: I.1-I.7 complete, E2E 792/792 (100%)" commit: "6752fde" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.6} @@ -1374,6 +1425,7 @@ entries: date: "2026-02-26" reason: "Fix JIT FP precision: getOrLoad must check dirty FP cache first (I.0)" commit: "be466a0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 59.9} @@ -1409,6 +1461,7 @@ entries: date: "2026-02-26" reason: "Update handover: Phase I complete, FP precision fixed" commit: "465146a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 56.6} @@ -1444,6 +1497,7 @@ entries: date: "2026-02-26" reason: "Add x86 JIT division safety: zero check, overflow, signed rem fixup" commit: "61e1c4d" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.1} @@ -1479,6 +1533,7 @@ entries: date: "2026-02-26" reason: "Fix x86 JIT register clobbering in division and ABI call setup" commit: "a93d4ab" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 61.1} @@ -1514,6 +1569,7 @@ entries: date: "2026-02-26" reason: "Fix x86 JIT SCRATCH2/vreg10 register alias: reserve R11 for scratch only" commit: "9ec9434" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 60.5} @@ -1549,6 +1605,7 @@ entries: date: "2026-02-26" reason: "Fix call liveness analysis: treat rd as USE for return/store/branch" commit: "bad86de" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 59.5} @@ -1584,6 +1641,7 @@ entries: date: "2026-02-26" reason: "Update handover: Phase J complete, all x86 JIT bugs fixed" commit: "be29897" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 56.1} @@ -1619,6 +1677,7 @@ entries: date: "2026-02-26" reason: "Add select, br_table, trunc_sat JIT opcodes for ARM64 and x86_64" commit: "22859e2" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 62.2} @@ -1654,6 +1713,7 @@ entries: date: "2026-02-26" reason: "Clarify W34 reentry guard comment: needs OSR for optimization" commit: "c01aa39" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 60.6} @@ -1689,6 +1749,7 @@ entries: date: "2026-02-26" reason: "Add ARM64 JIT optimizations: FP-direct load/store, const-folded ADD/SUB" commit: "bf56424" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 61.5} @@ -1724,6 +1785,7 @@ entries: date: "2026-02-26" reason: "Add ARM64 JIT div/rem-by-constant optimization (UMULL+LSR)" commit: "9261dbe" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 61.3} @@ -1759,6 +1821,7 @@ entries: date: "2026-02-26" reason: "Update Phase K progress: div-by-constant done, gaps documented" commit: "a8db014" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.5} @@ -1794,6 +1857,7 @@ entries: date: "2026-02-26" reason: "Optimize self-call setup: bypass shared prologue for self-call entry" commit: "26523a2" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 52.4} @@ -1829,6 +1893,7 @@ entries: date: "2026-02-26" reason: "Update Phase K progress: self-call setup optimization results" commit: "9b54765" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.8} @@ -1864,6 +1929,7 @@ entries: date: "2026-02-26" reason: "Eliminate redundant reg_ptr overflow check for self-call-only functions" commit: "9655e97" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.8} @@ -1899,6 +1965,7 @@ entries: date: "2026-02-26" reason: "Fix trunc_sat edge cases in x86_64 JIT and interpreter" commit: "a1acec0" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 49.8} @@ -1934,6 +2001,7 @@ entries: date: "2026-02-26" reason: "Record K.5 benchmark results, update Phase H Gate status" commit: "999dfb3" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 49.0} @@ -1969,6 +2037,7 @@ entries: date: "2026-02-26" reason: "Add x86_64 JIT self-call optimization" commit: "ced7c48" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 54.9} @@ -2004,6 +2073,7 @@ entries: date: "2026-02-26" reason: "Add x86_64 JIT div-by-constant optimization" commit: "d010830" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 51.7} @@ -2039,6 +2109,7 @@ entries: date: "2026-02-26" reason: "Update handover: x86_64 self-call and div-by-constant complete" commit: "fd30f76" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.8} @@ -2074,6 +2145,7 @@ entries: date: "2026-02-26" reason: "Fix ARM64 JIT: OSR support, FP cache self-clobber, globalGet x0 clobber" commit: "ee5f585" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.3} @@ -2108,6 +2180,7 @@ entries: date: "2026-02-26" reason: "Fix rw_c_string hang: skip back-edge JIT for reentry guard functions" commit: "b380c57" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.9} @@ -2143,6 +2216,7 @@ entries: date: "2026-02-26" reason: "Fix nbody FP cache: expand D-reg cache D2-D15, FP-aware MOV" commit: "c34454a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.0} @@ -2178,6 +2252,7 @@ entries: date: "2026-02-26" reason: "Re-measure rw_c_math: accept as regalloc limit (136 regs, 4.92x)" commit: "515c383" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.4} @@ -2213,6 +2288,7 @@ entries: date: "2026-02-27" reason: "P4: GC JIT implementation (struct.new/get/set + ref.null/is_null)" commit: "244f2bf" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.8} @@ -2248,6 +2324,7 @@ entries: date: "2026-02-27" reason: "R6: OSR for back-edge JIT — st_sieve 0.97x restored" commit: "6905eb7" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 49.5} @@ -2283,6 +2360,7 @@ entries: date: "2026-02-27" reason: "Release v1.2.0" commit: "93d4a9e" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 52.1} @@ -2318,6 +2396,7 @@ entries: date: "2026-03-02" reason: "Phase 1: guard pages + module cache (v1.3.0 candidate)" commit: "4de317d" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.8} @@ -2353,6 +2432,7 @@ entries: date: "2026-03-02" reason: "Phase 1 with cache variants baseline" commit: "0176572" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.1} @@ -2417,6 +2497,7 @@ entries: date: "2026-03-02" reason: "Release v1.3.0" commit: "3812372" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 52.4} @@ -2481,6 +2562,7 @@ entries: date: "2026-03-03" reason: "Phase 8 merge: 5 JIT codegen fixes + 50 real-world programs" commit: "03a16fe" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 85.7} @@ -2545,6 +2627,7 @@ entries: date: "2026-03-11" reason: "Suppress JIT when fuel metering active (no perf impact on normal execution)" commit: "83d1a33" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 49.6} @@ -2609,6 +2692,7 @@ entries: date: "2026-03-11" reason: "Add timeout support (PR#6 + CLI + JIT deadline suppression)" commit: "c333873" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.5} @@ -2673,6 +2757,7 @@ entries: date: "2026-03-15" reason: "PR #8 Windows first-class support + review fixes" commit: "6528ce4" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.5} @@ -2737,6 +2822,7 @@ entries: date: "2026-03-22" reason: "W35 fix: emitGlobalSet ABI clobber + --interp + i32.store16" commit: "1429f81" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 51.5} @@ -2801,6 +2887,7 @@ entries: date: "2026-03-23" reason: "198/256 SIMD opcodes native NEON (77% coverage)" commit: "f5e8a34" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.7} @@ -2865,6 +2952,7 @@ entries: date: "2026-03-23" reason: "235/256 SIMD native (92%), all non-relaxed except shuffle" commit: "1c52db8" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.5} @@ -2929,6 +3017,7 @@ entries: date: "2026-03-23" reason: "Phase 13.7: SIMD JIT benchmarks & wasmtime comparison" commit: "5ade595" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.8} @@ -2993,6 +3082,7 @@ entries: date: "2026-03-23" reason: "W40 epoch JIT timeout + W37 contiguous v128 + W39 multi-value return" commit: "a3211ac" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 53.0} @@ -3057,6 +3147,7 @@ entries: date: "2026-03-24" reason: "W38: HOT_THRESHOLD 10→3, extract_lane fix, back_edge_bailed" commit: "98a2827" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 50.8} @@ -3121,6 +3212,7 @@ entries: date: "2026-03-24" reason: "W38 final: threshold=3 + all fixes" commit: "8085bab" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 57.0} @@ -3185,6 +3277,7 @@ entries: date: "2026-03-25" reason: "Phase 20: written_vregs pre-scan fix — correctness fix, no perf change expected" commit: "126fa91" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.6} @@ -3249,6 +3342,7 @@ entries: date: "2026-03-25" reason: "Phase 20 complete: remainder aliasing fix, Mac+Ubuntu 50/50" commit: "65db814" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.4} @@ -3313,6 +3407,7 @@ entries: date: "2026-03-26" reason: "W44 SIMD register class: Q16-Q31 (ARM64) + XMM6-XMM15 (x86) cache for v128" commit: "e8d0317" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.3} @@ -3377,6 +3472,7 @@ entries: date: "2026-03-26" reason: "Post W44+SIMD bench: verify no scalar regression" commit: "a642ae3" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.9} @@ -3441,6 +3537,7 @@ entries: date: "2026-03-26" reason: "W45: SIMD Q-reg loop persistence (pre-header + flush stubs)" commit: "1e406db" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.6} @@ -3505,6 +3602,7 @@ entries: date: "2026-04-15" reason: "Baseline after PR #32 (force_interpreter persistence) + #33 (spec-sha bump) + #35 (doc URL fix); reference for upcoming PR #30/#28 work" commit: "201d13c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.5} @@ -3569,6 +3667,7 @@ entries: date: "2026-04-21" reason: "Release v1.8.0 — Config-based module loading API" commit: "924c043" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.7} @@ -3633,6 +3732,7 @@ entries: date: "2026-04-24" reason: "execution cancellation API (D134)" commit: "3bad07a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.8} @@ -3697,6 +3797,7 @@ entries: date: "2026-04-24" reason: "Release v1.9.0 baseline" commit: "231c7ca" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 55.0} @@ -3761,6 +3862,7 @@ entries: date: "2026-04-24" reason: "Release v1.9.1 baseline" commit: "078f8f2" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.2} @@ -3825,6 +3927,7 @@ entries: date: "2026-04-24" reason: "Zig 0.16.0 migration baseline" commit: "1df937b" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 51.7} @@ -3889,6 +3992,7 @@ entries: date: "2026-04-25" reason: "W46 Phase 2: route std.c.* through platform helpers" commit: "b168570" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 48.7} @@ -3953,6 +4057,7 @@ entries: date: "2026-04-25" reason: "W48: panic handler trim + segfault disable + u8 main return" commit: "68a7067" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.2} @@ -4017,6 +4122,7 @@ entries: date: "2026-04-26" reason: "loadCore errdefer for export_fns/cached_fns (issue #42)" commit: "dd7b43a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 44.9} @@ -4081,6 +4187,7 @@ entries: date: "2026-04-26" reason: "Release v1.11.0" commit: "2386f22" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 44.0} @@ -4145,6 +4252,7 @@ entries: date: "2026-04-29" reason: "docs: fresh-session simulation findings + Japanese strip" commit: "f9eb775" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.5} @@ -4209,6 +4317,7 @@ entries: date: "2026-04-29" reason: "ci(windows): drop shared-lib guard — Plan C-a (#68)" commit: "8a3370c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.0} @@ -4273,6 +4382,7 @@ entries: date: "2026-04-29" reason: "ci(windows): drop static-lib + static-link guards — Plan C-d (#69)" commit: "8fd36ab" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.7} @@ -4337,6 +4447,7 @@ entries: date: "2026-04-29" reason: "ci(windows): drop Rust example dynamic guard — Plan C-c (#71)" commit: "306c838" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.7} @@ -4401,6 +4512,7 @@ entries: date: "2026-04-29" reason: "ci(windows): cross-platform binary size via -Dstrip=true — Plan C-e + C-f (#70)" commit: "8b17991" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.5} @@ -4465,6 +4577,7 @@ entries: date: "2026-04-29" reason: "ci(windows): port FFI tests to Win32 — Plan C-b (#72)" commit: "29ba78a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.9} @@ -4529,6 +4642,7 @@ entries: date: "2026-04-29" reason: "docs(decisions): D137 — cross-platform stripping + per-OS size ceilings (#73)" commit: "0d3b8f6" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.3} @@ -4593,6 +4707,7 @@ entries: date: "2026-04-29" reason: "feat(windows): install-tools.ps1 — Rust / Go / TinyGo (W52) (#74)" commit: "6b89d0c" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.7} @@ -4657,6 +4772,7 @@ entries: date: "2026-04-29" reason: "docs: align Merge Gate / runner forms / per-OS size ceilings (#75)" commit: "b742f51" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.2} @@ -4721,6 +4837,7 @@ entries: date: "2026-04-29" reason: "docs: drop obsolete .dev/checklist-jit-fuel-timeout.md (#76)" commit: "2083573" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.3} @@ -4785,6 +4902,7 @@ entries: date: "2026-04-29" reason: "docs: changelog [Unreleased] PR-tags + D137 + memo.md current-task refresh (#77)" commit: "09e890a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.4} @@ -4849,6 +4967,7 @@ entries: date: "2026-04-29" reason: "docs(readme): W52 status + per-OS size ceilings (D137) (#78)" commit: "eb45994" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.4} @@ -4913,6 +5032,7 @@ entries: date: "2026-04-29" reason: "docs+ci: trailing cleanup after #75..#78 (#79)" commit: "f7897fb" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.9} @@ -4977,6 +5097,7 @@ entries: date: "2026-04-29" reason: "feat(flake): explicit URL+sha256 pins for wasm-tools + wasmtime (W50 PR-A) (#80)" commit: "5768928" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 47.7} @@ -5041,6 +5162,7 @@ entries: date: "2026-04-29" reason: "ci: add test-nix Linux job using Nix devshell (W50 PR-B) (#81)" commit: "b23a013" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 45.3} @@ -5105,6 +5227,7 @@ entries: date: "2026-04-29" reason: "ci: extend test-nix to macos-latest (W50 PR-C) (#82)" commit: "bb06753" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.6} @@ -5169,6 +5292,7 @@ entries: date: "2026-04-29" reason: "ci: complete W50 — Windows install-tools.ps1 + restore extras (W50 PR-D) (#83)" commit: "3a9c47a" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.6} @@ -5233,6 +5357,7 @@ entries: date: "2026-04-29" reason: "docs(w47): investigation note — variance dominates the +24 % signal (#84)" commit: "f087bab" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.0} @@ -5297,6 +5422,7 @@ entries: date: "2026-04-29" reason: "fix(w53): route rustup-init stdout through Out-Host (#85)" commit: "52c7ce4" + arch: aarch64-darwin build: ReleaseSafe results: fib: {time_ms: 46.5} diff --git a/bench/record.sh b/bench/record.sh index 6014bd83..45e5da9c 100755 --- a/bench/record.sh +++ b/bench/record.sh @@ -28,6 +28,8 @@ RUNS=5 WARMUP=3 TIMEOUT=60 # per-benchmark timeout in seconds NO_CACHE=false +# Auto-detected target triple. Resolved below; --arch=... overrides it. +ARCH="" # --- Benchmark definitions: name:wasm:function:args:type --- # Keep in sync with run_bench.sh @@ -85,6 +87,7 @@ for arg in "$@"; do --warmup=*) WARMUP="${arg#--warmup=}" ;; --timeout=*) TIMEOUT="${arg#--timeout=}" ;; --no-cache) NO_CACHE=true ;; + --arch=*) ARCH="${arg#--arch=}" ;; -h|--help) echo "Usage: bash bench/record.sh --id=ID --reason=REASON [OPTIONS]" echo "" @@ -100,6 +103,8 @@ for arg in "$@"; do echo " --warmup=N Number of warmup runs (default: 3)" echo " --timeout=SEC Per-benchmark timeout (default: 60)" echo " --no-cache Skip cached variant measurements" + echo " --arch=TRIPLE Override the auto-detected target triple" + echo " (e.g. aarch64-darwin, x86_64-linux, x86_64-windows)" echo " -h, --help Show this help" exit 0 ;; @@ -134,11 +139,33 @@ if [[ -z "$ID" || -z "$REASON" ]]; then exit 1 fi -# --- Check for duplicate id --- +# Resolve the target triple if the caller did not pass --arch=... +if [[ -z "$ARCH" ]]; then + case "$(uname -s)-$(uname -m)" in + Darwin-arm64) ARCH="aarch64-darwin" ;; + Darwin-x86_64) ARCH="x86_64-darwin" ;; + Linux-x86_64) ARCH="x86_64-linux" ;; + Linux-aarch64) ARCH="aarch64-linux" ;; + MINGW*-x86_64|MSYS*-x86_64|CYGWIN*-x86_64) ARCH="x86_64-windows" ;; + *) + echo "Error: cannot auto-detect target triple ($(uname -s)/$(uname -m))." >&2 + echo " Pass --arch= explicitly." >&2 + exit 1 + ;; + esac +fi + +# --- Check for duplicate (id, arch) --- +# An entry is identified by the (id, arch) tuple — the same merge SHA +# can be recorded once per target triple. Older entries that predate +# the multi-arch schema have an explicit `arch: aarch64-darwin` after +# the C-g migration; we still default-fill aarch64-darwin in the +# select below as a safety net for any hand-edited rows that omit +# the field. if [[ -f "$HISTORY_FILE" ]] && ! $OVERWRITE; then - existing=$(yq ".entries[] | select(.id == \"$ID\") | .id" "$HISTORY_FILE" 2>/dev/null || echo "") + existing=$(yq ".entries[] | select(.id == \"$ID\" and (.arch // \"aarch64-darwin\") == \"$ARCH\") | .id" "$HISTORY_FILE" 2>/dev/null || echo "") if [[ -n "$existing" ]]; then - echo "Error: Entry '$ID' already exists. Use --overwrite to replace." >&2 + echo "Error: Entry '$ID' already exists for arch '$ARCH'. Use --overwrite to replace." >&2 exit 1 fi fi @@ -310,9 +337,10 @@ entries: [] INITEOF fi -# Remove existing entry if overwriting +# Remove existing entry if overwriting (scoped to the current arch so +# --overwrite never wipes a sibling row recorded on a different host). if $OVERWRITE; then - yq -i "del(.entries[] | select(.id == \"$ID\"))" "$HISTORY_FILE" + yq -i "del(.entries[] | select(.id == \"$ID\" and (.arch // \"aarch64-darwin\") == \"$ARCH\"))" "$HISTORY_FILE" fi # Build YAML entry fragment @@ -322,6 +350,7 @@ id: "$ID" date: "$DATE" reason: "$REASON" commit: "$COMMIT" +arch: $ARCH build: ReleaseSafe results: ENTRYEOF diff --git a/scripts/record-merge-bench.sh b/scripts/record-merge-bench.sh index a77411de..a903ed8e 100755 --- a/scripts/record-merge-bench.sh +++ b/scripts/record-merge-bench.sh @@ -2,29 +2,33 @@ # scripts/record-merge-bench.sh — append a benchmark row to # bench/history.yaml for the current commit. # -# Project policy: every merge to main gets one row. Run this after the -# PR is merged and main is checked out locally, NOT before — the row -# should reference the merge commit, not the branch tip. +# Project policy: every merge to main gets one row per platform the +# user has access to. Run this after the PR is merged and main is +# checked out locally, NOT before — the row should reference the +# merge commit, not the branch tip. # -# Mac-only by design. bench/history.yaml's env block declares -# `os: Darwin ` so cross-host entries would be misleading. -# On Linux/Windows the script logs and exits 0 so it can sit in a -# scripted post-merge flow without breaking it. +# Multi-arch (C-g, 2026-04-29): bench/history.yaml stores entries for +# every target triple side by side; each row carries `arch:` +# (auto-detected from `uname -s -m`, override with --arch=...). Mac +# aarch64-darwin remains the canonical absolute-time baseline used at +# tag time, but x86_64-linux and x86_64-windows rows are encouraged +# so that cross-platform regressions surface early. # # Usage: -# bash scripts/record-merge-bench.sh # full record (5 runs + 3 warmup) -# bash scripts/record-merge-bench.sh --reason="..." # override default reason +# bash scripts/record-merge-bench.sh # full record (5 runs + 3 warmup) +# bash scripts/record-merge-bench.sh --reason="..." # override default reason +# bash scripts/record-merge-bench.sh --arch=x86_64-linux # explicit triple # # All arguments after the script are passed straight to -# bench/record.sh. --id and --reason are auto-filled from the current -# HEAD commit if you do not pass them explicitly. +# bench/record.sh. --id, --reason, and --arch are auto-filled when +# the caller does not pass them explicitly. # # Always use the default 5 runs + 3 warmup. bench/history.yaml is the -# canonical Mac M4 Pro absolute-time baseline used at tag time; lower -# run/warmup counts produce noisy / cold-cache-biased numbers that -# distort the long-term trend graph. `bench/run_bench.sh --quick` -# exists for interactive smoke tests — use that, not record.sh, when -# you just want a fast local check. +# canonical absolute-time baseline used at tag time; lower run/warmup +# counts produce noisy / cold-cache-biased numbers that distort the +# long-term trend graph. `bench/run_bench.sh --quick` exists for +# interactive smoke tests — use that, not record.sh, when you just +# want a fast local check. set -euo pipefail @@ -34,20 +38,16 @@ source "$SCRIPT_DIR/lib/versions.sh" cd "$ZWASM_REPO_ROOT" -if [ "$(uname)" != "Darwin" ]; then - echo "record-merge-bench: bench/history.yaml is Mac-specific (env: Darwin)." >&2 - echo " Skipping on $(uname)." >&2 - exit 0 -fi - -# Allow caller to override --id / --reason. We default-fill them from -# git only when the caller did not pass either flag. +# Allow caller to override --id / --reason / --arch. We default-fill +# them from git / `uname` only when the caller did not pass them. have_id=false have_reason=false +have_arch=false for arg in "$@"; do case "$arg" in --id=*) have_id=true ;; --reason=*) have_reason=true ;; + --arch=*) have_arch=true ;; esac done @@ -58,6 +58,20 @@ fi if ! $have_reason; then extra_args+=("--reason=$(git log -1 --pretty=%s)") fi +if ! $have_arch; then + case "$(uname -s)-$(uname -m)" in + Darwin-arm64) extra_args+=("--arch=aarch64-darwin") ;; + Darwin-x86_64) extra_args+=("--arch=x86_64-darwin") ;; + Linux-x86_64) extra_args+=("--arch=x86_64-linux") ;; + Linux-aarch64) extra_args+=("--arch=aarch64-linux") ;; + MINGW*-x86_64|MSYS*-x86_64|CYGWIN*-x86_64) extra_args+=("--arch=x86_64-windows") ;; + *) + echo "record-merge-bench: cannot auto-detect target triple ($(uname -s)/$(uname -m))." >&2 + echo " Pass --arch= explicitly." >&2 + exit 1 + ;; + esac +fi # Idempotent: if the auto-derived id already exists, the inner # bench/record.sh will refuse without --overwrite. That's intentional