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/