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

ruby-changes:73116

From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 00:53:31 +0900 (JST)
Subject: [ruby-changes:73116] 7c83a904a4 (master): Implement gc offset logic

https://git.ruby-lang.org/ruby.git/commit/?id=7c83a904a4

From 7c83a904a49a8ba3a1b78474a6d51a7a32178a4a Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 25 May 2022 15:05:54 -0400
Subject: Implement gc offset logic

---
 yjit/src/asm/x86_64/mod.rs     |  2 +-
 yjit/src/backend/ir.rs         | 68 +++++++++++++++++++++++++++---------------
 yjit/src/backend/x86_64/mod.rs | 30 ++++++++++++++-----
 yjit/src/codegen.rs            | 62 +++++++++++++++++++++++++++++++-------
 yjit/src/core.rs               | 14 ++++-----
 5 files changed, 126 insertions(+), 50 deletions(-)

diff --git a/yjit/src/asm/x86_64/mod.rs b/yjit/src/asm/x86_64/mod.rs
index 1f3dfd2e24..1ada5ffbb7 100644
--- a/yjit/src/asm/x86_64/mod.rs
+++ b/yjit/src/asm/x86_64/mod.rs
@@ -214,7 +214,7 @@ pub const AX:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType: https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/x86_64/mod.rs#L214
 pub const CX:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 1 });
 pub const DX:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 2 });
 pub const BX:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 3 });
-pub const SP:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 4 });
+//pub const SP:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 4 });
 pub const BP:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 5 });
 pub const SI:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 6 });
 pub const DI:   X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 16, reg_type: RegType::GP, reg_no: 7 });
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index 63a0478984..a578564afb 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -9,6 +9,7 @@ use crate::virtualmem::{CodePtr}; https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L9
 use crate::asm::{CodeBlock};
 use crate::asm::x86_64::{X86Opnd, X86Imm, X86UImm, X86Reg, X86Mem, RegType};
 use crate::core::{Context, Type, TempMapping};
+use crate::codegen::{JITState};
 
 #[cfg(target_arch = "x86_64")]
 use crate::backend::x86_64::*;
@@ -16,6 +17,10 @@ use crate::backend::x86_64::*; https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L17
 //#[cfg(target_arch = "aarch64")]
 //use crate::backend:aarch64::*
 
+pub const EC: Opnd = _EC;
+pub const CFP: Opnd = _CFP;
+pub const SP: Opnd = _SP;
+
 /// Instruction opcodes
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum Op
@@ -63,6 +68,9 @@ pub enum Op https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L68
     // A low-level mov instruction. It accepts two operands.
     Mov,
 
+    // Load effective address
+    Lea,
+
     // Bitwise AND test instruction
     Test,
 
@@ -315,7 +323,7 @@ pub struct Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L323
 
     /// Parallel vec with insns
     /// Index of the last insn using the output of this insn
-    pub(super) live_ranges: Vec<usize>
+    pub(super) live_ranges: Vec<usize>,
 }
 
 impl Assembler
@@ -323,7 +331,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L331
     pub fn new() -> Assembler {
         Assembler {
             insns: Vec::default(),
-            live_ranges: Vec::default()
+            live_ranges: Vec::default(),
         }
     }
 
@@ -608,10 +616,10 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L616
     }
 
     /// Compile the instructions down to machine code
-    pub fn compile(self, cb: &mut CodeBlock)
+    pub fn compile(self, jit: &mut JITState, cb: &mut CodeBlock)
     {
         let scratch_regs = Self::get_scratch_regs();
-        self.compile_with_regs(cb, scratch_regs);
+        self.compile_with_regs(jit, cb, scratch_regs);
     }
 }
 
@@ -682,6 +690,7 @@ def_push_2_opnd!(sub, Op::Sub); https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L690
 def_push_2_opnd!(and, Op::And);
 def_push_1_opnd!(load, Op::Load);
 def_push_2_opnd_no_out!(mov, Op::Mov);
+def_push_2_opnd_no_out!(lea, Op::Lea);
 def_push_2_opnd_no_out!(cmp, Op::Cmp);
 def_push_2_opnd_no_out!(test, Op::Test);
 
@@ -690,6 +699,10 @@ def_push_2_opnd_no_out!(test, Op::Test); https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L699
 // They are just wrappers to convert from X86Opnd into the IR Opnd type
 impl Context
 {
+    pub fn ir_sp_opnd(&mut self, idx: isize) -> Opnd {
+        self.sp_opnd(idx).into()
+    }
+
     pub fn ir_stack_opnd(&mut self, idx: i32) -> Opnd {
         self.stack_opnd(idx).into()
     }
@@ -801,62 +814,71 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L814
         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());
