Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions majit/majit-metainterp/src/trace_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,6 @@ pub struct ReconstructRecipe {
/// stable code identity rather than a live wrapper courier.
pub code_ptr: *const (),
pub jitcode_index: i32,
pub pc: usize,
/// Guard-carried JitCode offset from the decoded resume frame;
/// `majit_ir::resumedata::NO_JITCODE_PC` when the frame carried none.
pub jitcode_pc: i32,
Expand All @@ -569,9 +568,8 @@ pub struct BridgeInlineCarrier {
/// pc; the root must instead resume at its own `frames[0].pc`, so this is
/// threaded separately rather than derived from the trace start pc.
pub root_pc: usize,
/// Guard-carried JitCode offset from `resume_data.frames[0]`;
/// `majit_ir::resumedata::NO_JITCODE_PC` when the frame carried none.
pub root_jitcode_pc: i32,
/// The JitCode body that owns `root_pc`.
pub root_jitcode_index: i32,
/// `resume_data.frames[1..]`, OUTERMOST-FIRST. The portal (`frames[0]`)
/// is NOT here — it is the caller-visible root `sym`.
pub recipes: Vec<ReconstructRecipe>,
Expand Down
36 changes: 19 additions & 17 deletions pyre/pyre-jit-trace/src/jitcode_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2806,7 +2806,6 @@ fn compute_bridge_root_parent_frame(
root_sym: &crate::state::PyreSym,
trace_ctx: &mut TraceCtx,
root_pc: usize,
root_carried_jitcode_pc: i32,
) -> Option<InlineParentFrame> {
if root_sym.jitcode.is_null() {
return None;
Expand All @@ -2815,7 +2814,7 @@ fn compute_bridge_root_parent_frame(
// `root_pc` (`resume_data.frames[0].pc`) is already the post-call resume
// point — the slot the inner frame's result lands in — so it is the
// fallthrough `resume_py_pc` directly (no `semantic_fallthrough_pc`).
let resume_py_pc = root_pc as u32;
let resume_py_pc = crate::state::backxlat_py_pc(jitcode_index as i32, root_pc as i32) as u32;
// Null the not-yet-produced call-result slot before collecting the active
// boxes (the reconstructed callee supplies it on `SubReturn`), mirroring
// `compute_inline_caller_frame`. Operate on a clone so `root_sym` stays a
Expand All @@ -2834,14 +2833,17 @@ fn compute_bridge_root_parent_frame(
.bridge_registers_r
.clone()
.unwrap_or_else(|| root_sym.registers_r.clone());
if let Some(result_color) = crate::state::result_color_at_pc_at(jitcode_index as i32, root_pc) {
let root_py_pc = crate::state::backxlat_py_pc(jitcode_index as i32, root_pc as i32) as usize;
if let Some(result_color) =
crate::state::result_color_at_pc_at(jitcode_index as i32, root_py_pc)
{
if result_color < regs_r.len() {
regs_r[result_color] = trace_ctx.const_ref(pyre_object::PY_NULL as i64);
}
}
let root_word = (root_carried_jitcode_pc != majit_ir::resumedata::NO_JITCODE_PC
&& root_carried_jitcode_pc >= 0)
.then_some(root_carried_jitcode_pc as usize);
let root_word = ((root_pc as i32) != majit_ir::resumedata::NO_JITCODE_PC
&& (root_pc as i32) >= 0)
.then_some(root_pc);
let root_liveness_word = match root_word.filter(|_| m73_outercap_carry_enabled()) {
Some(w) => w as i32,
None => majit_ir::resumedata::NO_JITCODE_PC,
Expand Down Expand Up @@ -2879,7 +2881,7 @@ fn compute_bridge_root_parent_frame(
/// callee frame of a multi-frame bridge as an INLINE SUB-WALK
/// (`is_top_level = false`) rooted on the caller-visible portal `root_sym`.
///
/// The callee resumes at `entry` (its `resume_jitcode_pc_for(recipe.pc)`) with
/// The callee resumes at `entry` (its translated recipe Python pc) with
/// its registers seeded by `argboxes_r` (portal reds + in-flight operand-stack
/// temps from `setup_reconstructed_callee_frame`) and its locals carried in the
/// already-emitted frame vable. Because the walk is a sub-walk, the callee's
Expand All @@ -2902,7 +2904,6 @@ pub(crate) fn drive_bridge_carrier_subwalk(
session: &std::cell::RefCell<WalkSession>,
root_sym: &crate::state::PyreSym,
root_pc: usize,
root_jitcode_pc: i32,
callee_pjc: &std::sync::Arc<crate::PyJitCode>,
callee_code_key: usize,
callee_w_globals: usize,
Expand Down Expand Up @@ -3001,7 +3002,7 @@ pub(crate) fn drive_bridge_carrier_subwalk(
}

// Paused root portal frame for the multi-frame guard snapshot.
let root_frame = compute_bridge_root_parent_frame(root_sym, ctx, root_pc, root_jitcode_pc)?;
let root_frame = compute_bridge_root_parent_frame(root_sym, ctx, root_pc)?;
let outer_jitcode_index = root_frame.jitcode_index;
let outer_active_boxes = root_frame.boxes.clone();

Expand Down Expand Up @@ -3067,7 +3068,8 @@ pub(crate) fn drive_bridge_carrier_subwalk(
last_exc_value: None,
last_exc_value_concrete: ConcreteValue::Null,
// The outer Python frame is the root, paused at `root_pc`.
entry_py_pc: root_pc as u32,
entry_py_pc: crate::state::backxlat_py_pc(outer_jitcode_index as i32, root_pc as i32)
as u32,
outer_resume_marker_jit_pc: root_frame.resume_marker_jit_pc,
outer_jitcode_index,
outer_active_boxes,
Expand Down Expand Up @@ -3118,7 +3120,6 @@ pub(crate) fn drive_outer_frame_continuation(
root_code_key: usize,
root_w_globals: usize,
root_pc: usize,
root_jitcode_pc: i32,
entry: usize,
frame_box: OpRef,
frame_reg: usize,
Expand Down Expand Up @@ -3194,7 +3195,7 @@ pub(crate) fn drive_outer_frame_continuation(
regs_f[num_regs_f + i] = ctx.const_float(v);
}

let root_frame = compute_bridge_root_parent_frame(root_sym, ctx, root_pc, root_jitcode_pc)?;
let root_frame = compute_bridge_root_parent_frame(root_sym, ctx, root_pc)?;
let outer_jitcode_index = root_frame.jitcode_index;
let outer_active_boxes = root_frame.boxes.clone();

Expand All @@ -3214,13 +3215,13 @@ pub(crate) fn drive_outer_frame_continuation(
// walker banks. Only live colors are touched; dead slots stay
// `OpRef::NONE` so a later guard snapshot cannot capture a stale operand.
{
let root_word = (root_jitcode_pc != majit_ir::resumedata::NO_JITCODE_PC
&& root_jitcode_pc >= 0)
.then_some(root_jitcode_pc as usize);
let root_word = ((root_pc as i32) != majit_ir::resumedata::NO_JITCODE_PC
&& (root_pc as i32) >= 0)
.then_some(root_pc);
// Mirror `compute_bridge_root_parent_frame` so scatter reads the banks in collection order.
let banks = crate::state::frame_liveness_reg_indices_by_bank_at_with_jitcode_pc(
outer_jitcode_index as i32,
root_pc as i32,
crate::state::backxlat_py_pc(outer_jitcode_index as i32, root_pc as i32),
match root_word.filter(|_| m73_outercap_carry_enabled()) {
Some(w) => w as i32,
None => majit_ir::resumedata::NO_JITCODE_PC,
Expand Down Expand Up @@ -3335,7 +3336,8 @@ pub(crate) fn drive_outer_frame_continuation(
sub_jitcode_lookup: lookup_ref,
last_exc_value: None,
last_exc_value_concrete: ConcreteValue::Null,
entry_py_pc: root_pc as u32,
entry_py_pc: crate::state::backxlat_py_pc(outer_jitcode_index as i32, root_pc as i32)
as u32,
outer_resume_marker_jit_pc: root_frame.resume_marker_jit_pc,
outer_jitcode_index,
outer_active_boxes,
Expand Down
4 changes: 2 additions & 2 deletions pyre/pyre-jit-trace/src/pyjitcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,8 @@ impl PyJitCode {
/// PC directly in resume data (`miframe.pc`); pyre's resume data
/// stores the Python bytecode PC and translates here. This
/// translation is permanent: pyre interprets Python bytecode while
/// upstream interprets JitCode, so an *entry* py_pc (inline-callee
/// `recipe.pc`, root-portal / walk-entry `start_pc`) has no genuine
/// upstream interprets JitCode, so an *entry* py_pc (an inline-callee's
/// translated recipe pc, or root-portal / walk-entry `start_pc`) has no genuine
/// JitCode coordinate in hand and must be resolved through the
/// tables. The dense `pc_map` this once read has been deleted; the
/// offset now derives from the two surviving exact tables plus the
Expand Down
18 changes: 12 additions & 6 deletions pyre/pyre-jit-trace/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,11 @@ pub fn skip_python_trivia_forward_public(
}

/// Translate a resume-frame pc word to a Python instruction coordinate.
///
/// A negative word (sentinel / branch-orgpc tag) has no Python coordinate; per
/// the `decode_resume_pc` contract it passes through so the caller's `pc < 0`
/// screen rejects it (the internal metadata lookups below are bounds-checked and
/// never index with the word, so no wrap results).
pub fn backxlat_py_pc(jitcode_index: i32, pc_word: i32) -> i32 {
let fallback = majit_ir::resumedata::decode_resume_pc(pc_word).0;
python_pc_for_jitcode_pc_public(jitcode_index, pc_word)
Expand Down Expand Up @@ -5956,7 +5961,6 @@ fn reconstruct_inline_recipe(
return Some(ReconstructRecipe {
code_ptr: raw_code as *const (),
jitcode_index: frame.jitcode_index,
pc: py_pc,
jitcode_pc: frame.pc,
nlocals,
valuestackdepth,
Expand Down Expand Up @@ -6138,7 +6142,6 @@ fn reconstruct_inline_recipe(
Some(ReconstructRecipe {
code_ptr: raw_code as *const (),
jitcode_index: frame.jitcode_index,
pc: py_pc,
jitcode_pc: frame.pc,
nlocals,
valuestackdepth,
Expand Down Expand Up @@ -8982,13 +8985,13 @@ impl JitState for PyreJitState {
);
}
if resume_data.frames.len() > 1 {
let root_jitcode_index = resume_data.frames[0].jitcode_index;
let root_pc_valid = resume_data.frames[0].pc >= 0;
let root_pc = if root_pc_valid {
resume_data.frames[0].pc as usize
} else {
0
};
let root_jitcode_pc = resume_data.frames[0].pc;
let mut recipes: Vec<ReconstructRecipe> =
Vec::with_capacity(resume_data.frames.len() - 1);
let mut ok = root_pc_valid;
Expand Down Expand Up @@ -9027,7 +9030,7 @@ impl JitState for PyreJitState {
}
ctx.set_bridge_inline_carrier(BridgeInlineCarrier {
root_pc,
root_jitcode_pc,
root_jitcode_index,
recipes,
});
}
Expand Down Expand Up @@ -12791,8 +12794,11 @@ pub(crate) fn assemble_bridge_inline_pending(
for k in nlocals..valuestackdepth {
concrete_frame.push(recipe_slot_to_pyobj(recipe.concrete_r[k]));
}
// last_instr = recipe.pc - 1 so next_instr() resumes AT recipe.pc.
concrete_frame.set_last_instr_from_next_instr(recipe.pc);
// last_instr is one before the recipe's Python pc so next_instr() resumes there.
concrete_frame
.set_last_instr_from_next_instr(
backxlat_py_pc(recipe.jitcode_index, recipe.jitcode_pc) as usize
);

// Symbolic side: mirror the FAST branch field-for-field.
let mut sym = PyreSym::new_uninit(OpRef::NONE);
Expand Down
Loading
Loading