[前][次][番号順一覧][スレッド一覧]

ruby-changes:73124

From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 00:53:36 +0900 (JST)
Subject: [ruby-changes:73124] 03ed50310d (master): Have Assembler::compile() return a list of GC offsets

https://git.ruby-lang.org/ruby.git/commit/?id=03ed50310d

From 03ed50310d772e555f819a4b321e4d6593161233 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Tue, 7 Jun 2022 16:27:10 -0400
Subject: Have Assembler::compile() return a list of GC offsets

---
 yjit/src/backend/arm64/mod.rs  | 15 ++++++++-------
 yjit/src/backend/ir.rs         | 39 +++++++++++++++++----------------------
 yjit/src/backend/x86_64/mod.rs | 21 +++++++++++++--------
 yjit/src/codegen.rs            | 11 ++++-------
 yjit/src/core.rs               |  1 +
 5 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs
index f16f9c0f63..8685117c5f 100644
--- a/yjit/src/backend/arm64/mod.rs
+++ b/yjit/src/backend/arm64/mod.rs
@@ -33,31 +33,32 @@ impl From<Opnd> for A64Opnd { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/arm64/mod.rs#L33
 
 impl Assembler
 {
-    // Get the list of registers from which we can allocate on this platform
+    /// Get the list of registers from which we can allocate on this platform
     pub fn get_scratch_regs() -> Vec<Reg>
     {
         vec![X12_REG, X13_REG]
     }
 
-    // Split platform-specific instructions
+    /// Split platform-specific instructions
     fn arm64_split(mut self) -> Assembler
     {
         todo!();
     }
 
-    // Emit platform-specific machine code
-    pub fn arm64_emit(&mut self, jit: &mut JITState, cb: &mut CodeBlock)
+    /// Emit platform-specific machine code
+    /// Returns a list of GC offsets
+    pub fn arm64_emit(&mut self, cb: &mut CodeBlock) -> Vec<u32>
     {
         todo!();
     }
 
-    // Optimize and compile the stored instructions
-    pub fn compile_with_regs(self, jit: &mut JITState, cb: &mut CodeBlock, regs: Vec<Reg>)
+    /// Optimize and compile the stored instructions
+    pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>)
     {
         self
             .arm64_split()
             .split_loads()
             .alloc_regs(regs)
-            .arm64_emit(jit, cb);
+            .arm64_emit(jit, cb)
     }
 }
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index 3fe9b8d2ec..09ce6b4d6c 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -619,10 +619,12 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L619
     }
 
     /// Compile the instructions down to machine code
-    pub fn compile(self, jit: &mut JITState, cb: &mut CodeBlock)
+    /// NOTE: should compile return a list of block labels to enable
+    ///       compiling multiple blocks at a time?
+    pub fn compile(self, cb: &mut CodeBlock) -> Vec<u32>
     {
         let scratch_regs = Self::get_scratch_regs();
-        self.compile_with_regs(jit, cb, scratch_regs);
+        self.compile_with_regs(cb, scratch_regs)
     }
 }
 
@@ -831,18 +833,11 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L833
         assert_eq!(result.insns[5].out, Opnd::Reg(regs[0]));
     }
 