+
+        let mut regs = Assembler::get_scratch_regs();
+
+        return (
+            Assembler::new(),
+            JITState::new(&block),
+            CodeBlock::new_dummy(1024),
+            regs.drain(0..num_regs).collect()
+        );
+    }
+
     // Test full codegen pipeline
     #[test]
     fn test_compile()
     {
-        let mut asm = Assembler::new();
-        let mut cb = CodeBlock::new_dummy(1024);
-        let regs = Assembler::get_scratch_regs();
+        let (mut asm, mut jit, 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 cb);
+        asm.compile(&mut jit, &mut cb);
     }
 
     // Test memory-to-memory move
     #[test]
     fn test_mov_mem2mem()
     {
-        let mut asm = Assembler::new();
-        let mut cb = CodeBlock::new_dummy(1024);
-        let regs = Assembler::get_scratch_regs();
+        let (mut asm, mut jit, 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 cb, vec![regs[0]]);
+        asm.compile_with_regs(&mut jit, &mut cb, regs);
     }
 
     // Test load of register into new register
     #[test]
     fn test_load_reg()
     {
-        let mut asm = Assembler::new();
-        let mut cb = CodeBlock::new_dummy(1024);
-        let regs = Assembler::get_scratch_regs();
+        let (mut asm, mut jit, mut cb, regs) = setup_asm(1);
 
         let out = asm.load(SP);
         asm.mov(Opnd::mem(64, SP, 0), out);
 
-        asm.compile_with_regs(&mut cb, vec![regs[0]]);
+        asm.compile_with_regs(&mut jit, &mut cb, regs);
     }
 
     // Multiple registers needed and register reuse
     #[test]
     fn test_reuse_reg()
     {
-        let mut asm = Assembler::new();
-        let mut cb = CodeBlock::new_dummy(1024);
-        let regs = Assembler::get_scratch_regs();
+        let (mut asm, mut jit, 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 cb, vec![regs[0], regs[1]]);
+        asm.compile_with_regs(&mut jit, &mut cb, regs);
     }
 
     #[test]
@@ -866,15 +888,13 @@ mod tests { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L888
         {
         }
 
-        let mut asm = Assembler::new();
-        let mut cb = CodeBlock::new_dummy(1024);
-        let regs = Assembler::get_scratch_regs();
+        let (mut asm, mut jit, 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 cb, vec![regs[0], regs[1]]);
+        asm.compile_with_regs(&mut jit, &mut cb, regs);
     }
 }
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs
index f6a901f77d..f6ebcc5643 100644
--- a/yjit/src/backend/x86_64/mod.rs
+++ b/yjit/src/backend/x86_64/mod.rs
@@ -4,15 +4,17 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L4
 
 use crate::asm::{CodeBlock};
 use crate::asm::x86_64::*;
+use crate::codegen::{JITState};
+use crate::cruby::*;
 use crate::backend::ir::*;
 
 // Use the x86 register type for this platform
 pub type Reg = X86Reg;
 
 // Callee-saved registers
-pub const CFP: Opnd = Opnd::Reg(R13_REG);
-pub const EC: Opnd = Opnd::Reg(R12_REG);
-pub const SP: Opnd = Opnd::Reg(RBX_REG);
+pub const _CFP: Opnd = Opnd::Reg(R13_REG);
+pub const _EC: Opnd = Opnd::Reg(R12_REG);
+pub const _SP: Opnd = Opnd::Reg(RBX_REG);
 
 // C return value register on this platform
 pub const RET_REG: Reg = RAX_REG;
@@ -91,7 +93,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L93
     }
 
     // Emit platform-specific machine code
-    pub fn x86_emit(&self, cb: &mut CodeBlock)
+    pub fn x86_emit(&mut self, jit: &mut JITState, cb: &mut CodeBlock)
     {
         // For each instruction
         for insn in &self.insns {
@@ -107,8 +109,22 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L109
                     add(cb, insn.opnds[0].into(), insn.opnds[1].into())
                 },
 
-                Op::Load => mov(cb, insn.out.into(), insn.opnds[0].into()),
+                //TODO:
                 //Store
+
+                Op::Load => {
+                    mov(cb, insn.out.into(), insn.opnds[0].into());
+
+                    // If the value being loaded is a heapp object
+                    if let Opnd::Value(val) = insn.opnds[0] {
+                        if !val.special_const_p() {
+                            // The pointe (... truncated)

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

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