@@ -135,7 +135,7 @@ impl std::fmt::Display for BlockId {
135135
136136type InsnSet = BitSet<InsnId>;
137137type BlockSet = BitSet<BlockId>;
138- /// Set of indices into a frame's local table. Always sized to [`FrameState::locals`].
138+ /// Set of indices into a frame's local table. Always sized to [`field@ FrameState::locals`].
139139pub type LocalSet = BitSet<usize>;
140140
141141fn write_vec<T: std::fmt::Display>(f: &mut std::fmt::Formatter, objs: &Vec<T>) -> std::fmt::Result {
@@ -3282,7 +3282,7 @@ impl Function {
32823282 fn set_snapshot_spilled_locals(&mut self, insn_id: InsnId, spilled: LocalSet) {
32833283 let insn_id = self.union_find.borrow().find_const(insn_id);
32843284 match &mut self.insns[insn_id] {
3285- Insn::Snapshot { state } => state.set_spilled_locals( spilled) ,
3285+ Insn::Snapshot { state } => state.spilled_locals = spilled,
32863286 insn => panic!("Unexpected non-Snapshot {insn} when setting spilled locals"),
32873287 }
32883288 }
@@ -8104,6 +8104,11 @@ pub struct FrameState {
81048104 stack: Vec<InsnId>,
81058105 locals: Vec<InsnId>,
81068106
8107+ /// The subset of locals that must be in EP memory prior to a safepoint.
8108+ ///
8109+ /// Predominatedly used for with-block sends for locals syntatically accessed within the block.
8110+ spilled_locals: LocalSet,
8111+
81078112 /// `InsnId` of the caller's post-send `Snapshot` for inlined frames; `None`
81088113 /// for non-inlined frames. Stored as an instruction reference rather than
81098114 /// an owned `FrameState` so that value remapping in the caller's `Snapshot`
@@ -8117,17 +8122,6 @@ pub struct FrameState {
81178122 /// `cfp->jit_return` values do not alias across the shared native stack frame.
81188123 /// This value's upper bound is the `inline_max_iterations` value.
81198124 pub depth: InlineDepth,
8120-
8121- /// Locals codegen has spilled to memory, making the memory slot authoritative.
8122- /// Such a local is read or written by the block through this frame's EP.
8123- ///
8124- /// Two consumers depend on this: codegen spills exactly these before a
8125- /// block-passing call, and the stack map skips them so materialization does
8126- /// not overwrite a block's write with a stale register value.
8127- ///
8128- /// Empty for frames not suspended at a block-passing call (including inlined
8129- /// caller frames, whose block writes update registers directly).
8130- spilled_locals: LocalSet,
81318125}
81328126
81338127impl FrameState {
@@ -8218,18 +8212,10 @@ impl FrameState {
82188212 self.locals.iter()
82198213 }
82208214
8221- /// Local indices kept authoritative in EP for this frame's pending
8222- /// block-passing call. See the field docs on [`FrameState::spilled_locals`].
82238215 pub fn spilled_locals(&self) -> &LocalSet {
82248216 &self.spilled_locals
82258217 }
82268218
8227- /// Record the locals that must stay in EP across this frame's pending
8228- /// block-passing call (block-modifiable locals). See [`FrameState::spilled_locals`].
8229- fn set_spilled_locals(&mut self, spilled: LocalSet) {
8230- self.spilled_locals = spilled;
8231- }
8232-
82338219 /// Push a stack operand
82348220 fn stack_push(&mut self, opnd: InsnId) {
82358221 self.stack.push(opnd);
0 commit comments