ReviewOS

zig-utils/zig-js

JIT: compact selected loop SSA into native scratch space

#1015
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Parents: #466, #469 Performance evidence: #473 Follows: #1014

Executed evidence

After #1014, the exact frozen representativeJson function builds a valid optimizer plan with 131 bytecodes, 11 CFG blocks, 147 live whole-function SSA nodes, 13 edges, and 3 branches. All loop-region lowerers reject before selection because graph.nodes.len > jit.numeric_scratch_capacity (147 > 128), even though native OSR executes only one selected natural-loop region and imports its live entry values from the VM frame.

Scope

  • Select the exact natural loop before applying the native scratch-capacity gate.
  • Compact only values required by that region, its internal/backedge copies, exact side exits, frame states, handlers, and runtime-operation recovery states into stable region-local SSA slots.
  • Preserve original bytecode origins and CFG block identities for steps, diagnostics, side exits, and observability.
  • Reject irreducible or external-entry regions before pruning any edge that would expose the defect.
  • Keep all native scratch/deopt/stack-map indexes within the existing 128-slot ABI; do not enlarge the array to fit unrelated function nodes.

Acceptance

  • A focused function with more than 128 live pre-loop SSA values but a small natural loop publishes and executes exact OSR.
  • Entry imports, parallel edge copies, side-exit recovery, handlers, stack maps, invalidation, and moving-GC rewrites use the compact IDs.
  • Existing irreducible-region rejection remains pinned.
  • The exact representativeJson function advances past the 147/128 rejection; any next rejection is measured and filed separately.
  • Focused Debug, ReleaseFast, TSan, forced-tier semantic differential, and exact-parent timing remain green with no frozen-control regression.
9 days ago

Landed and pushed as e11e1a1.

Executed evidence:

  • exact frozen representativeJson: 147 whole-function nodes -> 127 outer-region nodes / 43 selected inner-region nodes; the 147/128 rejection is gone and lowering reaches the next independent unsupported-operation boundary;
  • real-GC focused production root: 448 passed, 1 platform skip, 0 failed (2.075 GB bounded peak);
  • ReleaseFast optimizer slice: 11 passed, 0 failed;
  • TSan optimizer slice: 11 passed, 0 failed;
  • oversized two-entry irreducible CFG remains rejected after the compaction fallback is forced.

The implementation keeps the fixed 128-slot ABI, preserves bytecode origins/block identities, remaps exact frame/edge recovery states, and verifies header dominance before pruning. I am leaving the issue open until the full forced-tier integration differential runs with the next measured operation-boundary change.

9 days ago

Completed by e11e1a1 and re-audited on current main at a4d47ae. The exact 147-node function-wide plan compacts to the selected 43-node region without changing the fixed 128-slot ABI. Current real-GC tests pass the loop set 14/14 plus the separate compaction/rejection set 4/4; both sets also pass under unsuppressed TSan. The tests pin frame imports, parallel copies, recovery states, moving safepoints, multi-exit reconstruction, and both original and post-compaction irreducible-region rejection. Frozen representative_json publishes optimizer OSR and preserves checksum 324952086.

Sign in to comment on this issue.