Skip to content

jit: inline nested int-arith calls in a carrier-resume bridge continuation (gh#343) - #748

Merged
youknowone merged 2 commits into
mainfrom
fib_recursive
Jul 24, 2026
Merged

youknowone merged 2 commits into
mainfrom
fib_recursive

Conversation

@youknowone

@youknowone youknowone commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Extends the carrier-resume sub-walk to inline a rare guard-bridge continuation's
nested exact-integer arithmetic calls instead of residualizing them as a
CALL_ASSEMBLER, closing the gh#343 plain-branch inlined-callee cost. Rebased
onto current main — the depth-N bridge-carrier convergence this branch
previously carried landed separately (#749), so this PR now contains only the
gh#343 fix.

Root cause: a branch (PopJumpIfFalse -> guard) inside an inlined callee makes
the callee's OWN inner calls (add, mul) on the traced arm degrade to a
residual CALL_ASSEMBLER (~100ns/crossing) while the primary loop inlines the
same chain to a few ns. The int-binop bridge-inline admission only fired for a
plain ROOT bridge (safe_root_bridge required !carrier_resume && !inline_subwalk), never for the carrier-resume sub-walk
(drive_bridge_frame_subwalk, which sets both) that a branchy continuation
traces through. The sub-walk drives its reconstructed frame through the same
metainterp the initial trace uses, so inlining the int-arith chain there is
uniform with a primary trace — residualizing was the deviation.

Commits:

  1. inline nested int-arith calls in a carrier-resume bridge continuation —
    split safe_root_bridge into root_bridge || subwalk_admit; admit the
    carrier-resume sub-walk unconditionally (carrier_resume + non-null
    snapshot_sym). No env gate — PyPy has no such switch, so the fix is always on.
  2. gate the branchy inlined-callee bridge regression in the synth suite —
    add pyre/bench/synth/bridge_branchy_callee.py, a deterministic-sum fixture
    gated against pypy by # pyre-check: max-pypy-ratio=8 on the native backends
    (wasm exempt, its guest has no time.perf_counter()).

Verification:

  • correctness: both backends build clean and the synthetic gate
    synth/bridge_branchy_callee holds at 1.4-1.7x (dynasm) / 3.3-3.6x
    (cranelift)
    vs pypy; a decline that keeps every crossing interpreted
    balloons to ~30x and FAILs the 8x gate
  • the fix engages exactly on the post-branch inner-call residual: a nested
    branchy driver goes 176ns -> 80ns/iter; a leaf branchy callee (no inner
    calls) is unchanged, and a straight (non-branch) callee does not regress
  • broadens a bridge-admission filter toward PyPy's filter-free
    _handle_guard_failure -> prepare_resume_from_failure -> interpret() resume
    (Codex parity review clean on the prior revision; removing the env gate makes
    it strictly more orthodox — PyPy uses no such runtime switch)

The exception-unwind continuation subcase of gh#343 (a raising callee, not a
data branch) is unchanged and stays with the epic.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Performance

    • Improved optimization of branch-heavy arithmetic workloads, with broader support for efficient inline execution.
    • Updated runtime safeguards to preserve reliable behavior across different execution paths.
  • Tests

    • Added synthetic benchmark coverage for branch-heavy calculations and performance validation.
  • Documentation

    • Added internal guidance describing performance safeguards and platform-specific benchmark expectations.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The JIT now admits additional carrier-resume bridge sub-walks when snapshot state exists. A synthetic benchmark exercises a branch inside an inlined callee, while explanatory comments document the parity-suite guard. The former regression script is removed.

Changes

Branchy callee bridge handling

Layer / File(s) Summary
Bridge inline admission
pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs
safe_root_bridge now includes carrier-resume sub-walks with an available snapshot symbol.
Synthetic benchmark and guard documentation
pyre/bench/synth/bridge_branchy_callee.py, pyre/check.py
Adds branchy arithmetic benchmark execution and documents its synthetic parity-suite guard and PyPy ratio gating.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • youknowone/pyre#724 — Covers related multiframe bridge-resume and recursive inline-depth work.

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant drive_branch
  participant compute_branch
  participant inline_call
  drive_branch->>compute_branch: evaluate each loop value
  compute_branch->>inline_call: process branchy callee inline path
  inline_call-->>compute_branch: admit carrier-resume bridge when snapshot exists
  compute_branch-->>drive_branch: return branch result
Loading

Poem

A rabbit hops through branches bright,
While bridges choose the safer flight.
A snapshot tucked beneath the tree,
Lets carrier walks pass merrily.
The benchmark prints its final cheer!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: inlining nested integer arithmetic in carrier-resume bridge continuations for gh#343.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fib_recursive

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ba32fae90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1373 to +1382
let bridge_rec_lift_exempt = pre_execute
&& fbw_bridge_rec_resid_enabled()
&& BRIDGE_REC_LIFT_TOP_INLINE.with(|c| {
let lifted_code = c.get();
let session = ctx.session.borrow();
lifted_code != 0
&& session.framestack.len() == 1
&& session.framestack[0].w_code == lifted_code
})
&& hazard == Some(FbwInlineCalleeHazard::SelfRecursiveStatic);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Limit the bridge residual exemption to the recursive call

This exemption is keyed only on the lifted frame's w_code plus the fact that the frame is statically self-recursive, but the pre-execute hook is invoked for every non-provably-side-effect-free residual in that frame. In a #704-lifted self-recursive integer callee that also does another residual effect (for example store_global, store_attr, logging, or a property/dunder call) before the recursive call, that unrelated residual now bypasses the nested-residual abort as well; if the bridge walk later declines, cleanup only rolls back the FBW journals, so the blackhole replay can re-run an effect that this guard was supposed to prevent. Please distinguish the actual self-recursive residual/CALL_ASSEMBLER case instead of exempting all residuals in the lifted frame.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

🤖 Codex parity review

Static analysis of this diff vs the local RPython/PyPy sources (commit fe4238d).
Updated: 2026-07-23T23:46:15.603Z

Files in the reviewed diff
pyre/bench/bridge_branchy_callee_regression.py
pyre/bench/synth/bridge_branchy_callee.py
pyre/check.py
pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs

1. Regressions to PyPy parity introduced by this patch

None.

2. Other mismatches introduced by this patch

None.

3. Pre-existing mismatches (already present before this patch)

  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs:1454 ↔ rpython/jit/metainterp/pyjitpl.py:1266 — Pyre permits bridge-origin inlining only for all-builtin-integer arguments and a BinaryOp residual body; PyPy’s inline_call_* always enters the callee frame and has no equivalent type/body-shaped bridge exclusion.

  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs:1398 ↔ rpython/jit/metainterp/pyjitpl.py:1390 — Pyre’s recursion cap counts only w_code; PyPy counts frames only when both the portal jitcode and every green-key value match. Pyre can therefore stop inlining distinct specializations of the same code too early.

  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs:1626 ↔ rpython/jit/metainterp/pyjitpl.py:1266 — Pyre restricts raising callees to one inline-frame depth, while PyPy creates and traces an MIFrame for each eligible inline call regardless of whether the callee can raise.

  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs:1639 ↔ rpython/jit/metainterp/pyjitpl.py:1266 — Pyre rejects otherwise eligible loop/branch callees when its strict/multiframe predicates fail; PyPy’s inline-call opcode transfers into the callee frame rather than imposing this body-shape prefilter.

4. Structural adaptations

  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs:1473 ↔ rpython/jit/metainterp/pyjitpl.py:2445 — The new carrier_resume admission is a Rust-side reconstruction of PyPy’s resumed MIFrame execution. It is semantically aligned: the carrier sub-walk rebuilds/pushes frame identity before walking, matching PyPy’s perform_call → newframe frame ownership model.

  • pyre/bench/synth/bridge_branchy_callee.py:1 ↔ rpython/jit/metainterp/pyjitpl.py:1266 — The new synthetic benchmark and max-pypy-ratio gate are pyre-specific test-harness infrastructure; PyPy has no corresponding benchmark source file. The test exercises PyPy’s normal inline-frame behavior rather than representing a source-translation divergence.

@youknowone youknowone changed the title jit: compile depth-2 bridge carriers in the default drain (opt-in) jit: compile depth-N bridge carriers in the default drain (opt-in) Jul 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a7c1cf94e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 1621 to +1622
let try_multiframe = multiframe_eligible
&& inline_depth < fbw_max_multiframe_depth()
&& inline_depth < effective_multiframe_depth

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the raise-depth cap to strict inlines too

When PYRE_FBW_MULTIFRAME_DEPTH is raised above 1 and a nested callee is strict_inlinable but contains a raise (for example a straight-line exception constructor/raise with no forward branch), this new cap is never consulted: try_multiframe is false for strict callees, the call continues through the strict path, and strict_seed below still uses the raw fbw_max_multiframe_depth(). That lets the cross-frame raise-unwind shape the new guard is trying to avoid still be inlined under an intermediate frame; please apply effective_multiframe_depth to the strict path as well, or reject/avoid seeding strict callees that contain raise.

AGENTS.md reference: AGENTS.md:L24-L30

Useful? React with 👍 / 👎.

@youknowone youknowone changed the title jit: compile depth-N bridge carriers in the default drain (opt-in) jit: compile depth-N bridge carriers and make deep chain-inline the default Jul 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a7046a867

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let Some(d) = crate::jitcode_runtime::decode_op_at(body_code, pc) else {
return false;
};
if d.opname == "raise" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include reraise in the raise-depth cap

With the new default depth allowing nested multiframe inlines, this scan only caps bodies containing raise/r; a callee that raises by bare raise in an exception handler uses the existing reraise/ opcode, so callee_body_contains_raise returns false and the callee can still be inlined below an intermediate frame. That re-enters the same unsupported cross-frame exception-unwind path the cap is meant to avoid for nested raising callees; please treat reraise as a raising opcode here as well.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f3126535a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pyre/check.py Outdated
Comment on lines +1793 to +1797
chk.run_selfcheck(
"bridge_branchy_callee",
f"{B}/bridge_branchy_callee_regression.py",
15,
skip_backends=("wasm",),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip branchy guard in multiframe-off runs

When check.py --no-fbw-inline-multiframe is used, pyre_env() forces PYRE_FBW_INLINE_MULTIFRAME=0 specifically to validate the flag-off fallback, but this newly added guard assumes compute_branch() is inlined via the multiframe path. With that path disabled, forward-branch callees are not multiframe_eligible (try_multiframe is false), so the script is no longer testing the gh#343 bridge continuation; it compares a residual-call branch path against the straight inlined path and can fail the rollback check. Please skip this selfcheck, or adjust its expectation, when FBW_INLINE_MULTIFRAME_OFF is set.

Useful? React with 👍 / 👎.

@youknowone youknowone changed the title jit: compile depth-N bridge carriers and make deep chain-inline the default jit: inline nested int-arith calls in a carrier-resume bridge continuation (gh#343) Jul 23, 2026
@youknowone
youknowone force-pushed the fib_recursive branch 2 times, most recently from f21088f to a96cfb7 Compare July 23, 2026 19:23
…ation

A branch (`PopJumpIfFalse` -> guard) inside an inlined callee makes the callee's
own inner calls (`add`, `mul`) on the traced arm degrade to a residual
`CALL_ASSEMBLER` (~100ns/crossing), while the primary loop inlines the same
chain to a few ns (gh#343). The int-binop bridge-inline admission
(`fbw_bridge_rec_inline_enabled` + `safe_root_bridge`) only fired for a plain
ROOT bridge, never for the carrier-resume sub-walk (`drive_bridge_frame_subwalk`,
which sets `carrier_resume`/`inline_subwalk`) that a branchy continuation traces
through.

Admit the carrier-resume sub-walk too: `safe_root_bridge = root_bridge ||
subwalk_admit`, where `subwalk_admit` holds when `carrier_resume` and a non-null
snapshot_sym. The sub-walk drives its reconstructed frame(s) forward through the
same metainterp the initial trace uses, so inlining a nested int-arith call there
is uniform with a primary trace — residualizing was the deviation.

Assisted-by: Claude
…suite

Add pyre/bench/synth/bridge_branchy_callee.py: a branch inside an inlined callee
(gh#343) whose rare arm guard-fails, exercising the carrier-resume sub-walk's
int-arith inline of the branchy continuation. It prints a deterministic sum and
is gated against pypy by `# pyre-check: max-pypy-ratio=8`. The synthetic suite
times pyre-JIT vs pypy (native backends, startup-subtracted): the fix holds at
1.4-1.7x (dynasm) / 3.3-3.6x (cranelift), while a decline that keeps every
crossing interpreted balloons it to ~30x, so the ratio catches the regression
with margin. wasm is exempt (guest has no time.perf_counter()). Drops the old
bridge_branchy_callee_regression.py run_selfcheck.

check.py dynasm + cranelift.

Assisted-by: Claude

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs`:
- Around line 1458-1474: The root-bridge self-recursion exemption is incorrectly
enabled for carrier-resume sub-walks through safe_root_bridge. Update the flag
computation near root_bridge and subwalk_admit so bridge_rec_root_selfrec
remains true only for the plain root_bridge, while carrier-resume entries can
still use subwalk_admit for inline admission; preserve the existing
self-recursive hazard checks for carrier-resume paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 47f3c814-805b-432a-acfc-ace3ed13dd2d

📥 Commits

Reviewing files that changed from the base of the PR and between 8fa227c and fe4238d.

📒 Files selected for processing (4)
  • pyre/bench/bridge_branchy_callee_regression.py
  • pyre/bench/synth/bridge_branchy_callee.py
  • pyre/check.py
  • pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs
💤 Files with no reviewable changes (1)
  • pyre/bench/bridge_branchy_callee_regression.py

Comment on lines +1458 to +1474
// A depth-1 carrier-resume sub-walk (`drive_bridge_frame_subwalk`) drives
// its reconstructed frame as the sub-walk root with an empty framestack,
// so it is uniform with a plain root bridge for the multiframe seed —
// admit it too so a rare guard-bridge continuation inlines its nested
// int-arith calls instead of residualizing them (the gh#343 branchy-callee
// cost).
let root_bridge = !ctx.fbw_mode.carrier_resume
&& !ctx.fbw_mode.inline_subwalk
&& !ctx.fbw_mode.snapshot_sym.is_null()
&& ctx.session.borrow().framestack.is_empty();
// A carrier-resume sub-walk (`drive_bridge_frame_subwalk`) drives its
// reconstructed frame(s) forward through the same metainterp the initial
// trace uses, so its inline of a nested int-arith call is the SAME as a
// primary trace's — admit it (any inline depth) so the rare guard-bridge
// continuation inlines instead of residualizing.
let subwalk_admit = ctx.fbw_mode.carrier_resume && !ctx.fbw_mode.snapshot_sym.is_null();
let safe_root_bridge = root_bridge || subwalk_admit;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the relevant implementation and usages without running repo code.
fd -a 'inline_call.rs' . | sed 's#^\./##'
echo '--- find file line count ---'
wc -l pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs

echo '--- outline around relevant file ---'
ast-grep outline pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs --view summary || true

echo '--- inspect lines 1430-1500 ---'
sed -n '1430,1500p' pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs | cat -n | sed 's/^/L /'

echo '--- inspect lines 2280-2340 ---'
sed -n '2280,2340p' pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs | cat -n | sed 's/^/L /'

echo '--- search symbol usages ---'
rg -n "bridge_rec_root_selfrec|SelfRecCaFoldGuard|safe_root_bridge|subwalk_admit|root_bridge|carrier_resume|drive_bridge_frame_subwalk" pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs

Repository: youknowone/pyre

Length of output: 10106


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- inspect carrier-resume mode context ---'
sed -n '1360,1515p' pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs | cat -n | sed 's/^/L /'

echo '--- inspect self-rec guard definition and nested-residual decline ---'
rg -n "struct SelfRecCaFoldGuard|impl SelfRecCaFoldGuard|SelfRecCaFoldGuard|fbw_abort_nested_unjournaled_residual|nested_unjournaled_residual|SELFREC_CA_FOLD_ACTIVE|bridge_rec_root_selfrec" pyre/pyre-jit-trace/src -S

echo '--- inspect related files from rg context ---'
for f in $(rg -l "SelfRecCaFoldGuard|fbw_abort_nested_unjournaled_residual|SELFREC_CA_FOLD_ACTIVE" pyre/pyre-jit-trace/src); do
  echo "### $f"
  wc -l "$f"
  rg -n -C 8 "SelfRecCaFoldGuard|fbw_abort_nested_unjournaled_residual|SELFREC_CA_FOLD_ACTIVE" "$f"
done

Repository: youknowone/pyre

Length of output: 27206


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- inspect carrier-resume mode context before selfrec block ---'
sed -n '1360,1465p' pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs | cat -n | sed 's/^/L /'

echo '--- inspect walk body around subcall inline continuation ---'
sed -n '1515,1780p' pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs | cat -n | sed 's/^/L /'

echo '--- inspect self-rec guard and nested-residual decline ---'
rg -n "struct SelfRecCaFoldGuard|impl SelfRecCaFoldGuard|SelfRecA|fbw_abort_nested_unjournaled_residual|fbw_abort_self_recursive|nested_unjournaled_residual|UNRECODABLE_MARKER|SAFE_FOLD" pyre/pyre-jit-trace/src -S

echo '--- list candidate helper files ---'
fd -a '.*\.rs$' pyre/pyre-jit-trace/src | xargs rg -l "SelfRecCaFoldGuard|fbw_abort_nested_unjournaled_residual|UNRECODABLE_MARKER|SAFE_FOLD"

Repository: youknowone/pyre

Length of output: 24984


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- inspect fbw_abort_nested_unjournaled_residual implementation ---'
sed -n '1266,1383p' pyre/pyre-jit-trace/src/jitcode_dispatch/fbw_state.rs | cat -n | sed 's/^/L /'

echo '--- inspect SelfRecCaFoldGuard RAII implementation ---'
sed -n '4638,4674p' pyre/pyre-jit-trace/src/jitcode_dispatch/mod.rs | cat -n | sed 's/^/L /'

echo '--- inspect residual call sites just before nested declarations ---'
for f in pyre/pyre-jit-trace/src/jitcode_dispatch/residual_call.rs pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs; do
  echo "### $f"
  rg -n -B 10 -A 12 "fbw_abort_nested_unjournaled_residual\\(" "$f"
done

echo '--- read-only behavioral probe: derive control-flow condition reachability ---'
python3 - <<'PY'
cases = [
    {"carrier_resume": False, "inline_subwalk": False, "snapshot_null": False, "framestack_empty": True},
    {"carrier_resume": True, "inline_subwalk": True, "snapshot_null": False, "framestack_empty": True},
    {"carrier_resume": True, "inline_subwalk": False, "snapshot_null": False, "framestack_empty": True},
]
for case in cases:
    root_bridge = (
        not case["carrier_resume"]
        and not case["inline_subwalk"]
        and not case["snapshot_null"]
        and case["framestack_empty"]
    )
    subwalk_admit = case["carrier_resume"] and not case["snapshot_null"]
    safe_root_bridge = root_bridge or subwalk_admit
    print(case, "root_bridge", root_bridge, "subwalk_admit", subwalk_admit, "safe_root_bridge", safe_root_bridge)
PY

Repository: youknowone/pyre

Length of output: 14279


Do not apply the root-bridge self-recursion exemption to carrier-resume sub-walks.

subwalk_admit already allows carrier-resume entries to inline, but it also makes safe_root_bridge true for non-root carrier bridges, so bridge_rec_root_selfrec enables SelfRecCaFoldGuard at Line 2318. That guard bypasses the self-recursive hazard check in fbw_abort_nested_unjournaled_residual, and the documented safety argument only applies to the plain root bridge. Narrow the flag to root_bridge, or add a carrier-resume-specific proof and regression test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyre/pyre-jit-trace/src/jitcode_dispatch/inline_call.rs` around lines 1458 -
1474, The root-bridge self-recursion exemption is incorrectly enabled for
carrier-resume sub-walks through safe_root_bridge. Update the flag computation
near root_bridge and subwalk_admit so bridge_rec_root_selfrec remains true only
for the plain root_bridge, while carrier-resume entries can still use
subwalk_admit for inline admission; preserve the existing self-recursive hazard
checks for carrier-resume paths.

@youknowone
youknowone merged commit ef274d3 into main Jul 24, 2026
29 of 31 checks passed
@youknowone
youknowone deleted the fib_recursive branch July 24, 2026 01:57
youknowone added a commit that referenced this pull request Jul 24, 2026
…ume keep

Record in the PYRE_P2_DRAIN retirement note that the branchy inlined-callee
continuation gap's plain-branch subcase is closed unconditionally (the
carrier-resume sub-walk int-binop inline landed without a gate in #748), and
its exception-unwind subcase is handled by the now-unconditional try-block
callee inline + carrier-boundary raise delivery (PYRE_FBW_TRYBLOCK_INLINE /
PYRE_FBW_CARRIER_RAISE retired). Add PYRE_CARRIER_EXC_RESUME to Judged KEEP
(default-off; the bridge_guard_exc GC-rooting and the unconditional
execute_ll_raised exception assign are the parity gaps to close before it is
enabled by default).

Assisted-by: Claude
youknowone added a commit that referenced this pull request Jul 24, 2026
…e handler fix (#759)

* jit: retire two default-on FBW inline gates

PYRE_FBW_TRYBLOCK_INLINE and PYRE_FBW_CARRIER_RAISE both defaulted on with
no remaining reason to toggle off once verified, so make their behavior
unconditional and drop the gates:

- a try-block CALL whose except handler rejoins a loop always
  multi-frame-inlines; decline_inline_caller_frame_for_catch_marker now
  runs the any-loop rejoin test directly instead of branching between it
  and a specific-loop fallback.
- the depth-2 carrier-boundary raise delivery in drive_bridge_carrier_walk
  is always active.

Deletes the now-dead exc_handler_rejoins_specific_loop and
enclosing_loop_header_jit_pc (only the carrier-raise-off branch used them)
and the now-unused call_jit_pc parameter of
decline_inline_caller_frame_for_catch_marker. PYRE_CARRIER_EXC_RESUME stays
(default-off lever).

exceptions / exception_args_virtual / break_except_live_local bit-exact
with loops_aborted=0; bridge_branchy_callee regression passes; check.py
dynasm 303/303, cranelift 303/303, wasm 300/300.

Assisted-by: Claude

* docs: gate-triage note — branchy subcase closures and carrier-exc-resume keep

Record in the PYRE_P2_DRAIN retirement note that the branchy inlined-callee
continuation gap's plain-branch subcase is closed unconditionally (the
carrier-resume sub-walk int-binop inline landed without a gate in #748), and
its exception-unwind subcase is handled by the now-unconditional try-block
callee inline + carrier-boundary raise delivery (PYRE_FBW_TRYBLOCK_INLINE /
PYRE_FBW_CARRIER_RAISE retired). Add PYRE_CARRIER_EXC_RESUME to Judged KEEP
(default-off; the bridge_guard_exc GC-rooting and the unconditional
execute_ll_raised exception assign are the parity gaps to close before it is
enabled by default).

Assisted-by: Claude

* jit: set class_of_last_exc_is_const on the carrier-raise handler entry

The carrier-boundary raise handler-entry branch in dispatch_via_miframe
seeded last_exc_value + the handler-entry operand stack but left
class_of_last_exc_is_const at its stale pre-bridge value, unlike the
sibling exc_edge_catch_target branch and the walk-level SubRaise routing
(opimpl_raise), which set it true. The seed's exception is a const-class
raise (the callee's inline RAISE recorded a NewWithVtable of a known
class), so a reraise in the handler read the standing exception state
from the stale flag. Set it true to match the siblings.

Document the default-off PYRE_CARRIER_EXC_RESUME pre-flip-on parity gaps
(gate-triage.md, trace_ctx.rs): the bridge_guard_exc GCREF-as-i64 is not a
traced root and the seed's execute_ll_raised assign is guarded by is_null
rather than unconditional; both are inert while the gate is off.

reraise-in-handler repro bit-exact (875000) on both backends; check.py
dynasm 301/301, cranelift 301/301, wasm 297/297.

Assisted-by: Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant