From bcf5c1cdc4998bd6019c771eb8d50d6ca24d10f2 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Tue, 11 Feb 2025 16:11:02 -0800 Subject: Generate working putnil-leave using the backend --- zjit/src/asm/mod.rs | 5 +++++ zjit/src/codegen.rs | 23 +++++++++++++++++++++++ zjit/src/lib.rs | 10 ++++------ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 zjit/src/codegen.rs diff --git a/zjit/src/asm/mod.rs b/zjit/src/asm/mod.rs index a9d4621b1e..a95569a011 100644 --- a/zjit/src/asm/mod.rs +++ b/zjit/src/asm/mod.rs @@ -130,6 +130,11 @@ impl CodeBlock { // self.dropped_bytes = true; // retry emitting the Insn after next_page //} } + + /// Make all the code in the region executable. Call this at the end of a write session. + pub fn mark_all_executable(&mut self) { + self.mem_block.borrow_mut().mark_all_executable(); + } } impl crate::virtualmem::CodePtrBase for CodeBlock { diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs new file mode 100644 index 0000000000..19b09e4456 --- /dev/null +++ b/zjit/src/codegen.rs @@ -0,0 +1,23 @@ +use crate::{asm::CodeBlock, backend::ir::*, cruby::*}; + +/// Compile code that pops a frame and returns Qnil +pub fn gen_leave(cb: &mut CodeBlock) { + let mut asm = Assembler::new(); + + // rdi: EC, rsi: CFP + let ec = C_ARG_OPNDS[0]; + let cfp = C_ARG_OPNDS[1]; + + // Pop frame: CFP = CFP + RUBY_SIZEOF_CONTROL_FRAME + let incr_cfp = asm.add(cfp, RUBY_SIZEOF_CONTROL_FRAME.into()); + asm.mov(cfp, incr_cfp); + + // Set ec->cfp: *(EC + RUBY_OFFSET_EC_CFP) = CFP + asm.mov(Opnd::mem(64, ec, RUBY_OFFSET_EC_CFP), cfp); + + // Return Qnil + asm.cret(Qnil.into()); + + asm.compile_with_regs(cb, Assembler::get_alloc_regs()); + cb.mark_all_executable(); +} diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs index b50eb720f5..b557602ccc 100644 --- a/zjit/src/lib.rs +++ b/zjit/src/lib.rs @@ -4,6 +4,7 @@ mod state; mod cruby; mod ir; +mod codegen; mod stats; mod utils; mod virtualmem; @@ -12,6 +13,7 @@ mod backend; mod disasm; mod options; +use codegen::gen_leave; use state::ZJITState; #[cfg(feature = "disasm")] use options::get_option; @@ -80,7 +82,7 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co let cb = ZJITState::get_code_block(); let start_ptr = cb.get_write_ptr(); - //x86_emit(cb); + gen_leave(cb); #[cfg(feature = "disasm")] if get_option!(dump_disasm) { @@ -89,9 +91,5 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co println!("{}", disasm); } - if cfg!(target_arch = "x86_64") { - start_ptr.raw_ptr(cb) - } else { - std::ptr::null() - } + start_ptr.raw_ptr(cb) } -- cgit v1.2.3