summaryrefslogtreecommitdiff
path: root/zjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2025-02-10 17:12:31 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2025-04-18 21:52:57 +0900
commit9c267256d896125a2aea4be8609ec415ff7760ef (patch)
tree8748691ef4902c78ed17b98033116a9f1aa518ce /zjit
parente28ab5480e457b54681b4b23b1081a62aec8cb16 (diff)
Stub YJIT-specific implementations in the backend
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13131
Diffstat (limited to 'zjit')
-rw-r--r--zjit/src/asm/arm64/arg/mod.rs2
-rw-r--r--zjit/src/asm/mod.rs9
-rw-r--r--zjit/src/asm/x86_64/mod.rs4
-rw-r--r--zjit/src/backend.rs31
-rw-r--r--zjit/src/backend/arm64/mod.rs137
-rw-r--r--zjit/src/backend/ir.rs89
-rw-r--r--zjit/src/backend/x86_64/mod.rs122
-rw-r--r--zjit/src/lib.rs3
-rw-r--r--zjit/src/utils.rs13
9 files changed, 225 insertions, 185 deletions
diff --git a/zjit/src/asm/arm64/arg/mod.rs b/zjit/src/asm/arm64/arg/mod.rs
index 0949090d68..9aff99a817 100644
--- a/zjit/src/asm/arm64/arg/mod.rs
+++ b/zjit/src/asm/arm64/arg/mod.rs
@@ -10,6 +10,8 @@ mod sys_reg;
mod truncate;
pub use bitmask_imm::BitmaskImmediate;
+#[cfg(target_arch = "aarch64")]
+pub use condition::Condition;
pub use inst_offset::InstructionOffset;
pub use sf::Sf;
pub use shifted_imm::ShiftedImmediate;
diff --git a/zjit/src/asm/mod.rs b/zjit/src/asm/mod.rs
index b112b2373a..a9d4621b1e 100644
--- a/zjit/src/asm/mod.rs
+++ b/zjit/src/asm/mod.rs
@@ -50,6 +50,10 @@ impl CodeBlock {
}
}
+ pub fn get_write_pos(&self) -> usize {
+ self.write_pos
+ }
+
/// Get a (possibly dangling) direct pointer to the current write position
pub fn get_write_ptr(&self) -> CodePtr {
self.get_ptr(self.write_pos)
@@ -105,6 +109,11 @@ impl CodeBlock {
}
}
+ /// Check if bytes have been dropped (unwritten because of insufficient space)
+ pub fn has_dropped_bytes(&self) -> bool {
+ self.dropped_bytes
+ }
+
// Add a label reference at the current write position
pub fn label_ref(&mut self, _label_idx: usize, _num_bytes: usize, _encode: fn(&mut CodeBlock, i64, i64)) {
// TODO: copy labels
diff --git a/zjit/src/asm/x86_64/mod.rs b/zjit/src/asm/x86_64/mod.rs
index b9b64402d9..c8c9187ea4 100644
--- a/zjit/src/asm/x86_64/mod.rs
+++ b/zjit/src/asm/x86_64/mod.rs
@@ -682,11 +682,10 @@ pub fn call_rel32(cb: &mut CodeBlock, rel32: i32) {
cb.write_bytes(&rel32.to_le_bytes());
}
-/*
/// call - Call a pointer, encode with a 32-bit offset if possible
pub fn call_ptr(cb: &mut CodeBlock, scratch_opnd: X86Opnd, dst_ptr: *const u8) {
if let X86Opnd::Reg(_scratch_reg) = scratch_opnd {
- todo!();
+ // TODO: implement a counter
// Pointer to the end of this call instruction
let end_ptr = cb.get_ptr(cb.write_pos + 5);
@@ -707,7 +706,6 @@ pub fn call_ptr(cb: &mut CodeBlock, scratch_opnd: X86Opnd, dst_ptr: *const u8) {
unreachable!();
}
}
-*/
/// call - Call to label with 32-bit offset
pub fn call_label(cb: &mut CodeBlock, label_idx: usize) {
diff --git a/zjit/src/backend.rs b/zjit/src/backend.rs
deleted file mode 100644
index 01249ba13d..0000000000
--- a/zjit/src/backend.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use crate::{asm::x86_64::{add, mov, ret, RAX_REG, RDI_REG, RSI_REG}, asm::CodeBlock, cruby::{Qnil, RUBY_OFFSET_EC_CFP, RUBY_SIZEOF_CONTROL_FRAME}};
-use crate::asm::x86_64::X86Opnd::Mem;
-use crate::asm::x86_64::X86Opnd::Reg;
-use crate::asm::x86_64::X86Opnd::UImm;
-use crate::asm::x86_64::X86UImm;
-use crate::asm::x86_64::X86Mem;
-
-// Emit x86_64 instructions into CodeBlock
-// TODO: Create a module like YJIT's Assembler and consider putting this there
-pub fn x86_emit(cb: &mut CodeBlock) { // TODO: take our backend IR
- // rdi: EC, rsi: CFP
- let ec = RDI_REG;
- let cfp = RSI_REG;
-
- // Pop frame: CFP = CFP + RUBY_SIZEOF_CONTROL_FRAME
- add(cb, Reg(cfp), UImm(X86UImm { num_bits: 64, value: RUBY_SIZEOF_CONTROL_FRAME as u64 }));
-
- // Set ec->cfp: *(EC + RUBY_OFFSET_EC_CFP) = CFP
- let ec_cfp = X86Mem {
- num_bits: 64,
- base_reg_no: ec.reg_no,
- idx_reg_no: None,
- scale_exp: 0,
- disp: RUBY_OFFSET_EC_CFP,
- };
- mov(cb, Mem(ec_cfp), Reg(cfp));
-
- // Return Qnil
- mov(cb, Reg(RAX_REG), UImm(X86UImm { num_bits: 64, value: Qnil.as_u64() }));
- ret(cb);
-}
diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs
index 66e333f867..42cefca5f2 100644
--- a/zjit/src/backend/arm64/mod.rs
+++ b/zjit/src/backend/arm64/mod.rs
@@ -1,6 +1,6 @@
use std::mem::take;
-use crate::asm::{CodeBlock, OutlinedCb};
+use crate::asm::{CodeBlock};
use crate::asm::arm64::*;
use crate::cruby::*;
use crate::backend::ir::*;
@@ -39,11 +39,14 @@ impl CodeBlock {
pub fn jmp_ptr_bytes(&self) -> usize {
// b instruction's offset is encoded as imm26 times 4. It can jump to
// +/-128MiB, so this can be used when --yjit-exec-mem-size <= 128.
+ /*
let num_insns = if b_offset_fits_bits(self.virtual_region_size() as i64 / 4) {
1 // b instruction
} else {
5 // 4 instructions to load a 64-bit absolute address + br instruction
};
+ */
+ let num_insns = 5; // TODO: support virtual_region_size() check
num_insns * 4
}
@@ -70,7 +73,7 @@ impl From<Opnd> for A64Opnd {
Opnd::CArg(_) => panic!("attempted to lower an Opnd::CArg"),
Opnd::InsnOut { .. } => panic!("attempted to lower an Opnd::InsnOut"),
Opnd::Value(_) => panic!("attempted to lower an Opnd::Value"),
- Opnd::Stack { .. } => panic!("attempted to lower an Opnd::Stack"),
+ //Opnd::Stack { .. } => panic!("attempted to lower an Opnd::Stack"),
Opnd::None => panic!(
"Attempted to lower an Opnd::None. This often happens when an out operand was not allocated for an instruction because the output of the instruction was not used. Please ensure you are using the output."
),
@@ -92,14 +95,18 @@ impl From<&Opnd> for A64Opnd {
/// more than necessary when other_cb jumps from a position early in the page.
/// This invalidates a small range of cb twice, but we accept the small cost.
fn emit_jmp_ptr_with_invalidation(cb: &mut CodeBlock, dst_ptr: CodePtr) {
+ /*
#[cfg(not(test))]
let start = cb.get_write_ptr();
+ */
emit_jmp_ptr(cb, dst_ptr, true);
+ /*
#[cfg(not(test))]
{
let end = cb.get_write_ptr();
unsafe { rb_yjit_icache_invalidate(start.raw_ptr(cb) as _, end.raw_ptr(cb) as _) };
}
+ */
}
fn emit_jmp_ptr(cb: &mut CodeBlock, dst_ptr: CodePtr, padding: bool) {
@@ -280,7 +287,7 @@ impl Assembler
/// do follow that encoding, and if they don't then we load them first.
fn split_bitmask_immediate(asm: &mut Assembler, opnd: Opnd, dest_num_bits: u8) -> Opnd {
match opnd {
- Opnd::Reg(_) | Opnd::CArg(_) | Opnd::InsnOut { .. } | Opnd::Stack { .. } => opnd,
+ Opnd::Reg(_) | Opnd::CArg(_) | Opnd::InsnOut { .. } /*| Opnd::Stack { .. }*/ => opnd,
Opnd::Mem(_) => split_load_operand(asm, opnd),
Opnd::Imm(imm) => {
if imm == 0 {
@@ -327,7 +334,7 @@ impl Assembler
asm.load(opnd)
}
},
- Opnd::None | Opnd::Value(_) | Opnd::Stack { .. } => unreachable!()
+ Opnd::None | Opnd::Value(_) /*| Opnd::Stack { .. }*/ => unreachable!()
}
}
@@ -381,7 +388,7 @@ impl Assembler
}
let live_ranges: Vec<usize> = take(&mut self.live_ranges);
- let mut asm_local = Assembler::new_with_label_names(take(&mut self.label_names), take(&mut self.side_exits), self.num_locals);
+ let mut asm_local = Assembler::new_with_label_names(take(&mut self.label_names));
let asm = &mut asm_local;
let mut iterator = self.into_draining_iter();
@@ -403,9 +410,9 @@ impl Assembler
*opnd = asm.load(*opnd);
}
},
- Opnd::Stack { .. } => {
- *opnd = asm.lower_stack_opnd(opnd);
- }
+ //Opnd::Stack { .. } => {
+ // *opnd = asm.lower_stack_opnd(opnd);
+ //}
_ => {}
};
}
@@ -445,11 +452,12 @@ impl Assembler
if let (Opnd::Reg(_), Opnd::Reg(_), Some(Insn::Mov { dest, src })) = (left, right, iterator.peek()) {
if live_ranges[index] == index + 1 {
// Check after potentially lowering a stack operand to a register operand
- let lowered_dest = if let Opnd::Stack { .. } = dest {
- asm.lower_stack_opnd(dest)
- } else {
- *dest
- };
+ //let lowered_dest = if let Opnd::Stack { .. } = dest {
+ // asm.lower_stack_opnd(dest)
+ //} else {
+ // *dest
+ //};
+ let lowered_dest = *dest;
if out == src && matches!(lowered_dest, Opnd::Reg(_)) {
*out = lowered_dest;
iterator.map_insn_index(asm);
@@ -460,6 +468,7 @@ impl Assembler
asm.push_insn(insn);
}
+ /*
// Lower to Joz and Jonz for generating CBZ/CBNZ for compare-with-0-and-branch.
ref insn @ Insn::Cmp { ref left, right: ref right @ (Opnd::UImm(0) | Opnd::Imm(0)) } |
ref insn @ Insn::Test { ref left, right: ref right @ (Opnd::InsnOut { .. } | Opnd::Reg(_)) } if {
@@ -487,6 +496,7 @@ impl Assembler
iterator.map_insn_index(asm);
iterator.next_unmapped(); // Pop merged jump instruction
}
+ */
Insn::CCall { opnds, fptr, .. } => {
assert!(opnds.len() <= C_ARG_OPNDS.len());
@@ -743,7 +753,7 @@ impl Assembler
/// Emit platform-specific machine code
/// Returns a list of GC offsets. Can return failure to signal caller to retry.
- fn arm64_emit(&mut self, cb: &mut CodeBlock, ocb: &mut Option<&mut OutlinedCb>) -> Result<Vec<u32>, EmitError> {
+ fn arm64_emit(&mut self, cb: &mut CodeBlock) -> Result<Vec<u32>, EmitError> {
/// Determine how many instructions it will take to represent moving
/// this value into a register. Note that the return value of this
/// function must correspond to how many instructions are used to
@@ -833,9 +843,9 @@ impl Assembler
bcond(cb, CONDITION, InstructionOffset::from_bytes(bytes));
});
},
- Target::SideExit { .. } => {
- unreachable!("Target::SideExit should have been compiled by compile_side_exit")
- },
+ //Target::SideExit { .. } => {
+ // unreachable!("Target::SideExit should have been compiled by compile_side_exit")
+ //},
};
}
@@ -845,7 +855,7 @@ impl Assembler
let dst_addr = dst_ptr.as_offset();
let src_addr = cb.get_write_ptr().as_offset();
- if cmp_branch_offset_fits_bits((dst_addr - src_addr) / 4) {
+ if bcond_offset_fits_bits((dst_addr - src_addr) / 4) {
// If the offset fits in one instruction, generate cbz or cbnz
let bytes = (dst_addr - src_addr) as i32;
if branch_if_zero {
@@ -890,6 +900,7 @@ impl Assembler
ldr_post(cb, opnd, A64Opnd::new_mem(64, C_SP_REG, C_SP_STEP));
}
+ /*
/// Compile a side exit if Target::SideExit is given.
fn compile_side_exit(
target: Target,
@@ -904,6 +915,7 @@ impl Assembler
Ok(target)
}
}
+ */
// dbg!(&self.insns);
@@ -914,20 +926,22 @@ impl Assembler
let mut pos_markers: Vec<(usize, CodePtr)> = vec![];
// For each instruction
- let start_write_pos = cb.get_write_pos();
+ //let start_write_pos = cb.get_write_pos();
let mut insn_idx: usize = 0;
while let Some(insn) = self.insns.get(insn_idx) {
- let src_ptr = cb.get_write_ptr();
+ //let src_ptr = cb.get_write_ptr();
let had_dropped_bytes = cb.has_dropped_bytes();
- let old_label_state = cb.get_label_state();
+ //let old_label_state = cb.get_label_state();
let mut insn_gc_offsets: Vec<u32> = Vec::new();
match insn {
- Insn::Comment(text) => {
- cb.add_comment(text);
+ Insn::Comment(_text) => {
+ //cb.add_comment(text);
+ unimplemented!("comments are not supported yet");
},
- Insn::Label(target) => {
- cb.write_label(target.unwrap_label_idx());
+ Insn::Label(_target) => {
+ //cb.write_label(target.unwrap_label_idx());
+ unimplemented!("labels are not supported yet");
},
// Report back the current position in the generated code
Insn::PosMarker(..) => {
@@ -1065,9 +1079,9 @@ impl Assembler
Opnd::CArg { .. } => {
unreachable!("C argument operand was not lowered before arm64_emit");
}
- Opnd::Stack { .. } => {
- unreachable!("Stack operand was not lowered before arm64_emit");
- }
+ //Opnd::Stack { .. } => {
+ // unreachable!("Stack operand was not lowered before arm64_emit");
+ //}
Opnd::None => {
unreachable!("Attempted to load from None operand");
}
@@ -1189,7 +1203,7 @@ impl Assembler
br(cb, opnd.into());
},
Insn::Jmp(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(dst_ptr) => {
emit_jmp_ptr(cb, dst_ptr, true);
},
@@ -1207,42 +1221,43 @@ impl Assembler
b(cb, InstructionOffset::from_bytes(bytes));
});
},
- Target::SideExit { .. } => {
- unreachable!("Target::SideExit should have been compiled by compile_side_exit")
- },
+ //Target::SideExit { .. } => {
+ // unreachable!("Target::SideExit should have been compiled by compile_side_exit")
+ //},
};
},
Insn::Je(target) | Insn::Jz(target) => {
- emit_conditional_jump::<{Condition::EQ}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::EQ}>(cb, *target);
},
Insn::Jne(target) | Insn::Jnz(target) | Insn::JoMul(target) => {
- emit_conditional_jump::<{Condition::NE}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::NE}>(cb, *target);
},
Insn::Jl(target) => {
- emit_conditional_jump::<{Condition::LT}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::LT}>(cb, *target);
},
Insn::Jg(target) => {
- emit_conditional_jump::<{Condition::GT}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::GT}>(cb, *target);
},
Insn::Jge(target) => {
- emit_conditional_jump::<{Condition::GE}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::GE}>(cb, *target);
},
Insn::Jbe(target) => {
- emit_conditional_jump::<{Condition::LS}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::LS}>(cb, *target);
},
Insn::Jb(target) => {
- emit_conditional_jump::<{Condition::CC}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::CC}>(cb, *target);
},
Insn::Jo(target) => {
- emit_conditional_jump::<{Condition::VS}>(cb, compile_side_exit(*target, self, ocb)?);
+ emit_conditional_jump::<{Condition::VS}>(cb, *target);
},
Insn::Joz(opnd, target) => {
- emit_cmp_zero_jump(cb, opnd.into(), true, compile_side_exit(*target, self, ocb)?);
+ emit_cmp_zero_jump(cb, opnd.into(), true, *target);
},
Insn::Jonz(opnd, target) => {
- emit_cmp_zero_jump(cb, opnd.into(), false, compile_side_exit(*target, self, ocb)?);
+ emit_cmp_zero_jump(cb, opnd.into(), false, *target);
},
- Insn::IncrCounter { mem, value } => {
+ Insn::IncrCounter { mem: _, value: _ } => {
+ /*
let label = cb.new_label("incr_counter_loop".to_string());
cb.write_label(label);
@@ -1258,6 +1273,8 @@ impl Assembler
cmp(cb, Self::SCRATCH1, A64Opnd::new_uimm(0));
emit_conditional_jump::<{Condition::NE}>(cb, Target::Label(label));
+ */
+ unimplemented!("labels are not supported yet");
},
Insn::Breakpoint => {
brk(cb, A64Opnd::None);
@@ -1284,16 +1301,14 @@ impl Assembler
}
Insn::LiveReg { .. } => (), // just a reg alloc signal, no code
Insn::PadInvalPatch => {
- while (cb.get_write_pos().saturating_sub(std::cmp::max(start_write_pos, cb.page_start_pos()))) < cb.jmp_ptr_bytes() && !cb.has_dropped_bytes() {
- nop(cb);
- }
+ unimplemented!("we haven't needed padding in ZJIT yet");
}
};
// On failure, jump to the next page and retry the current insn
- if !had_dropped_bytes && cb.has_dropped_bytes() && cb.next_page(src_ptr, emit_jmp_ptr_with_invalidation) {
+ if !had_dropped_bytes && cb.has_dropped_bytes() {
// Reset cb states before retrying the current Insn
- cb.set_label_state(old_label_state);
+ //cb.set_label_state(old_label_state);
// We don't want label references to cross page boundaries. Signal caller for
// retry.
@@ -1324,19 +1339,21 @@ impl Assembler
}
/// Optimize and compile the stored instructions
- pub fn compile_with_regs(self, cb: &mut CodeBlock, ocb: Option<&mut OutlinedCb>, regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
+ pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
let asm = self.arm64_split();
let mut asm = asm.alloc_regs(regs);
// Create label instances in the code block
+ /*
for (idx, name) in asm.label_names.iter().enumerate() {
let label_idx = cb.new_label(name.to_string());
assert!(label_idx == idx);
}
+ */
let start_ptr = cb.get_write_ptr();
+ /*
let starting_label_state = cb.get_label_state();
- let mut ocb = ocb; // for &mut
let emit_result = match asm.arm64_emit(cb, &mut ocb) {
Err(EmitError::RetryOnNextPage) => {
// we want to lower jumps to labels to b.cond instructions, which have a 1 MiB
@@ -1351,29 +1368,32 @@ impl Assembler
}
result => result
};
+ */
+ let emit_result = asm.arm64_emit(cb);
if let (Ok(gc_offsets), false) = (emit_result, cb.has_dropped_bytes()) {
- cb.link_labels();
+ //cb.link_labels();
// Invalidate icache for newly written out region so we don't run stale code.
// It should invalidate only the code ranges of the current cb because the code
// ranges of the other cb might have a memory region that is still PROT_NONE.
- #[cfg(not(test))]
- cb.without_page_end_reserve(|cb| {
- for (start, end) in cb.writable_addrs(start_ptr, cb.get_write_ptr()) {
- unsafe { rb_yjit_icache_invalidate(start as _, end as _) };
- }
- });
+ //#[cfg(not(test))]
+ //cb.without_page_end_reserve(|cb| {
+ // for (start, end) in cb.writable_addrs(start_ptr, cb.get_write_ptr()) {
+ // unsafe { rb_yjit_icache_invalidate(start as _, end as _) };
+ // }
+ //});
Some((start_ptr, gc_offsets))
} else {
- cb.clear_labels();
+ //cb.clear_labels();
None
}
}
}
+/*
#[cfg(test)]
mod tests {
use super::*;
@@ -1828,3 +1848,4 @@ mod tests {
"});
}
}
+*/
diff --git a/zjit/src/backend/ir.rs b/zjit/src/backend/ir.rs
index 75cec765f7..7902df7d9b 100644
--- a/zjit/src/backend/ir.rs
+++ b/zjit/src/backend/ir.rs
@@ -1,14 +1,14 @@
-use std::collections::HashMap;
use std::fmt;
use std::convert::From;
use std::mem::take;
-use crate::codegen::{gen_counted_exit, gen_outlined_exit};
-use crate::cruby::{vm_stack_canary, SIZEOF_VALUE_I32, VALUE, VM_ENV_DATA_SIZE};
+use crate::asm::CodeBlock;
+//use crate::codegen::{gen_counted_exit, gen_outlined_exit};
+use crate::cruby::VALUE;
use crate::virtualmem::CodePtr;
-use crate::asm::{CodeBlock, OutlinedCb};
-use crate::core::{Context, RegMapping, RegOpnd, MAX_CTX_TEMPS};
+//use crate::asm::{CodeBlock, OutlinedCb};
+//use crate::core::{Context, RegMapping, RegOpnd, MAX_CTX_TEMPS};
use crate::options::*;
-use crate::stats::*;
+//use crate::stats::*;
use crate::backend::current::*;
@@ -70,6 +70,7 @@ pub enum Opnd
InsnOut{ idx: usize, num_bits: u8 },
/// Pointer to a slot on the VM stack
+ /*
Stack {
/// Index from stack top. Used for conversion to StackOpnd.
idx: i32,
@@ -84,6 +85,7 @@ pub enum Opnd
/// ctx.reg_mapping when this operand is read. Used for register allocation.
reg_mapping: Option<RegMapping>
},
+ */
// Low-level operands, for lowering
Imm(i64), // Raw signed immediate
@@ -99,7 +101,7 @@ impl fmt::Debug for Opnd {
Self::None => write!(fmt, "None"),
Value(val) => write!(fmt, "Value({val:?})"),
CArg(reg) => write!(fmt, "CArg({reg:?})"),
- Stack { idx, sp_offset, .. } => write!(fmt, "SP[{}]", *sp_offset as i32 - idx - 1),
+ //Stack { idx, sp_offset, .. } => write!(fmt, "SP[{}]", *sp_offset as i32 - idx - 1),
InsnOut { idx, num_bits } => write!(fmt, "Out{num_bits}({idx})"),
Imm(signed) => write!(fmt, "{signed:x}_i64"),
UImm(unsigned) => write!(fmt, "{unsigned:x}_u64"),
@@ -174,7 +176,7 @@ impl Opnd
Opnd::Reg(reg) => Some(Opnd::Reg(reg.with_num_bits(num_bits))),
Opnd::Mem(Mem { base, disp, .. }) => Some(Opnd::Mem(Mem { base, disp, num_bits })),
Opnd::InsnOut { idx, .. } => Some(Opnd::InsnOut { idx, num_bits }),
- Opnd::Stack { idx, stack_size, num_locals, sp_offset, reg_mapping, .. } => Some(Opnd::Stack { idx, num_bits, stack_size, num_locals, sp_offset, reg_mapping }),
+ //Opnd::Stack { idx, stack_size, num_locals, sp_offset, reg_mapping, .. } => Some(Opnd::Stack { idx, num_bits, stack_size, num_locals, sp_offset, reg_mapping }),
_ => None,
}
}
@@ -229,6 +231,7 @@ impl Opnd
Self::match_num_bits_iter(opnds.iter())
}
+ /*
/// Convert Opnd::Stack into RegMapping
pub fn reg_opnd(&self) -> RegOpnd {
self.get_reg_opnd().unwrap()
@@ -251,6 +254,7 @@ impl Opnd
_ => None,
}
}
+ */
}
impl From<usize> for Opnd {
@@ -296,8 +300,8 @@ pub enum Target
{
/// Pointer to a piece of YJIT-generated code
CodePtr(CodePtr),
- /// Side exit with a counter
- SideExit { counter: Counter, context: Option<SideExitContext> },
+ // Side exit with a counter
+ //SideExit { counter: Counter, context: Option<SideExitContext> },
/// Pointer to a side exit code
SideExitPtr(CodePtr),
/// A label within the generated code
@@ -306,9 +310,11 @@ pub enum Target
impl Target
{
+ /*
pub fn side_exit(counter: Counter) -> Target {
Target::SideExit { counter, context: None }
}
+ */
pub fn unwrap_label_idx(&self) -> usize {
match self {
@@ -966,6 +972,7 @@ impl fmt::Debug for Insn {
}
/// Set of variables used for generating side exits
+/*
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SideExitContext {
/// PC of the instruction being compiled
@@ -1012,6 +1019,7 @@ impl SideExitContext {
ctx
}
}
+*/
/// Initial capacity for asm.insns vector
const ASSEMBLER_INSNS_CAPACITY: usize = 256;
@@ -1028,6 +1036,7 @@ pub struct Assembler {
/// Names of labels
pub(super) label_names: Vec<String>,
+ /*
/// Context for generating the current insn
pub ctx: Context,
@@ -1049,10 +1058,17 @@ pub struct Assembler {
/// If true, the next ccall() should verify its leafness
leaf_ccall: bool,
+ */
}
impl Assembler
{
+ /// Create an Assembler
+ pub fn new() -> Self {
+ Self::new_with_label_names(Vec::default())
+ }
+
+ /*
/// Create an Assembler for ISEQ-specific code.
/// It includes all inline code and some outlined code like side exits and stubs.
pub fn new(num_locals: u32) -> Self {
@@ -1064,27 +1080,19 @@ impl Assembler
pub fn new_without_iseq() -> Self {
Self::new_with_label_names(Vec::default(), HashMap::default(), None)
}
+ */
/// Create an Assembler with parameters that are populated by another Assembler instance.
/// This API is used for copying an Assembler for the next compiler pass.
- pub fn new_with_label_names(
- label_names: Vec<String>,
- side_exits: HashMap<SideExitContext, CodePtr>,
- num_locals: Option<u32>
- ) -> Self {
+ pub fn new_with_label_names(label_names: Vec<String>) -> Self {
Self {
insns: Vec::with_capacity(ASSEMBLER_INSNS_CAPACITY),
live_ranges: Vec::with_capacity(ASSEMBLER_INSNS_CAPACITY),
label_names,
- ctx: Context::default(),
- num_locals,
- side_exits,
- side_exit_pc: None,
- side_exit_stack_size: None,
- leaf_ccall: false,
}
}
+ /*
/// Get the list of registers that can be used for stack temps.
pub fn get_temp_regs2() -> &'static [Reg] {
let num_regs = get_option!(num_temp_regs);
@@ -1101,6 +1109,7 @@ impl Assembler
self.side_exit_pc = Some(pc);
self.side_exit_stack_size = Some(stack_size);
}
+ */
/// Build an Opnd::InsnOut from the current index of the assembler and the
/// given number of bits.
@@ -1129,6 +1138,7 @@ impl Assembler
self.live_ranges[idx] = insn_idx;
}
// Set current ctx.reg_mapping to Opnd::Stack.
+ /*
Opnd::Stack { idx, num_bits, stack_size, num_locals, sp_offset, reg_mapping: None } => {
assert_eq!(
self.ctx.get_stack_size() as i16 - self.ctx.get_sp_offset() as i16,
@@ -1145,11 +1155,13 @@ impl Assembler
reg_mapping: Some(self.ctx.get_reg_mapping()),
};
}
+ */
_ => {}
}
}
// Set a side exit context to Target::SideExit
+ /*
if let Some(Target::SideExit { context, .. }) = insn.target_mut() {
// We should skip this when this instruction is being copied from another Assembler.
if context.is_none() {
@@ -1159,11 +1171,13 @@ impl Assembler
));
}
}
+ */
self.insns.push(insn);
self.live_ranges.push(insn_idx);
}
+ /*
/// Get a cached side exit, wrapping a counter if specified
pub fn get_side_exit(&mut self, side_exit_context: &SideExitContext, counter: Option<Counter>, ocb: &mut OutlinedCb) -> Option<CodePtr> {
// Get a cached side exit
@@ -1179,6 +1193,7 @@ impl Assembler
// Wrap a counter if needed
gen_counted_exit(side_exit_context.pc, side_exit, ocb, counter)
}
+ */
/// Create a new label instance that we can jump to
pub fn new_label(&mut self, name: &str) -> Target
@@ -1190,6 +1205,7 @@ impl Assembler
Target::Label(label_idx)
}
+ /*
/// Convert Opnd::Stack to Opnd::Mem or Opnd::Reg
pub fn lower_stack_opnd(&self, opnd: &Opnd) -> Opnd {
// Convert Opnd::Stack to Opnd::Mem
@@ -1345,6 +1361,7 @@ impl Assembler
self.ctx.set_reg_mapping(reg_mapping);
}
}
+ */
// Shuffle register moves, sometimes adding extra moves using SCRATCH_REG,
// so that they will not rewrite each other before they are used.
@@ -1471,7 +1488,7 @@ impl Assembler
let live_ranges: Vec<usize> = take(&mut self.live_ranges);
// shifted_live_ranges is indexed by mapped indexes in insn operands.
let mut shifted_live_ranges: Vec<usize> = live_ranges.clone();
- let mut asm = Assembler::new_with_label_names(take(&mut self.label_names), take(&mut self.side_exits), self.num_locals);
+ let mut asm = Assembler::new_with_label_names(take(&mut self.label_names));
let mut iterator = self.into_draining_iter();
while let Some((index, mut insn)) = iterator.next_mapped() {
@@ -1623,20 +1640,21 @@ impl Assembler
/// Compile the instructions down to machine code.
/// Can fail due to lack of code memory and inopportune code placement, among other reasons.
#[must_use]
- pub fn compile(self, cb: &mut CodeBlock, ocb: Option<&mut OutlinedCb>) -> Option<(CodePtr, Vec<u32>)>
+ pub fn compile(self, cb: &mut CodeBlock) -> Option<(CodePtr, Vec<u32>)>
{
let start_addr = cb.get_write_ptr();
let alloc_regs = Self::get_alloc_regs();
- let ret = self.compile_with_regs(cb, ocb, alloc_regs);
+ let ret = self.compile_with_regs(cb, alloc_regs);
- if let Some(dump_disasm) = get_option_ref!(dump_disasm) {
- use crate::disasm::dump_disasm_addr_range;
+ if get_option!(dump_disasm) {
let end_addr = cb.get_write_ptr();
- dump_disasm_addr_range(cb, start_addr, end_addr, dump_disasm)
+ let disasm = crate::disasm::disasm_addr_range(start_addr.raw_ptr(cb) as usize, end_addr.raw_ptr(cb) as usize);
+ println!("{}", disasm);
}
ret
}
+ /*
/// Compile with a limited number of registers. Used only for unit tests.
#[cfg(test)]
pub fn compile_with_num_regs(self, cb: &mut CodeBlock, num_regs: usize) -> (CodePtr, Vec<u32>)
@@ -1645,12 +1663,14 @@ impl Assembler
let alloc_regs = alloc_regs.drain(0..num_regs).collect();
self.compile_with_regs(cb, None, alloc_regs).unwrap()
}
+ */
/// Consume the assembler by creating a new draining iterator.
pub fn into_draining_iter(self) -> AssemblerDrainingIterator {
AssemblerDrainingIterator::new(self)
}
+ /*
/// Return true if the next ccall() is expected to be leaf.
pub fn get_leaf_ccall(&mut self) -> bool {
self.leaf_ccall
@@ -1660,6 +1680,7 @@ impl Assembler
pub fn expect_leaf_ccall(&mut self) {
self.leaf_ccall = true;
}
+ */
}
/// A struct that allows iterating through an assembler's instructions and
@@ -1760,6 +1781,7 @@ impl Assembler {
}
pub fn ccall(&mut self, fptr: *const u8, opnds: Vec<Opnd>) -> Opnd {
+ /*
// Let vm_check_canary() assert this ccall's leafness if leaf_ccall is set
let canary_opnd = self.set_stack_canary(&opnds);
@@ -1773,11 +1795,13 @@ impl Assembler {
// Temporarily manipulate RegMappings so that we can use registers
// to pass stack operands that are already spilled above.
self.ctx.set_reg_mapping(old_temps);
+ */
// Call a C function
let out = self.next_opnd_out(Opnd::match_num_bits(&opnds));
self.push_insn(Insn::CCall { fptr, opnds, out });
+ /*
// Registers in old_temps may be clobbered by the above C call,
// so rollback the manipulated RegMappings to a spilled version.
self.ctx.set_reg_mapping(new_temps);
@@ -1786,10 +1810,12 @@ impl Assembler {
if let Some(canary_opnd) = canary_opnd {
self.mov(canary_opnd, 0.into());
}
+ */
out
}
+ /*
/// Let vm_check_canary() assert the leafness of this ccall if leaf_ccall is set
fn set_stack_canary(&mut self, opnds: &Vec<Opnd>) -> Option<Opnd> {
// Use the slot right above the stack top for verifying leafness.
@@ -1812,6 +1838,7 @@ impl Assembler {
canary_opnd
}
+ */
pub fn cmp(&mut self, left: Opnd, right: Opnd) {
self.push_insn(Insn::Cmp { left, right });
@@ -1829,7 +1856,7 @@ impl Assembler {
// Re-enable ccall's RegMappings assertion disabled by cpush_all.
// cpush_all + cpop_all preserve all stack temp registers, so it's safe.
- self.set_reg_mapping(self.ctx.get_reg_mapping());
+ //self.set_reg_mapping(self.ctx.get_reg_mapping());
}
pub fn cpop_into(&mut self, opnd: Opnd) {
@@ -1847,7 +1874,7 @@ impl Assembler {
// Temps will be marked back as being in registers by cpop_all.
// We assume that cpush_all + cpop_all are used for C functions in utils.rs
// that don't require spill_regs for GC.
- self.set_reg_mapping(RegMapping::default());
+ //self.set_reg_mapping(RegMapping::default());
}
pub fn cret(&mut self, opnd: Opnd) {
@@ -2089,6 +2116,7 @@ impl Assembler {
out
}
+ /*
/// Verify the leafness of the given block
pub fn with_leaf_ccall<F, R>(&mut self, mut block: F) -> R
where F: FnMut(&mut Self) -> R {
@@ -2098,6 +2126,7 @@ impl Assembler {
self.leaf_ccall = old_leaf_ccall;
ret
}
+ */
/// Add a label at the current position
pub fn write_label(&mut self, target: Target) {
@@ -2115,6 +2144,7 @@ impl Assembler {
/// Macro to use format! for Insn::Comment, which skips a format! call
/// when not dumping disassembly.
+/*
macro_rules! asm_comment {
($asm:expr, $($fmt:tt)*) => {
if $crate::options::get_option_ref!(dump_disasm).is_some() {
@@ -2123,6 +2153,7 @@ macro_rules! asm_comment {
};
}
pub(crate) use asm_comment;
+*/
#[cfg(test)]
mod tests {
diff --git a/zjit/src/backend/x86_64/mod.rs b/zjit/src/backend/x86_64/mod.rs
index c0d42e79e6..17e5a3e605 100644
--- a/zjit/src/backend/x86_64/mod.rs
+++ b/zjit/src/backend/x86_64/mod.rs
@@ -2,10 +2,9 @@ use std::mem::take;
use crate::asm::*;
use crate::asm::x86_64::*;
-use crate::codegen::CodePtr;
+use crate::virtualmem::CodePtr;
use crate::cruby::*;
use crate::backend::ir::*;
-use crate::options::*;
use crate::utils::*;
// Use the x86 register type for this platform
@@ -112,7 +111,7 @@ impl Assembler
fn x86_split(mut self) -> Assembler
{
let live_ranges: Vec<usize> = take(&mut self.live_ranges);
- let mut asm = Assembler::new_with_label_names(take(&mut self.label_names), take(&mut self.side_exits), self.num_locals);
+ let mut asm = Assembler::new_with_label_names(take(&mut self.label_names));
let mut iterator = self.into_draining_iter();
while let Some((index, mut insn)) = iterator.next_unmapped() {
@@ -143,9 +142,9 @@ impl Assembler
let mut opnd_iter = insn.opnd_iter_mut();
while let Some(opnd) = opnd_iter.next() {
- if let Opnd::Stack { .. } = opnd {
- *opnd = asm.lower_stack_opnd(opnd);
- }
+ //if let Opnd::Stack { .. } = opnd {
+ // *opnd = asm.lower_stack_opnd(opnd);
+ //}
unmapped_opnds.push(*opnd);
*opnd = match opnd {
@@ -186,11 +185,12 @@ impl Assembler
// We want to do `dest == left`, but `left` has already gone
// through lower_stack_opnd() while `dest` has not. So we
// lower `dest` before comparing.
- let lowered_dest = if let Opnd::Stack { .. } = dest {
- asm.lower_stack_opnd(dest)
- } else {
- *dest
- };
+ //let lowered_dest = if let Opnd::Stack { .. } = dest {
+ // asm.lower_stack_opnd(dest)
+ //} else {
+ // *dest
+ //};
+ let lowered_dest = *dest;
lowered_dest == *left
} => {
*out = *dest;
@@ -402,7 +402,7 @@ impl Assembler
}
/// Emit platform-specific machine code
- pub fn x86_emit(&mut self, cb: &mut CodeBlock, ocb: &mut Option<&mut OutlinedCb>) -> Option<Vec<u32>>
+ pub fn x86_emit(&mut self, cb: &mut CodeBlock) -> Option<Vec<u32>>
{
/// For some instructions, we want to be able to lower a 64-bit operand
/// without requiring more registers to be available in the register
@@ -432,20 +432,6 @@ impl Assembler
}
}
- /// Compile a side exit if Target::SideExit is given.
- fn compile_side_exit(
- target: Target,
- asm: &mut Assembler,
- ocb: &mut Option<&mut OutlinedCb>,
- ) -> Option<Target> {
- if let Target::SideExit { counter, context } = target {
- let side_exit = asm.get_side_exit(&context.unwrap(), Some(counter), ocb.as_mut().unwrap());
- Some(Target::SideExitPtr(side_exit?))
- } else {
- Some(target)
- }
- }
-
fn emit_csel(
cb: &mut CodeBlock,
truthy: Opnd,
@@ -482,22 +468,24 @@ impl Assembler
let mut pos_markers: Vec<(usize, CodePtr)> = vec![];
// For each instruction
- let start_write_pos = cb.get_write_pos();
+ //let start_write_pos = cb.get_write_pos();
let mut insn_idx: usize = 0;
while let Some(insn) = self.insns.get(insn_idx) {
- let src_ptr = cb.get_write_ptr();
+ //let src_ptr = cb.get_write_ptr();
let had_dropped_bytes = cb.has_dropped_bytes();
- let old_label_state = cb.get_label_state();
+ //let old_label_state = cb.get_label_state();
let mut insn_gc_offsets: Vec<u32> = Vec::new();
match insn {
- Insn::Comment(text) => {
- cb.add_comment(text);
+ Insn::Comment(_text) => {
+ unimplemented!("comments are not supported yet");
+ //cb.add_comment(text);
},
// Write the label at the current position
- Insn::Label(target) => {
- cb.write_label(target.unwrap_label_idx());
+ Insn::Label(_target) => {
+ unimplemented!("labels are not supported yet");
+ //cb.write_label(target.unwrap_label_idx());
},
// Report back the current position in the generated code
@@ -518,17 +506,23 @@ impl Assembler
// Set up RBP to work with frame pointer unwinding
// (e.g. with Linux `perf record --call-graph fp`)
Insn::FrameSetup => {
+ unimplemented!("frames are not supported yet");
+ /*
if get_option!(frame_pointer) {
push(cb, RBP);
mov(cb, RBP, RSP);
push(cb, RBP);
}
+ */
},
Insn::FrameTeardown => {
+ unimplemented!("frames are not supported yet");
+ /*
if get_option!(frame_pointer) {
pop(cb, RBP);
pop(cb, RBP);
}
+ */
},
Insn::Add { left, right, .. } => {
@@ -706,91 +700,91 @@ impl Assembler
// Conditional jump to a label
Insn::Jmp(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jmp_ptr(cb, code_ptr),
Target::Label(label_idx) => jmp_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
Insn::Je(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => je_ptr(cb, code_ptr),
Target::Label(label_idx) => je_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
Insn::Jne(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jne_ptr(cb, code_ptr),
Target::Label(label_idx) => jne_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
Insn::Jl(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jl_ptr(cb, code_ptr),
Target::Label(label_idx) => jl_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jg(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jg_ptr(cb, code_ptr),
Target::Label(label_idx) => jg_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jge(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jge_ptr(cb, code_ptr),
Target::Label(label_idx) => jge_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jbe(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jbe_ptr(cb, code_ptr),
Target::Label(label_idx) => jbe_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jb(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jb_ptr(cb, code_ptr),
Target::Label(label_idx) => jb_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jz(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jz_ptr(cb, code_ptr),
Target::Label(label_idx) => jz_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
Insn::Jnz(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jnz_ptr(cb, code_ptr),
Target::Label(label_idx) => jnz_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
Insn::Jo(target) |
Insn::JoMul(target) => {
- match compile_side_exit(*target, self, ocb)? {
+ match *target {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jo_ptr(cb, code_ptr),
Target::Label(label_idx) => jo_label(cb, label_idx),
- Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
+ //Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
}
@@ -832,17 +826,20 @@ impl Assembler
}
Insn::LiveReg { .. } => (), // just a reg alloc signal, no code
Insn::PadInvalPatch => {
+ unimplemented!("we don't need padding yet");
+ /*
let code_size = cb.get_write_pos().saturating_sub(std::cmp::max(start_write_pos, cb.page_start_pos()));
if code_size < cb.jmp_ptr_bytes() {
nop(cb, (cb.jmp_ptr_bytes() - code_size) as u32);
}
+ */
}
};
// On failure, jump to the next page and retry the current insn
- if !had_dropped_bytes && cb.has_dropped_bytes() && cb.next_page(src_ptr, jmp_ptr) {
+ if !had_dropped_bytes && cb.has_dropped_bytes() {
// Reset cb states before retrying the current Insn
- cb.set_label_state(old_label_state);
+ //cb.set_label_state(old_label_state);
} else {
insn_idx += 1;
gc_offsets.append(&mut insn_gc_offsets);
@@ -867,26 +864,27 @@ impl Assembler
}
/// Optimize and compile the stored instructions
- pub fn compile_with_regs(self, cb: &mut CodeBlock, ocb: Option<&mut OutlinedCb>, regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
+ pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
let asm = self.x86_split();
let mut asm = asm.alloc_regs(regs);
// Create label instances in the code block
+ /*
for (idx, name) in asm.label_names.iter().enumerate() {
let label_idx = cb.new_label(name.to_string());
assert!(label_idx == idx);
}
+ */
- let mut ocb = ocb; // for &mut
let start_ptr = cb.get_write_ptr();
- let gc_offsets = asm.x86_emit(cb, &mut ocb);
+ let gc_offsets = asm.x86_emit(cb);
if let (Some(gc_offsets), false) = (gc_offsets, cb.has_dropped_bytes()) {
- cb.link_labels();
+ //cb.link_labels();
Some((start_ptr, gc_offsets))
} else {
- cb.clear_labels();
+ //cb.clear_labels();
None
}
diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs
index 60fa90d402..d84706d172 100644
--- a/zjit/src/lib.rs
+++ b/zjit/src/lib.rs
@@ -12,7 +12,6 @@ mod backend;
mod disasm;
mod options;
-use backend::x86_emit;
use codegen::ZJITState;
use options::get_option;
use crate::cruby::*;
@@ -80,7 +79,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);
+ //x86_emit(cb);
#[cfg(feature = "disasm")]
if get_option!(dump_disasm) {
diff --git a/zjit/src/utils.rs b/zjit/src/utils.rs
index e69de29bb2..57ee75fdf0 100644
--- a/zjit/src/utils.rs
+++ b/zjit/src/utils.rs
@@ -0,0 +1,13 @@
+/// The `Into<u64>` Rust does not provide.
+/// Convert to u64 with assurance that the value is preserved.
+/// Currently, `usize::BITS == 64` holds for all platforms we support.
+pub(crate) trait IntoU64 {
+ fn as_u64(self) -> u64;
+}
+
+#[cfg(target_pointer_width = "64")]
+impl IntoU64 for usize {
+ fn as_u64(self) -> u64 {
+ self as u64
+ }
+}