-    fn setup_asm(num_regs: usize) -> (Assembler, JITState, CodeBlock, Vec<Reg>) {
-        let blockid = BlockId {
-            iseq: std::ptr::null(),
-            idx: 0,
-        };
-        let block = Block::new(blockid, &Context::default());
-
+    fn setup_asm(num_regs: usize) -> (Assembler, CodeBlock, Vec<Reg>) {
         let mut regs = Assembler::get_scratch_regs();
 
         return (
             Assembler::new(),
-            JITState::new(&block),
             CodeBlock::new_dummy(1024),
             regs.drain(0..num_regs).collect()
         );
@@ -852,50 +847,50 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L847
     #[test]
     fn test_compile()
     {
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(1);
+        let (mut asm, mut cb, regs) = setup_asm(1);
 
         let out = asm.add(Opnd::Reg(regs[0]), Opnd::UImm(2));
         asm.add(out, Opnd::UImm(2));
 
-        asm.compile(&mut jit, &mut cb);
+        asm.compile(&mut cb);
     }
 
     // Test memory-to-memory move
     #[test]
     fn test_mov_mem2mem()
     {
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(1);
+        let (mut asm, mut cb, regs) = setup_asm(1);
 
         asm.comment("check that comments work too");
         asm.mov(Opnd::mem(64, SP, 0), Opnd::mem(64, SP, 8));
 
-        asm.compile_with_regs(&mut jit, &mut cb, regs);
+        asm.compile_with_regs(&mut cb, regs);
     }
 
     // Test load of register into new register
     #[test]
     fn test_load_reg()
     {
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(1);
+        let (mut asm, mut cb, regs) = setup_asm(1);
 
         let out = asm.load(SP);
         asm.mov(Opnd::mem(64, SP, 0), out);
 
-        asm.compile_with_regs(&mut jit, &mut cb, regs);
+        asm.compile_with_regs(&mut cb, regs);
     }
 
     // Multiple registers needed and register reuse
     #[test]
     fn test_reuse_reg()
     {
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(2);
+        let (mut asm, mut cb, regs) = setup_asm(2);
 
         let v0 = asm.add(Opnd::mem(64, SP, 0), Opnd::UImm(1));
         let v1 = asm.add(Opnd::mem(64, SP, 8), Opnd::UImm(1));
         let v2 = asm.add(v0, Opnd::UImm(1));
         asm.add(v0, v2);
 
-        asm.compile_with_regs(&mut jit, &mut cb, regs);
+        asm.compile_with_regs(&mut cb, regs);
     }
 
     #[test]
@@ -905,24 +900,24 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L900
         {
         }
 
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(2);
+        let (mut asm, mut cb, regs) = setup_asm(2);
 
         asm.ccall(
             dummy_c_fun as *const u8,
             vec![Opnd::mem(64, SP, 0), Opnd::UImm(1)]
         );
 
-        asm.compile_with_regs(&mut jit, &mut cb, regs);
+        asm.compile_with_regs(&mut cb, regs);
     }
 
     #[test]
     fn test_lea_ret()
     {
-        let (mut asm, mut jit, mut cb, regs) = setup_asm(1);
+        let (mut asm, mut cb, regs) = setup_asm(1);
 
         let addr = asm.lea(Opnd::mem(64, SP, 0));
         asm.cret(addr);
 
-        asm.compile_with_regs(&mut jit, &mut cb, regs);
+        asm.compile_with_regs(&mut cb, regs);
     }
 }
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs
index 66f6beefc9..d0f57d908f 100644
--- a/yjit/src/backend/x86_64/mod.rs
+++ b/yjit/src/backend/x86_64/mod.rs
@@ -49,7 +49,7 @@ impl From<Opnd> for X86Opnd { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L49
 
 impl Assembler
 {
-    // Get the list of registers from which we can allocate on this platform
+    /// Get the list of registers from which we can allocate on this platform
     pub fn get_scratch_regs() -> Vec<Reg>
     {
         vec![
@@ -58,7 +58,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L58
         ]
     }
 
-    // Emit platform-specific machine code
+    /// Emit platform-specific machine code
     fn x86_split(mut self) -> Assembler
     {
         let live_ranges: Vec<usize> = std::mem::take(&mut self.live_ranges);
@@ -92,9 +92,12 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L92
         })
     }
 
-    // Emit platform-specific machine code
-    pub fn x86_emit(&mut self, jit: &mut JITState, cb: &mut CodeBlock)
+    /// Emit platform-specific machine code
+    pub fn x86_emit(&mut self, cb: &mut CodeBlock) -> Vec<u32>
     {
+        // List of GC offsets
+        let mut gc_offsets: Vec<u32> = Vec::new();
+
         // For each instruction
         for insn in &self.insns {
             match insn.op {
@@ -120,7 +123,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L123
                         if !val.special_const_p() {
                             // The pointer immediate is encoded as the last part of the mov written out
                             let ptr_offset: u32 = (cb.get_write_pos() as u32) - (SIZEOF_VALUE as u32);
-                            jit.add_gc_obj_offset(ptr_offset);
+                            gc_offsets.push(ptr_offset);
                         }
                     }
                 },
@@ -162,15 +165,17 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L165
                 _ => panic!("unsupported instruction passed to x86 backend: {:?}", insn.op)
             };
         }
+
+        gc_offsets
     }
 
-    // Optimize and compile the stored instructions
-    pub fn compile_with_regs(self, jit: &mut JITState, cb: &mut CodeBlock, regs: Vec<Reg>)
+    /// Optimize and compile the stored instructions
+    pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>) -> Vec<u32>
     {
         self
         .x86_split()
         .split_loads()
         .alloc_regs(regs)
-        .x86_emit(jit, cb);
+        .x86_emit(cb)
     }
 }
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 99436d5f06..d6f8b34596 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -118,12 +118,6 @@ impl JITState { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L118
         self.opcode
     }
 
-    pub fn add_gc_obj_offset(self: &mut JITState, ptr_offset: u32) {
-        let mut gc_obj_vec: RefMut<_> = self.block.borrow_mut();
-        gc_obj_vec.add_gc_obj_offset(ptr_offset);
-        incr_counter!(num_gc_obj_refs);
-    }
-
     pub fn get_pc(self: &JITState) -> *mut VALUE {
         self.pc
     }
@@ -838,10 +832,13 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L832
     // Finish filling out the block
     {
         // Compile code into the code block
-        asm.compile(&mut jit, cb);
+        let gc_offsets = asm.compile(cb);
 
         let mut block = jit.block.borrow_mut();
 
+        // Add the GC offsets to the block
+        gc_offsets.iter().map(|offs| { block.add_gc_obj_offset(*offs) });
+
         // Mark the end  (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]