@@ -133,23 +133,28 @@ machinery **engage real program shapes and prove it**, not new subsystems. In pr
133133 deopt state-map format / OSR-exit, NOT a one-liner — and none has a * correctness*
134134 driver today, so the differential cannot gate a reconstruction bug by output alone;
135135 they must be driven by dedicated repro tests):**
136- - ** (a) Live-out SCALAR aggregate reconstruction (most tractable; do first).**
137- ` native_loop_carried_struct_in_region ` / the variant+struct SR passes bail when
138- the aggregate is read after the loop (` passes.rs:7430 ` , the live-after / escape
139- check). To lift that: when every field is scalar, record a * reconstruction recipe*
140- ` (orig_reg, layout/tag, [leaf_reg per field]) ` from the SR pass, thread it through
141- ` translate ` into the OSR result, and at ** OSR-exit** (reg_vm, before resuming the
142- interpreter on the live-out window) rebuild ` VmValue::Struct ` /` Variant ` from the
143- leaf regs and write it into ` orig_reg ` . No ` handle→VmValue ` problem (all scalar);
144- the differential validates correctness once a live-out-struct kernel is added.
145- - ** (b) Composite HEAP-payload reconstruction.** A variant/struct field that is a
146- heap value (` Handle ` ) currently bails (` passes.rs:6205/6210 ` ). The blocker: a heap
147- field in a native reg is an opaque handle, and the interpreter frame no longer
148- holds the dissolved value. Approach: extend the recipe so a heap field references
149- its ** interpreter-visible SOURCE register** (the reg the ` MakeVariant ` /` MakeStruct `
150- read it from), provided that reg stays live + unclobbered to the reconstruction
151- point (needs a liveness proof); reconstruction reads ` frame.reg(source) ` . Fields
152- with no live source reg still bail.
136+ - ** (a) Live-out / escaping aggregate OSR — ALREADY COVERED (correctness + OSR)
137+ via native heap writes; only a perf refinement remains.** A loop-carried struct
138+ read after the loop or returned already OSRs through the transactional heap-write
139+ path (` native_osr_loop_carried_struct_live_after_loop_uses_heap_writes ` ,
140+ ` ..._escaping_uses_heap_writes ` — both green). The scalar loop-carried-struct SR
141+ pass declines (` passes.rs:7430 ` ) but OSR proceeds with the un-dissolved body
142+ (host-helper ` SetFieldSlot ` writes, journaled). So this is ** not a capability
143+ gap** — the only refinement is scalar-replacing such live-out structs for fewer
144+ host calls (record a recipe ` (orig_reg, layout, [leaf_reg]) ` , rebuild at OSR-exit);
145+ pure perf, low priority.
146+ - ** (b) Live-after HEAP-payload variant/Result OSR — the one genuine remaining
147+ coverage gap (perf, not correctness).** A ` Result ` /variant with a heap-payload arm
148+ that is ** live after the loop** does NOT OSR today (` native_osr_j3_escaping_result_does_not_osr `
149+ asserts ` osr_entries == 0 ` ); it is correct (runs on the interpreter), just not
150+ accelerated. Unlike structs (which OSR via heap writes), a dissolved variant's heap
151+ payload has no live heap object to write back. Blocker: a heap field in a native
152+ reg is an opaque handle and the interpreter frame no longer holds the dissolved
153+ value. Approach: extend the reconstruction recipe so a heap field references its
154+ ** interpreter-visible SOURCE register** (the reg ` MakeVariant ` /` MakeStruct ` read it
155+ from), provided that reg stays live + unclobbered to the reconstruction point
156+ (needs a liveness proof); reconstruction reads ` frame.reg(source) ` . Subtle
157+ (which arm, in-loop-built payloads have no live source) — a deliberate slice.
153158 - ** (c) Inlined logical-frame-chain format.** A deopt inside a ` native_inline_leaf_calls `
154159 region resumes at the caller's ` CallKnown ` and re-runs the (side-effect-free)
155160 callee — * correct today* . Full J0.1 reconstructs the logical callee frame in place
0 commit comments