jit: route strict inline-callee guards through the multi-frame snapshot#453
Conversation
Seed the callee `frame`/`ec` portal reds for a strict straight-line inline callee at the top inline level (un-gate the seeding from `try_multiframe`), so `collect_callee_active_boxes` sources the callee frame red and `walker_capture_multi_frame_inline_snapshot` succeeds instead of declining. A seeded strict callee then pushes a paused caller frame via `compute_inline_caller_frame`, so its in-callee guards resume at the callee's own coordinate; `compute_inline_caller_frame` returning `None` (a CALL inside a try-block, or no result on the operand stack at the return point) falls back to the single-frame collapse. Delete `strict_callee_collapse_unsound`, `fbw_strict_multiframe_enabled`, and the `PYRE_FBW_STRICT_MULTIFRAME` env var: the per-callee opcode-scanning predicate that chose collapse-vs-decline is replaced by the multi-frame routing. Nested strict callees (`inline_depth >= FBW_MAX_MULTIFRAME_DEPTH`) and un-seedable callees keep the single-frame collapse fallback. check.py: dynasm 159/159, cranelift 159/159, wasm 159/159. The four wasm #420 benches (inline_callee_constructs_object, inlined_helper_mutation, inlined_mutation_before_abort, sre_pattern_methods) and inline_helper compile and pass on all three backends. Assisted-by: Claude
|
Warning Review limit reached
Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🤖 Codex parity reviewStatic analysis of this diff vs the local RPython/PyPy sources (commit 628be7f). Codex did not produce a report (exit 1). Last log lines: |
Follow-up to #440. #440 fixed the four wasm-only #420 benches, but its strict-callee handling relied on machinery with no RPython/PyPy analog — a per-callee opcode-scanning predicate (
strict_callee_collapse_unsound), gated by aPYRE_FBW_STRICT_MULTIFRAMEenv flag, that chose collapse-vs-decline. This replaces that with the faithful multi-frame resume.The un-faithful machinery (deleted)
For a strict straight-line inline callee, the callee
frame/ecportal reds were seeded only insideif try_multiframe {(i.e. only for branch-bearing callees). A strict callee therefore hadportal_frame_reg == OpRef::NONE, socollect_callee_active_boxesreturnedUnsupportedandwalker_capture_multi_frame_inline_snapshotalways declined. The multi-frame path never actually resumed a strict callee at its own coordinate — it only chose between declining to a residual call and collapsing to the caller CALL boundary.strict_callee_collapse_unsoundwas the valve for that choice: it scanned the callee body for heap side effects (residual_call_r_*,residual_call_*_v,setfield,setarrayitem,setinteriorfield) and pushed the paused caller frame (→ MF decline → residual) only for side-effecting callees, keeping pure leaves on the single-frame collapse. That is a pyre-specific heuristic; RPython captures oneSnapshotframe perMIFrameand re-enters each at its saved pc — there is no opcode-scan and no collapse.Faithful replacement
jit: route strict inline-callee guards through the multi-frame snapshot:frame/ecportal reds at the top inline level (un-gated from thetry_multiframepath, via astrict_seed = strict_inlinable && inline_depth < FBW_MAX_MULTIFRAME_DEPTHguard and a'seed:labeled block).collect_callee_active_boxesnow sources the callee frame red, sowalker_capture_multi_frame_inline_snapshotsucceeds rather than declining.compute_inline_caller_frame— the seeded callee pushes a paused caller frame and its guards resume at the callee's own coordinate, with the caller paused at the CALL return point (the RPythonSnapshot.frames/resume.py rebuild_from_resumedatashape), instead of collapsing to the caller boundary.strict_callee_collapse_unsound,fbw_strict_multiframe_enabled, and thePYRE_FBW_STRICT_MULTIFRAMEenv var.inline_depth >= FBW_MAX_MULTIFRAME_DEPTH, task fib_recursive: recursive CALL_ASSEMBLER lands (now faster than CPython); residual ~4-5x-vs-pypy floor needs flat/virtualized jitframe #126), un-seedable callees, and caller shapescompute_inline_caller_framecannot build yet (a CALL inside a try-block, or no result on the operand stack at the return point).Fully retiring the single-frame collapse is a follow-up coupled to #126 (raising
FBW_MAX_MULTIFRAME_DEPTH) and #73 (kept operand-stack temps) — it needs the void / try-block caller-frame shapes the multi-frame path cannot yet build.Results (full
pyre/check.py, all three backends)The four #420 benches (
inline_callee_constructs_object,inlined_helper_mutation,inlined_mutation_before_abort,sre_pattern_methods) andinline_helpercompile and pass on all three backends. The side-effecting callees (inline_callee_constructs_object,inlined_mutation_before_abort) now inline via the multi-frame resume (loops_compiled=1) instead of residualizing.🤖 Generated with Claude Code