diff --git a/CLAUDE.md b/CLAUDE.md index 224516d46d..01f00e3a4b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation. -**Current Version:** 0.5.1300 +**Current Version:** 0.5.1301 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index acec9fe48f..8fda8abac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5547,7 +5547,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perry" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "base64", @@ -5607,14 +5607,14 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "serde", ] [[package]] name = "perry-audio-miniaudio" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "cc", "libc", @@ -5622,7 +5622,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "inkwell", @@ -5639,7 +5639,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-hir", @@ -5647,7 +5647,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-hir", @@ -5655,7 +5655,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-dispatch", @@ -5664,7 +5664,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-hir", @@ -5672,7 +5672,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "base64", @@ -5684,7 +5684,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-hir", @@ -5692,7 +5692,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "async-trait", @@ -5721,14 +5721,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "serde", "serde_json", @@ -5736,7 +5736,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1300" +version = "0.5.1301" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5747,7 +5747,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "clap", @@ -5762,7 +5762,7 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "block2", "objc2", @@ -5772,7 +5772,7 @@ dependencies = [ [[package]] name = "perry-ext-argon2" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "argon2", "perry-ffi", @@ -5780,7 +5780,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "reqwest", @@ -5789,7 +5789,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bcrypt", "perry-ffi", @@ -5797,7 +5797,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "rusqlite", @@ -5805,7 +5805,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "scraper", @@ -5813,7 +5813,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "perry-runtime", @@ -5821,7 +5821,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "chrono", "cron", @@ -5831,7 +5831,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "chrono", "perry-ffi", @@ -5839,7 +5839,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "rust_decimal", @@ -5847,7 +5847,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "serde_json", @@ -5855,7 +5855,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "rand 0.10.1", @@ -5863,7 +5863,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "perry-runtime", @@ -5871,14 +5871,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bytes", "http-body-util", @@ -5896,7 +5896,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bytes", "lazy_static", @@ -5909,7 +5909,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bytes", "h2", @@ -5933,7 +5933,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "lazy_static", "perry-ffi", @@ -5943,7 +5943,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "jsonwebtoken", @@ -5954,7 +5954,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "lru", "perry-ffi", @@ -5963,7 +5963,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "chrono", "perry-ffi", @@ -5971,7 +5971,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bson", "futures-util", @@ -5983,7 +5983,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "chrono", "perry-ffi", @@ -5993,7 +5993,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "nanoid", "perry-ffi", @@ -6002,7 +6002,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "bytes", "perry-ffi", @@ -6015,7 +6015,7 @@ dependencies = [ [[package]] name = "perry-ext-node-forge" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "const-oid 0.9.6", "der 0.7.10", @@ -6034,7 +6034,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "lettre", "perry-ffi", @@ -6044,7 +6044,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "printpdf", @@ -6052,7 +6052,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "sqlx", @@ -6061,7 +6061,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "governor", "perry-ffi", @@ -6069,7 +6069,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "fast_image_resize", "image", @@ -6079,14 +6079,14 @@ dependencies = [ [[package]] name = "perry-ext-slugify" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-streams" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "lazy_static", "perry-ffi", @@ -6095,7 +6095,7 @@ dependencies = [ [[package]] name = "perry-ext-undici" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "perry-runtime", @@ -6104,7 +6104,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "uuid", @@ -6112,7 +6112,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ffi", "regex", @@ -6122,7 +6122,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "futures-util", "lazy_static", @@ -6135,7 +6135,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "brotli", "flate2", @@ -6145,7 +6145,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "dashmap", "once_cell", @@ -6154,7 +6154,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-api-manifest", @@ -6172,7 +6172,7 @@ dependencies = [ [[package]] name = "perry-parser" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-diagnostics", @@ -6184,7 +6184,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "base64", @@ -6226,14 +6226,14 @@ dependencies = [ [[package]] name = "perry-runtime-static" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-runtime", ] [[package]] name = "perry-stdlib" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "aes 0.8.4", "aes 0.9.1", @@ -6328,14 +6328,14 @@ dependencies = [ [[package]] name = "perry-stdlib-static" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-stdlib", ] [[package]] name = "perry-transform" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "perry-hir", @@ -6344,14 +6344,14 @@ dependencies = [ [[package]] name = "perry-ui" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ui-model", ] [[package]] name = "perry-ui-android" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "itoa", @@ -6368,7 +6368,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "rand 0.10.1", "serde", @@ -6378,7 +6378,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "cairo-rs 0.22.0", @@ -6401,7 +6401,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "block2", @@ -6417,7 +6417,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "block2", @@ -6432,7 +6432,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1300" +version = "0.5.1301" [[package]] name = "perry-ui-test" @@ -6443,11 +6443,11 @@ dependencies = [ [[package]] name = "perry-ui-testkit" -version = "0.5.1300" +version = "0.5.1301" [[package]] name = "perry-ui-tvos" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "block2", @@ -6463,7 +6463,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "block2", @@ -6479,7 +6479,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "block2", "libc", @@ -6492,7 +6492,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "base64", "libc", @@ -6509,14 +6509,14 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "perry-ui-windows", ] [[package]] name = "perry-updater" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "anyhow", "base64", @@ -6532,7 +6532,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1300" +version = "0.5.1301" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index 48c44288a0..ac8f0975ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -315,7 +315,7 @@ codegen-units = 16 codegen-units = 16 [workspace.package] -version = "0.5.1300" +version = "0.5.1301" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry" diff --git a/changelog.d/7534-plan-baseline-1299.md b/changelog.d/7534-plan-baseline-1299.md new file mode 100644 index 0000000000..298eaa0aed --- /dev/null +++ b/changelog.d/7534-plan-baseline-1299.md @@ -0,0 +1,22 @@ +### Docs: engine plan carries the full v0.5.1299 baseline, and a re-ordered backlog + +The plan's performance backlog was materially stale: its worst row was +`json_parse_1mb` at 6.27x, and it did not list `object_deep_clone` or +`promise_all_chains` at all — because until #7495 and #7516/#7529 landed, those +two kernels **crashed** rather than ran. + +Replaced with all twelve app-pattern kernels measured on the pinned quiet mini +at v0.5.1299 (AC power, CPU-quiet gate, node 22.23.1 / bun 1.3.14, 11 runs per +cell), plus the JSON polyglot legs. Two findings drive a re-ordering: + +- **`object_deep_clone` is 37.5x bun** (657 ms vs 17.5 ms) — the worst cell by + 3x over the next, and never before measurable. Now #7533, and first in the + queue with a profile-first instruction. +- **The JSON lazy tape is a net negative on scans**: the optimized build is + 2.2x slower than the unoptimized one on `field_access` (2984 ms vs 1350 ms) + with 3.6x the RSS, while remaining a 6.8x win on `roundtrip` (192 ms, beating + bun's 216 and node's 379 and within ~8% of Rust serde_json). #7478. + +`#7502` (nine shipped-lowering mechanics with no assertion anywhere) is added +to the ordering explicitly: today's ~20 rooting bugs were all found by hand +with `PERRY_GC_PROTECT_FROMSPACE`, because nothing else can find them. diff --git a/docs/engine-plan.md b/docs/engine-plan.md index cd68d47526..4832078d11 100644 --- a/docs/engine-plan.md +++ b/docs/engine-plan.md @@ -6,7 +6,7 @@ every dated status section, incident narrative and superseded sequencing lives in [`engine-plan-history.md`](engine-plan-history.md); this file holds only the current state and the remaining work so it stays readable across context loads. -Last synced **2026-08-06** (repsel status corrected same day: 4b was already merged). +Last synced **2026-08-06**, after the v0.5.1299 public-baseline sweep. | Concern | Detail lives in | |---|---| @@ -84,23 +84,49 @@ be by-construction (`expr_produces_non_pointer_bits_by_construction`), and #7501 found that even a static layout *declaration* gets revoked at runtime, so collector-facing metadata needs a live header test at the store. -### Performance backlog (public-baseline sweep, 2026-08-06, quiet host) - -Pinned Node v22.23.1 / Bun 1.3.14, 11 runs per cell. Worst-first vs bun: - -| row | ratio | workstream | -|---|--:|---| -| `json_parse_1mb` | 6.27× | JSON parser speed (shared with tape) | -| `map_1m` | 5.74× | Map internals | -| `batch` | 5.29× | app-pattern batch | -| `field_access` (json_polyglot) | ~13× | JSON tape scan. #7499 landed the reparse path but is a deliberate **no-op here** — the cost is the 10k `lazy_get` calls, so the early batch-flip trigger is the real fix | -| element-shape kernel (`keep[j].v`) | 6.2× vs node | repsel — invariant landed (#7496), consumer pending | -| `string_template_interp` | 3.09× | string building | -| `json_stringify_1mb` | 2.62× | JSON stringify | - -**Wins to protect:** JSON roundtrip **194 ms vs bun 221 / node 384** (the -tape's memcpy path — any tape change is measured against it; #7476 pins the -numbers); `date_format_parse` 0.82× vs bun. +### Performance backlog — full app-pattern sweep (v0.5.1299, pinned quiet mini) + +AC power, CPU-quiet gate passed, node 22.23.1 / bun 1.3.14, 11 runs per cell. +**All twelve kernels, worst first** — this supersedes the earlier partial table, +which topped out at 6.27x and predated two kernels running at all: + +| kernel | perry | bun | node | perry/bun | owner | +|---|--:|--:|--:|--:|---| +| **object_deep_clone** | 657.0 ms | 17.5 | 56.9 | **37.5x** | **#7533** | +| **promise_all_chains** | 259.7 ms | 22.7 | 64.0 | **11.4x** | unowned | +| json_parse_1mb | 438.2 ms | 68.1 | 127.1 | 6.4x | unowned | +| batch | 127.8 ms | 26.5 | 74.8 | 4.8x | unowned | +| map_1m | 1233.7 ms | 256.5 | 320.1 | 4.8x | unowned (largest absolute) | +| string_template_interp | 106.9 ms | 41.6 | 100.6 | 2.6x | unowned | +| json_stringify_1mb | 97.3 ms | 38.5 | 95.1 | 2.5x | unowned | +| string_concat_csv | 51.3 ms | 27.1 | 82.3 | 1.9x | borderline | +| buffer_transcode | 58.2 ms | 43.9 | 85.8 | 1.3x | ok | +| string_split_map_join | 51.1 ms | 44.1 | 75.8 | 1.2x | ok | +| regex_replace | 56.4 ms | 49.8 | 98.0 | 1.1x | ok | +| **date_format_parse** | 36.0 ms | 44.8 | 116.3 | **0.80x** | **win** | + +**`object_deep_clone` and `promise_all_chains` are new to this table because +they were CRASHING, not slow** — fixed today by #7495 and #7516/#7529. Their +first-ever measurement makes deep clone the worst cell by 3x over the next. +#7533 carries the profile-first instruction and an explicit A/B against +`f06270d06` to establish how much predates today's rooting stack. + +### JSON polyglot legs — the tape is a net negative on scans + +Same run. `roundtrip` is the crown jewel and `field_access` is the problem: + +| leg | perry optimized | perry idiomatic | bun | node | rust serde_json | +|---|--:|--:|--:|--:|--:| +| roundtrip | **192 ms** (82 MB) | 1307 ms | 216 | 379 | 178 | +| field_access | **2984 ms** (219 MB, sigma 136) | **1350 ms** (61 MB) | 218 | 380 | 183 | + +Perry **wins roundtrip** against both JS runtimes and lands within ~8% of Rust +serde_json. But on `field_access` the **optimized configuration is 2.2x SLOWER +than the unoptimized one** and carries 3.6x the RSS — the lazy tape is a net +negative on scan-shaped access, and its sigma of 136 (against every other row's +under 5) says the cost is data-dependently variable. The 1350 ms idiomatic row +is the floor any fix must beat: simply declining the tape for this shape would +already be 2.2x better. Tracked in **#7478**. ### Gates and blockers @@ -124,32 +150,40 @@ numbers); `date_format_parse` 0.82× vs bun. ## What is left, in order -1. **#7510 — `gc::layout` side tables (33.6%)**, the single biggest lever in - the engine. Its thread-local lookups are also part of the 17% TLS residue, - so one fix pays twice. Needs the quiet host to verify. -2. **#7497** — the last blocker on the public benchmark artifact. Publishing - turns `lint` green and **ends admin-bypass merging**; #7475 is closed - (it was a rooting bug, not the feature-stripped archive — #7495). -3. **#7512** — cheap bisect first: a static IR call-census diff says what the - class path emits that the literal path does not. May collapse into #7510 or - #7511, which is why it runs before either. -4. **#7511 — write barriers (16.1%)**, sequenced after #7512 in case that - accounts for it. Correctness-first: acceptance requires +1. **#7533 — `object_deep_clone` at 37.5x bun**, the worst cell in the public + artifact by 3x and newly measurable (it used to crash). Profile FIRST; the + issue carries an explicit A/B against `f06270d06` to settle whether today's + rooting re-reads are material on a spread-heavy workload. If they are, the + answer is hoisting them (#7487's pooled-alloca precedent), never removing + them — they close real use-after-frees. +2. **#7478 — the JSON tape's scan path**, where our optimized build is 2.2x + slower than our unoptimized one. The 1350 ms idiomatic row is the floor. +3. **#7510 — `gc::layout` side tables**, whose real remaining lever is + `js_gc_init_typed_shape_layout` + `shape_install_shared` (~13%), rebuilding + both masks on every construction of an already-installed shape. #7525 landed + the emptiness prerequisite and corrected the ticket's stale premise + (`layout_forget_object` is 3.0%, not the 14.5% it was filed on). +4. **#7511 — write barriers (16.1%)**. Correctness-first: acceptance requires `PERRY_GC_VERIFY_EVACUATION=1` / `PERRY_GC_VERIFY_MARK=1` and the ratchet probes, because a wrong answer here corrupts memory rather than slowing it. -5. **Repsel** — the element-shape invariant landed (#7496); the versioned-loop +5. **#7502 — the shipped root lowering has no coverage**: nine mechanics have + no native-roots assertion anywhere, six of them shapes + `gc-rooting-invariant.md` records as having already shipped broken. Today's + ~20 rooting bugs were all found by hand with `PERRY_GC_PROTECT_FROMSPACE` + because nothing else can find them. This is the structural fix. +6. **Repsel** — the element-shape invariant landed (#7496); the versioned-loop consumer and element `Ptr` remain. Deliberately sequenced **after** the bookkeeping levers: element reads are 13% of `churn` at 4.3×, the best ratio in the table, so this is an RSS/footprint play more than a time one. -6. **Layer 1** — migrate remaining lowerings onto the rooted-combinator API +7. **Layer 1** — migrate remaining lowerings onto the rooted-combinator API (`crates/perry-codegen/src/rooting.rs`); the arm-aware scan is the worklist tool. **Layer 3** — shrink the 107-module ceiling list toward empty; the end state is the raw accessor unreachable, not counted. -7. **Statepoint-side static checker** — teach `gc_root_dominance_check.py` to +8. **Statepoint-side static checker** — teach `gc_root_dominance_check.py` to read relocation bundles, closing the gap the #7452/#7460 repairs named. -8. **RSS re-derivation under the statepoint default** (#7056) — the earlier +9. **RSS re-derivation under the statepoint default** (#7056) — the earlier numbers were measured under the shadow stack. -9. **Ratchet large-Eden probe arm** (#7481's lesson), plus the pending +10. **Ratchet large-Eden probe arm** (#7481's lesson), plus the pending quiet-host re-pins (`wt-scavtenure` baseline). ---