@@ -297,10 +297,10 @@ pub enum Insn {
297297 //SetIvar {},
298298 //GetIvar {},
299299
300- // Own a FrameStateId so that instructions can look up their dominating FrameStateId when
300+ // Own a FrameState so that instructions can look up their dominating FrameState when
301301 // generating deopt side-exits and frame reconstruction metadata. Does not directly generate
302302 // any code.
303- Snapshot { state : FrameStateId } ,
303+ Snapshot { state : FrameState } ,
304304
305305 // Unconditional jump
306306 Jump ( BranchEdge ) ,
@@ -316,19 +316,19 @@ pub enum Insn {
316316
317317 // Send without block with dynamic dispatch
318318 // Ignoring keyword arguments etc for now
319- SendWithoutBlock { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , args : Vec < InsnId > , state : FrameStateId } ,
320- Send { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , blockiseq : IseqPtr , args : Vec < InsnId > , state : FrameStateId } ,
321- SendWithoutBlockDirect { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , iseq : IseqPtr , args : Vec < InsnId > , state : FrameStateId } ,
319+ SendWithoutBlock { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , args : Vec < InsnId > , state : InsnId } ,
320+ Send { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , blockiseq : IseqPtr , args : Vec < InsnId > , state : InsnId } ,
321+ SendWithoutBlockDirect { self_val : InsnId , call_info : CallInfo , cd : * const rb_call_data , iseq : IseqPtr , args : Vec < InsnId > , state : InsnId } ,
322322
323323 // Control flow instructions
324324 Return { val : InsnId } ,
325325
326326 /// Fixnum +, -, *, /, %, ==, !=, <, <=, >, >=
327- FixnumAdd { left : InsnId , right : InsnId , state : FrameStateId } ,
328- FixnumSub { left : InsnId , right : InsnId , state : FrameStateId } ,
329- FixnumMult { left : InsnId , right : InsnId , state : FrameStateId } ,
330- FixnumDiv { left : InsnId , right : InsnId , state : FrameStateId } ,
331- FixnumMod { left : InsnId , right : InsnId , state : FrameStateId } ,
327+ FixnumAdd { left : InsnId , right : InsnId , state : InsnId } ,
328+ FixnumSub { left : InsnId , right : InsnId , state : InsnId } ,
329+ FixnumMult { left : InsnId , right : InsnId , state : InsnId } ,
330+ FixnumDiv { left : InsnId , right : InsnId , state : InsnId } ,
331+ FixnumMod { left : InsnId , right : InsnId , state : InsnId } ,
332332 FixnumEq { left : InsnId , right : InsnId } ,
333333 FixnumNeq { left : InsnId , right : InsnId } ,
334334 FixnumLt { left : InsnId , right : InsnId } ,
@@ -337,9 +337,9 @@ pub enum Insn {
337337 FixnumGe { left : InsnId , right : InsnId } ,
338338
339339 /// Side-exit if val doesn't have the expected type.
340- GuardType { val : InsnId , guard_type : Type , state : FrameStateId } ,
340+ GuardType { val : InsnId , guard_type : Type , state : InsnId } ,
341341 /// Side-exit if val is not the expected VALUE.
342- GuardBitEquals { val : InsnId , expected : VALUE , state : FrameStateId } ,
342+ GuardBitEquals { val : InsnId , expected : VALUE , state : InsnId } ,
343343
344344 /// Generate no code (or padding if necessary) and insert a patch point
345345 /// that can be rewritten to a side exit when the Invariant is broken.
@@ -581,7 +581,6 @@ pub struct Function {
581581 insn_types : Vec < Type > ,
582582 blocks : Vec < Block > ,
583583 entry_block : BlockId ,
584- frame_states : Vec < FrameState > ,
585584}
586585
587586impl Function {
@@ -593,7 +592,6 @@ impl Function {
593592 union_find : UnionFind :: new ( ) ,
594593 blocks : vec ! [ Block :: default ( ) ] ,
595594 entry_block : BlockId ( 0 ) ,
596- frame_states : vec ! [ ] ,
597595 }
598596 }
599597
@@ -628,17 +626,12 @@ impl Function {
628626 self . insns . len ( )
629627 }
630628
631- /// Store the given FrameState on the Function so that it can be cheaply referenced by
632- /// instructions.
633- fn push_frame_state ( & mut self , state : FrameState ) -> FrameStateId {
634- let id = FrameStateId ( self . frame_states . len ( ) ) ;
635- self . frame_states . push ( state) ;
636- id
637- }
638-
639- /// Return a reference to the FrameState at the given index.
640- pub fn frame_state ( & self , id : FrameStateId ) -> & FrameState {
641- & self . frame_states [ id. 0 ]
629+ /// Return a reference to the FrameState at the given instruction index.
630+ pub fn frame_state ( & self , insn_id : InsnId ) -> & FrameState {
631+ match & self . insns [ insn_id. 0 ] {
632+ Insn :: Snapshot { state } => state,
633+ insn => panic ! ( "Unexpected non-Snapshot {insn} when looking up FrameState" ) ,
634+ }
642635 }
643636
644637 fn new_block ( & mut self ) -> BlockId {
@@ -872,7 +865,7 @@ impl Function {
872865 for insn_id in old_insns {
873866 match self . find ( insn_id) {
874867 Insn :: SendWithoutBlock { self_val, call_info, cd, args, state } => {
875- let frame_state = & self . frame_states [ state. 0 ] ;
868+ let frame_state = self . frame_state ( state) ;
876869 let self_type = match payload. get_operand_types ( frame_state. insn_idx ) {
877870 Some ( [ self_type, ..] ) if self_type. is_top_self ( ) => self_type,
878871 _ => { self . push_insn_id ( block, insn_id) ; continue ; }
@@ -1108,9 +1101,6 @@ impl FrameState {
11081101 }
11091102}
11101103
1111- #[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug ) ]
1112- pub struct FrameStateId ( pub usize ) ;
1113-
11141104/// Compute the index of a local variable from its slot index
11151105fn ep_offset_to_local_idx ( iseq : IseqPtr , ep_offset : u32 ) -> usize {
11161106 // Layout illustration
@@ -1315,8 +1305,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
13151305 // Get the current pc and opcode
13161306 let pc = unsafe { rb_iseq_pc_at_idx ( iseq, insn_idx. into ( ) ) } ;
13171307 state. pc = pc;
1318- let exit_state = fun. push_frame_state ( state. clone ( ) ) ;
1319- fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
1308+ let exit_state = fun. push_insn ( block, Insn :: Snapshot { state : state. clone ( ) } ) ;
13201309
13211310 // try_into() call below is unfortunate. Maybe pick i32 instead of usize for opcodes.
13221311 let opcode: u32 = unsafe { rb_iseq_opcode_at_pc ( iseq, pc) }
@@ -1572,7 +1561,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
15721561}
15731562
15741563/// Generate guards for two fixnum outputs
1575- fn guard_two_fixnums ( state : & mut FrameState , exit_state : FrameStateId , fun : & mut Function , block : BlockId ) -> Result < ( InsnId , InsnId ) , ParseError > {
1564+ fn guard_two_fixnums ( state : & mut FrameState , exit_state : InsnId , fun : & mut Function , block : BlockId ) -> Result < ( InsnId , InsnId ) , ParseError > {
15761565 let left = fun. push_insn ( block, Insn :: GuardType { val : state. stack_opnd ( 1 ) ?, guard_type : Fixnum , state : exit_state } ) ;
15771566 let right = fun. push_insn ( block, Insn :: GuardType { val : state. stack_opnd ( 0 ) ?, guard_type : Fixnum , state : exit_state } ) ;
15781567
0 commit comments