summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-09-14 15:49:40 -0700
committerGitHub <noreply@github.com>2023-09-14 15:49:40 -0700
commit982d6503b9715d8b2fe07ab6b94b08601a34426d (patch)
tree61554a2b30dcbfc6469c0c81ecec186cf8fcc062
parent0ba6c603bca195064c5530009d72dd42ad42d153 (diff)
YJIT: Skip Insn::Comment and format! if disasm is disabled (#8441)
* YJIT: Skip Insn::Comment and format! if disasm is disabled Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> * YJIT: Get rid of asm.comment --------- Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Notes
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
-rw-r--r--yjit/src/backend/ir.rs21
-rw-r--r--yjit/src/backend/tests.rs2
-rw-r--r--yjit/src/codegen.rs252
-rw-r--r--yjit/src/core.rs20
4 files changed, 151 insertions, 144 deletions
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index 7477f375ac..c61a4e059b 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -1051,7 +1051,7 @@ impl Assembler
/// Append an instruction onto the current list of instructions and update
/// the live ranges of any instructions whose outputs are being used as
/// operands to this instruction.
- pub(super) fn push_insn(&mut self, insn: Insn) {
+ pub fn push_insn(&mut self, insn: Insn) {
// Index of this instruction
let insn_idx = self.insns.len();
@@ -1187,7 +1187,7 @@ impl Assembler
// Spill live stack temps
if self.ctx.get_reg_temps() != RegTemps::default() {
- self.comment(&format!("spill_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), RegTemps::default().as_u8()));
+ asm_comment!(self, "spill_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), RegTemps::default().as_u8());
for stack_idx in 0..u8::min(MAX_REG_TEMPS, self.ctx.get_stack_size()) {
if self.ctx.get_reg_temps().get(stack_idx) {
let idx = self.ctx.get_stack_size() - 1 - stack_idx;
@@ -1227,7 +1227,7 @@ impl Assembler
/// Update which stack temps are in a register
pub fn set_reg_temps(&mut self, reg_temps: RegTemps) {
if self.ctx.get_reg_temps() != reg_temps {
- self.comment(&format!("reg_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), reg_temps.as_u8()));
+ asm_comment!(self, "reg_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), reg_temps.as_u8());
self.ctx.set_reg_temps(reg_temps);
self.verify_reg_temps();
}
@@ -1723,10 +1723,6 @@ impl Assembler {
self.push_insn(Insn::Cmp { left, right });
}
- pub fn comment(&mut self, text: &str) {
- self.push_insn(Insn::Comment(text.to_string()));
- }
-
#[must_use]
pub fn cpop(&mut self) -> Opnd {
let out = self.next_opnd_out(Opnd::DEFAULT_NUM_BITS);
@@ -2002,6 +1998,17 @@ impl Assembler {
}
}
+/// Macro to use format! for Insn::Comment, which skips a format! call
+/// when disasm is not supported.
+macro_rules! asm_comment {
+ ($asm:expr, $($fmt:tt)*) => {
+ if cfg!(feature = "disasm") {
+ $asm.push_insn(Insn::Comment(format!($($fmt)*)));
+ }
+ };
+}
+pub(crate) use asm_comment;
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/yjit/src/backend/tests.rs b/yjit/src/backend/tests.rs
index 8ba9f61d25..985e5a0e94 100644
--- a/yjit/src/backend/tests.rs
+++ b/yjit/src/backend/tests.rs
@@ -87,7 +87,7 @@ fn test_mov_mem2mem()
{
let (mut asm, mut cb) = setup_asm();
- asm.comment("check that comments work too");
+ asm_comment!(asm, "check that comments work too");
asm.mov(Opnd::mem(64, SP, 0), Opnd::mem(64, SP, 8));
asm.compile_with_num_regs(&mut cb, 1);
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index dd4944b362..afa4a4cf6f 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -253,7 +253,7 @@ fn gen_counter_incr(asm: &mut Assembler, counter: Counter) {
assert!(!DEFAULT_COUNTERS.contains(&counter), "gen_counter_incr incremented {:?}", counter);
if get_option!(gen_stats) {
- asm.comment(&format!("increment counter {}", counter.get_name()));
+ asm_comment!(asm, "increment counter {}", counter.get_name());
let ptr = get_counter_ptr(&counter.get_name());
let ptr_reg = asm.load(Opnd::const_ptr(ptr as *const u8));
let counter_opnd = Opnd::mem(64, ptr_reg, 0);
@@ -272,7 +272,7 @@ fn jit_save_pc(jit: &JITState, asm: &mut Assembler) {
pc.offset(cur_insn_len)
};
- asm.comment("save PC to CFP");
+ asm_comment!(asm, "save PC to CFP");
asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), Opnd::const_ptr(ptr as *const u8));
}
@@ -283,7 +283,7 @@ fn jit_save_pc(jit: &JITState, asm: &mut Assembler) {
fn gen_save_sp(asm: &mut Assembler) {
asm.spill_temps();
if asm.ctx.get_sp_offset() != 0 {
- asm.comment("save SP to CFP");
+ asm_comment!(asm, "save SP to CFP");
let stack_pointer = asm.ctx.sp_opnd(0);
let sp_addr = asm.lea(stack_pointer);
asm.mov(SP, sp_addr);
@@ -417,7 +417,7 @@ fn gen_stub_exit(ocb: &mut OutlinedCb) -> CodePtr {
gen_counter_incr(&mut asm, Counter::exit_from_branch_stub);
- asm.comment("exit from branch stub");
+ asm_comment!(asm, "exit from branch stub");
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);
@@ -436,7 +436,7 @@ fn gen_exit(exit_pc: *mut VALUE, asm: &mut Assembler) {
#[cfg(all(feature = "disasm", not(test)))]
{
let opcode = unsafe { rb_vm_insn_addr2opcode((*exit_pc).as_ptr()) };
- asm.comment(&format!("exit to interpreter on {}", insn_name(opcode as usize)));
+ asm_comment!(asm, "exit to interpreter on {}", insn_name(opcode as usize));
}
// Spill stack temps before returning to the interpreter
@@ -527,7 +527,7 @@ pub fn gen_counted_exit(side_exit: CodePtr, ocb: &mut OutlinedCb, counter: Optio
let mut asm = Assembler::new();
// Load the pointer into a register
- asm.comment(&format!("increment counter {}", counter.get_name()));
+ asm_comment!(asm, "increment counter {}", counter.get_name());
let ptr_reg = asm.load(Opnd::const_ptr(get_counter_ptr(&counter.get_name()) as *const u8));
let counter_opnd = Opnd::mem(64, ptr_reg, 0);
@@ -571,7 +571,7 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr {
// This chunk of code expects REG_EC to be filled properly and
// RAX to contain the return value of the C method.
- asm.comment("full cfunc return");
+ asm_comment!(asm, "full cfunc return");
asm.ccall(
rb_full_cfunc_return as *const u8,
vec![EC, C_RET_OPND]
@@ -608,7 +608,7 @@ fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr {
// Every exit to the interpreter should be counted
gen_counter_incr(&mut asm, Counter::leave_interp_return);
- asm.comment("exit from leave");
+ asm_comment!(asm, "exit from leave");
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);
@@ -634,12 +634,12 @@ fn gen_leave_exception(ocb: &mut OutlinedCb) -> CodePtr {
// Every exit to the interpreter should be counted
gen_counter_incr(&mut asm, Counter::leave_interp_return);
- asm.comment("increment SP of the caller");
+ asm_comment!(asm, "increment SP of the caller");
let sp = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP);
let new_sp = asm.add(sp, SIZEOF_VALUE.into());
asm.mov(sp, new_sp);
- asm.comment("exit from exception");
+ asm_comment!(asm, "exit from exception");
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);
@@ -673,7 +673,7 @@ pub fn gen_entry_chain_guard(
let expected_pc = unsafe { rb_iseq_pc_at_idx(iseq, insn_idx.into()) };
let expected_pc_opnd = Opnd::const_ptr(expected_pc as *const u8);
- asm.comment("guard expected PC");
+ asm_comment!(asm, "guard expected PC");
asm.cmp(pc_opnd, expected_pc_opnd);
asm.mark_entry_start(&entry);
@@ -697,9 +697,9 @@ pub fn gen_entry_prologue(
let mut asm = Assembler::new();
if get_option_ref!(dump_disasm).is_some() {
- asm.comment(&format!("YJIT entry point: {}", iseq_get_location(iseq, 0)));
+ asm_comment!(asm, "YJIT entry point: {}", iseq_get_location(iseq, 0));
} else {
- asm.comment("YJIT entry");
+ asm_comment!(asm, "YJIT entry");
}
asm.frame_setup();
@@ -780,7 +780,7 @@ fn gen_check_ints(
) {
// Check for interrupts
// see RUBY_VM_CHECK_INTS(ec) macro
- asm.comment("RUBY_VM_CHECK_INTS(ec)");
+ asm_comment!(asm, "RUBY_VM_CHECK_INTS(ec)");
// Not checking interrupt_mask since it's zero outside finalize_deferred_heap_pages,
// signal_exec, or rb_postponed_job_flush.
@@ -863,8 +863,8 @@ pub fn gen_single_block(
if get_option_ref!(dump_disasm).is_some() {
let blockid_idx = blockid.idx;
let chain_depth = if asm.ctx.get_chain_depth() > 0 { format!("(chain_depth: {})", asm.ctx.get_chain_depth()) } else { "".to_string() };
- asm.comment(&format!("Block: {} {}", iseq_get_location(blockid.iseq, blockid_idx), chain_depth));
- asm.comment(&format!("reg_temps: {:08b}", asm.ctx.get_reg_temps().as_u8()));
+ asm_comment!(asm, "Block: {} {}", iseq_get_location(blockid.iseq, blockid_idx), chain_depth);
+ asm_comment!(asm, "reg_temps: {:08b}", asm.ctx.get_reg_temps().as_u8());
}
// For each instruction to compile
@@ -920,7 +920,7 @@ pub fn gen_single_block(
let mut status = None;
if let Some(gen_fn) = get_gen_fn(VALUE(opcode)) {
// Add a comment for the name of the YARV instruction
- asm.comment(&format!("Insn: {:04} {} (stack_size: {})", insn_idx, insn_name(opcode), asm.ctx.get_stack_size()));
+ asm_comment!(asm, "Insn: {:04} {} (stack_size: {})", insn_idx, insn_name(opcode), asm.ctx.get_stack_size());
// If requested, dump instructions for debugging
if get_option!(dump_insns) {
@@ -1260,7 +1260,7 @@ fn gen_newarray(
let values_ptr = if n == 0 {
Opnd::UImm(0)
} else {
- asm.comment("load pointer to array elements");
+ asm_comment!(asm, "load pointer to array elements");
let offset_magnitude = (SIZEOF_VALUE as u32) * n;
let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize));
asm.lea(values_opnd)
@@ -1412,7 +1412,7 @@ fn guard_object_is_heap(
return;
}
- asm.comment("guard object is heap");
+ asm_comment!(asm, "guard object is heap");
// Test that the object is not an immediate
asm.test(object, (RUBY_IMMEDIATE_MASK as u64).into());
@@ -1444,7 +1444,7 @@ fn guard_object_is_array(
};
guard_object_is_heap(asm, object_reg, object_opnd, counter);
- asm.comment("guard object is array");
+ asm_comment!(asm, "guard object is array");
// Pull out the type mask
let flags_opnd = Opnd::mem(VALUE_BITS, object_reg, RUBY_OFFSET_RBASIC_FLAGS);
@@ -1476,7 +1476,7 @@ fn guard_object_is_string(
};
guard_object_is_heap(asm, object_reg, object_opnd, counter);
- asm.comment("guard object is string");
+ asm_comment!(asm, "guard object is string");
// Pull out the type mask
let flags_reg = asm.load(Opnd::mem(VALUE_BITS, object_reg, RUBY_OFFSET_RBASIC_FLAGS));
@@ -1500,7 +1500,7 @@ fn guard_object_is_not_ruby2_keyword_hash(
object_opnd: Opnd,
counter: Counter,
) {
- asm.comment("guard object is not ruby2 keyword hash");
+ asm_comment!(asm, "guard object is not ruby2 keyword hash");
let not_ruby2_keyword = asm.new_label("not_ruby2_keyword");
asm.test(object_opnd, (RUBY_IMMEDIATE_MASK as u64).into());
@@ -1600,7 +1600,7 @@ fn gen_expandarray(
// Guard on the comptime/expected array length
if comptime_len >= num {
- asm.comment(&format!("guard array length >= {}", num));
+ asm_comment!(asm, "guard array length >= {}", num);
asm.cmp(array_len_opnd, num.into());
jit_chain_guard(
JCC_JB,
@@ -1612,7 +1612,7 @@ fn gen_expandarray(
);
} else {
- asm.comment(&format!("guard array length == {}", comptime_len));
+ asm_comment!(asm, "guard array length == {}", comptime_len);
asm.cmp(array_len_opnd, comptime_len.into());
jit_chain_guard(
JCC_JNE,
@@ -1640,7 +1640,7 @@ fn gen_expandarray(
let offset = i32::try_from(i * (SIZEOF_VALUE as u32)).unwrap();
// Missing elements are Qnil
- asm.comment(&format!("load array[{}]", i));
+ asm_comment!(asm, "load array[{}]", i);
let elem_opnd = if i < comptime_len { Opnd::mem(64, ary_opnd.unwrap(), offset) } else { Qnil.into() };
asm.mov(top, elem_opnd);
}
@@ -2145,7 +2145,7 @@ fn gen_get_ivar(
if !receiver_t_object || uses_custom_allocator || comptime_receiver.shape_too_complex() || megamorphic {
// General case. Call rb_ivar_get().
// VALUE rb_ivar_get(VALUE obj, ID id)
- asm.comment("call rb_ivar_get()");
+ asm_comment!(asm, "call rb_ivar_get()");
// The function could raise exceptions.
jit_prepare_routine_call(jit, asm);
@@ -2186,7 +2186,7 @@ fn gen_get_ivar(
let shape_id_offset = unsafe { rb_shape_id_offset() };
let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset);
- asm.comment("guard shape");
+ asm_comment!(asm, "guard shape");
asm.cmp(shape_opnd, Opnd::UImm(expected_shape as u64));
jit_chain_guard(
JCC_JNE,
@@ -2291,7 +2291,7 @@ fn gen_write_iv(
let ivar_opnd = Opnd::mem(64, recv, offs);
// Write the IV
- asm.comment("write IV");
+ asm_comment!(asm, "write IV");
asm.mov(ivar_opnd, set_value);
} else {
// Compile time value is *not* embedded.
@@ -2302,7 +2302,7 @@ fn gen_write_iv(
// Write the ivar in to the extended table
let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * ivar_index) as i32);
- asm.comment("write IV");
+ asm_comment!(asm, "write IV");
asm.mov(ivar_opnd, set_value);
}
}
@@ -2409,7 +2409,7 @@ fn gen_setinstancevariable(
// then just write out the IV write as a function call.
// too-complex shapes can't use index access, so we use rb_ivar_get for them too.
if !receiver_t_object || uses_custom_allocator || shape_too_complex || new_shape_too_complex || megamorphic {
- asm.comment("call rb_vm_setinstancevariable()");
+ asm_comment!(asm, "call rb_vm_setinstancevariable()");
let ic = jit.get_arg(1).as_u64(); // type IVC
@@ -2444,7 +2444,7 @@ fn gen_setinstancevariable(
let shape_id_offset = unsafe { rb_shape_id_offset() };
let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset);
- asm.comment("guard shape");
+ asm_comment!(asm, "guard shape");
asm.cmp(shape_opnd, Opnd::UImm(expected_shape as u64));
jit_chain_guard(
JCC_JNE,
@@ -2466,7 +2466,7 @@ fn gen_setinstancevariable(
if let Some((current_capacity, new_capacity)) = needs_extension {
// Generate the C call so that runtime code will increase
// the capacity and set the buffer.
- asm.comment("call rb_ensure_iv_list_size");
+ asm_comment!(asm, "call rb_ensure_iv_list_size");
// It allocates so can trigger GC, which takes the VM lock
// so could yield to a different ractor.
@@ -2486,7 +2486,7 @@ fn gen_setinstancevariable(
write_val = asm.stack_pop(1);
gen_write_iv(asm, comptime_receiver, recv, ivar_index, write_val, needs_extension.is_some());
- asm.comment("write shape");
+ asm_comment!(asm, "write shape");
let shape_id_offset = unsafe { rb_shape_id_offset() };
let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset);
@@ -2518,7 +2518,7 @@ fn gen_setinstancevariable(
asm.cmp(write_val, Qnil.into());
asm.jbe(skip_wb);
- asm.comment("write barrier");
+ asm_comment!(asm, "write barrier");
asm.ccall(
rb_gc_writebarrier as *const u8,
vec![
@@ -2630,7 +2630,7 @@ fn gen_definedivar(
let shape_id_offset = unsafe { rb_shape_id_offset() };
let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset);
- asm.comment("guard shape");
+ asm_comment!(asm, "guard shape");
asm.cmp(shape_opnd, Opnd::UImm(shape_id as u64));
jit_chain_guard(
JCC_JNE,
@@ -2746,19 +2746,19 @@ fn guard_two_fixnums(
let arg0_type = asm.ctx.get_opnd_type(arg0.into());
if arg0_type.is_heap() || arg1_type.is_heap() {
- asm.comment("arg is heap object");
+ asm_comment!(asm, "arg is heap object");
asm.jmp(Target::side_exit(counter));
return;
}
if arg0_type != Type::Fixnum && arg0_type.is_specific() {
- asm.comment("arg0 not fixnum");
+ asm_comment!(asm, "arg0 not fixnum");
asm.jmp(Target::side_exit(counter));
return;
}
if arg1_type != Type::Fixnum && arg1_type.is_specific() {
- asm.comment("arg1 not fixnum");
+ asm_comment!(asm, "arg1 not fixnum");
asm.jmp(Target::side_exit(counter));
return;
}
@@ -2770,7 +2770,7 @@ fn guard_two_fixnums(
// If not fixnums at run-time, fall back
if arg0_type != Type::Fixnum {
- asm.comment("guard arg0 fixnum");
+ asm_comment!(asm, "guard arg0 fixnum");
asm.test(arg0, Opnd::UImm(RUBY_FIXNUM_FLAG as u64));
jit_chain_guard(
@@ -2783,7 +2783,7 @@ fn guard_two_fixnums(
);
}
if arg1_type != Type::Fixnum {
- asm.comment("guard arg1 fixnum");
+ asm_comment!(asm, "guard arg1 fixnum");
asm.test(arg1, Opnd::UImm(RUBY_FIXNUM_FLAG as u64));
jit_chain_guard(
@@ -3996,7 +3996,7 @@ fn gen_throw(
}
let val = asm.ccall(rb_vm_throw as *mut u8, vec![EC, CFP, throw_state.into(), throwobj]);
- asm.comment("exit from throw");
+ asm_comment!(asm, "exit from throw");
asm.cpop_into(SP);
asm.cpop_into(EC);
asm.cpop_into(CFP);
@@ -4060,7 +4060,7 @@ fn jit_guard_known_klass(
assert!(!val_type.is_heap());
assert!(val_type.is_unknown());
- asm.comment("guard object is nil");
+ asm_comment!(asm, "guard object is nil");
asm.cmp(obj_opnd, Qnil.into());
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
@@ -4069,7 +4069,7 @@ fn jit_guard_known_klass(
assert!(!val_type.is_heap());
assert!(val_type.is_unknown());
- asm.comment("guard object is true");
+ asm_comment!(asm, "guard object is true");
asm.cmp(obj_opnd, Qtrue.into());
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
@@ -4078,7 +4078,7 @@ fn jit_guard_known_klass(
assert!(!val_type.is_heap());
assert!(val_type.is_unknown());
- asm.comment("guard object is false");
+ asm_comment!(asm, "guard object is false");
assert!(Qfalse.as_i32() == 0);
asm.test(obj_opnd, obj_opnd);
jit_chain_guard(JCC_JNZ, jit, asm, ocb, max_chain_depth, counter);
@@ -4089,7 +4089,7 @@ fn jit_guard_known_klass(
// BIGNUM can be handled by the general else case below
assert!(val_type.is_unknown());
- asm.comment("guard object is fixnum");
+ asm_comment!(asm, "guard object is fixnum");
asm.test(obj_opnd, Opnd::Imm(RUBY_FIXNUM_FLAG as i64));
jit_chain_guard(JCC_JZ, jit, asm, ocb, max_chain_depth, counter);
asm.ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum);
@@ -4100,7 +4100,7 @@ fn jit_guard_known_klass(
if val_type != Type::ImmSymbol || !val_type.is_imm() {
assert!(val_type.is_unknown());
- asm.comment("guard object is static symbol");
+ asm_comment!(asm, "guard object is static symbol");
assert!(RUBY_SPECIAL_SHIFT == 8);
asm.cmp(obj_opnd.with_num_bits(8).unwrap(), Opnd::UImm(RUBY_SYMBOL_FLAG as u64));
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
@@ -4112,7 +4112,7 @@ fn jit_guard_known_klass(
assert!(val_type.is_unknown());
// We will guard flonum vs heap float as though they were separate classes
- asm.comment("guard object is flonum");
+ asm_comment!(asm, "guard object is flonum");
let flag_bits = asm.and(obj_opnd, Opnd::UImm(RUBY_FLONUM_MASK as u64));
asm.cmp(flag_bits, Opnd::UImm(RUBY_FLONUM_FLAG as u64));
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
@@ -4135,7 +4135,7 @@ fn jit_guard_known_klass(
// this situation.
// Also, guarding by identity is incorrect for IO objects because
// IO#reopen can be used to change the class and singleton class of IO objects!
- asm.comment("guard known object with singleton class");
+ asm_comment!(asm, "guard known object with singleton class");
asm.cmp(obj_opnd, sample_instance.into());
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
} else if val_type == Type::CString && unsafe { known_klass == rb_cString } {
@@ -4149,7 +4149,7 @@ fn jit_guard_known_klass(
// Check that the receiver is a heap object
// Note: if we get here, the class doesn't have immediate instances.
if !val_type.is_heap() {
- asm.comment("guard not immediate");
+ asm_comment!(asm, "guard not immediate");
asm.test(obj_opnd, (RUBY_IMMEDIATE_MASK as u64).into());
jit_chain_guard(JCC_JNZ, jit, asm, ocb, max_chain_depth, counter);
asm.cmp(obj_opnd, Qfalse.into());
@@ -4167,7 +4167,7 @@ fn jit_guard_known_klass(
// Bail if receiver class is different from known_klass
// TODO: jit_mov_gc_ptr keeps a strong reference, which leaks the class.
- asm.comment("guard known class");
+ asm_comment!(asm, "guard known class");
asm.cmp(klass_opnd, known_klass.into());
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
@@ -4223,14 +4223,14 @@ fn jit_rb_obj_not(
match recv_opnd.known_truthy() {
Some(false) => {
- asm.comment("rb_obj_not(nil_or_false)");
+ asm_comment!(asm, "rb_obj_not(nil_or_false)");
asm.stack_pop(1);
let out_opnd = asm.stack_push(Type::True);
asm.mov(out_opnd, Qtrue.into());
},
Some(true) => {
// Note: recv_opnd != Type::Nil && recv_opnd != Type::False.
- asm.comment("rb_obj_not(truthy)");
+ asm_comment!(asm, "rb_obj_not(truthy)");
asm.stack_pop(1);
let out_opnd = asm.stack_push(Type::False);
asm.mov(out_opnd, Qfalse.into());
@@ -4254,7 +4254,7 @@ fn jit_rb_true(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("nil? == true");
+ asm_comment!(asm, "nil? == true");
asm.stack_pop(1);
let stack_ret = asm.stack_push(Type::True);
asm.mov(stack_ret, Qtrue.into());
@@ -4272,7 +4272,7 @@ fn jit_rb_false(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("nil? == false");
+ asm_comment!(asm, "nil? == false");
asm.stack_pop(1);
let stack_ret = asm.stack_push(Type::False);
asm.mov(stack_ret, Qfalse.into());
@@ -4316,7 +4316,7 @@ fn jit_rb_kernel_is_a(
}
let sample_is_a = unsafe { rb_obj_is_kind_of(sample_lhs, sample_rhs) == Qtrue };
- asm.comment("Kernel#is_a?");
+ asm_comment!(asm, "Kernel#is_a?");
asm.cmp(asm.stack_opnd(0), sample_rhs.into());
asm.jne(Target::side_exit(Counter::guard_send_is_a_class_mismatch));
@@ -4375,7 +4375,7 @@ fn jit_rb_kernel_instance_of(
let sample_instance_of = sample_lhs_real_class == sample_rhs;
- asm.comment("Kernel#instance_of?");
+ asm_comment!(asm, "Kernel#instance_of?");
asm.cmp(asm.stack_opnd(0), sample_rhs.into());
jit_chain_guard(
JCC_JNE,
@@ -4412,7 +4412,7 @@ fn jit_rb_mod_eqq(
return false;
}
- asm.comment("Module#===");
+ asm_comment!(asm, "Module#===");
// By being here, we know that the receiver is a T_MODULE or a T_CLASS, because Module#=== can
// only live on these objects. With that, we can call rb_obj_is_kind_of() without
// jit_prepare_routine_call() or a control frame push because it can't raise, allocate, or call
@@ -4442,7 +4442,7 @@ fn jit_rb_obj_equal(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("equal?");
+ asm_comment!(asm, "equal?");
let obj1 = asm.stack_pop(1);
let obj2 = asm.stack_pop(1);
@@ -4484,7 +4484,7 @@ fn jit_rb_int_equal(
guard_two_fixnums(jit, asm, ocb);
// Compare the arguments
- asm.comment("rb_int_equal");
+ asm_comment!(asm, "rb_int_equal");
let arg1 = asm.stack_pop(1);
let arg0 = asm.stack_pop(1);
asm.cmp(arg0, arg1);
@@ -4513,7 +4513,7 @@ fn jit_rb_int_mul(
// rb_fix_mul_fix may allocate memory for Bignum
jit_prepare_routine_call(jit, asm);
- asm.comment("Integer#*");
+ asm_comment!(asm, "Integer#*");
let obj = asm.stack_pop(1);
let recv = asm.stack_pop(1);
let ret = asm.ccall(rb_fix_mul_fix as *const u8, vec![recv, obj]);
@@ -4541,7 +4541,7 @@ fn jit_rb_int_div(
// rb_fix_div_fix may GC-allocate for Bignum
jit_prepare_routine_call(jit, asm);
- asm.comment("Integer#/");
+ asm_comment!(asm, "Integer#/");
let obj = asm.stack_pop(1);
let recv = asm.stack_pop(1);
@@ -4626,7 +4626,7 @@ fn jit_rb_int_aref(
}
guard_two_fixnums(jit, asm, ocb);
- asm.comment("Integer#[]");
+ asm_comment!(asm, "Integer#[]");
let obj = asm.stack_pop(1);
let recv = asm.stack_pop(1);
@@ -4656,7 +4656,7 @@ fn jit_rb_str_uplus(
// We allocate when we dup the string
jit_prepare_routine_call(jit, asm);
- asm.comment("Unary plus on string");
+ asm_comment!(asm, "Unary plus on string");
let recv_opnd = asm.stack_pop(1);
let recv_opnd = asm.load(recv_opnd);
let flags_opnd = asm.load(Opnd::mem(64, recv_opnd, RUBY_OFFSET_RBASIC_FLAGS));
@@ -4691,11 +4691,11 @@ fn jit_rb_str_bytesize(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("String#bytesize");
+ asm_comment!(asm, "String#bytesize");
let recv = asm.stack_pop(1);
- asm.comment("get string length");
+ asm_comment!(asm, "get string length");
let str_len_opnd = Opnd::mem(
std::os::raw::c_long::BITS as u8,
asm.load(recv),
@@ -4723,7 +4723,7 @@ fn jit_rb_str_getbyte(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("String#getbyte");
+ asm_comment!(asm, "String#getbyte");
extern "C" {
fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE;
}
@@ -4756,7 +4756,7 @@ fn jit_rb_str_to_s(
known_recv_class: *const VALUE,
) -> bool {
if !known_recv_class.is_null() && unsafe { *known_recv_class == rb_cString } {
- asm.comment("to_s on plain string");
+ asm_comment!(asm, "to_s on plain string");
// The method returns the receiver, which is already on the stack.
// No stack movement.
return true;
@@ -4777,7 +4777,7 @@ fn jit_rb_str_empty_p(
) -> bool {
let recv_opnd = asm.stack_pop(1);
- asm.comment("get string length");
+ asm_comment!(asm, "get string length");
let str_len_opnd = Opnd::mem(
std::os::raw::c_long::BITS as u8,
asm.load(recv_opnd),
@@ -4827,7 +4827,7 @@ fn jit_rb_str_concat(
// Test if string encodings differ. If different, use rb_str_append. If the same,
// use rb_yjit_str_simple_append, which calls rb_str_cat.
- asm.comment("<< on strings");
+ asm_comment!(asm, "<< on strings");
// Take receiver's object flags XOR arg's flags. If any
// string-encoding flags are different between the two,
@@ -4899,7 +4899,7 @@ fn jit_rb_ary_push(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("Array#<<");
+ asm_comment!(asm, "Array#<<");
// rb_ary_push allocates memory for buffer extension
jit_prepare_routine_call(jit, asm);
@@ -5004,7 +5004,7 @@ fn jit_obj_respond_to(
let _recv_opnd = asm.stack_pop(1);
// This is necessary because we have no guarantee that sym_opnd is a constant
- asm.comment("guard known mid");
+ asm_comment!(asm, "guard known mid");
asm.cmp(sym_opnd, mid_sym.into());
jit_chain_guard(
JCC_JNE,
@@ -5030,7 +5030,7 @@ fn jit_rb_f_block_given_p(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("block_given?");
+ asm_comment!(asm, "block_given?");
// Same as rb_vm_frame_block_handler
let ep_opnd = gen_get_lep(jit, asm);
@@ -5059,7 +5059,7 @@ fn jit_thread_s_current(
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
- asm.comment("Thread.current");
+ asm_comment!(asm, "Thread.current");
asm.stack_pop(1);
// ec->thread_ptr
@@ -5161,7 +5161,7 @@ fn gen_push_frame(
) {
let sp = frame.sp;
- asm.comment("push cme, specval, frame type");
+ asm_comment!(asm, "push cme, specval, frame type");
// Write method entry at sp[-3]
// sp[-3] = me;
@@ -5208,7 +5208,7 @@ fn gen_push_frame(
}
};
if let SpecVal::BlockHandler(Some(BlockHandler::AlreadySet)) = frame.specval {
- asm.comment("specval should have been set");
+ asm_comment!(asm, "specval should have been set");
} else {
asm.store(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -2), specval);
}
@@ -5231,7 +5231,7 @@ fn gen_push_frame(
// .ep = <sp - 1>,
// .block_code = 0,
// };
- asm.comment("push callee control frame");
+ asm_comment!(asm, "push callee control frame");
// For an iseq call PC may be None, in which case we will not set PC and will allow jitted code
// to set it as necessary.
@@ -5261,11 +5261,11 @@ fn gen_push_frame(
let new_cfp = asm.lea(cfp_opnd(0));
if set_sp_cfp {
- asm.comment("switch to new CFP");
+ asm_comment!(asm, "switch to new CFP");
asm.mov(CFP, new_cfp);
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP);
} else {
- asm.comment("set ec->cfp");
+ asm_comment!(asm, "set ec->cfp");
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp);
}
}
@@ -5357,7 +5357,7 @@ fn gen_send_cfunc(
// Stack overflow check
// #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
// REG_CFP <= REG_SP + 4 * SIZEOF_VALUE + sizeof(rb_control_frame_t)
- asm.comment("stack overflow check");
+ asm_comment!(asm, "stack overflow check");
let stack_limit = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE * 4 + 2 * RUBY_SIZEOF_CONTROL_FRAME) as isize));
asm.cmp(CFP, stack_limit);
asm.jbe(Target::side_exit(Counter::guard_send_se_cf_overflow));
@@ -5482,7 +5482,7 @@ fn gen_send_cfunc(
if !kw_arg.is_null() {
// Build a hash from all kwargs passed
- asm.comment("build_kwhash");
+ asm_comment!(asm, "build_kwhash");
let imemo_ci = VALUE(ci as usize);
assert_ne!(0, unsafe { rb_IMEMO_TYPE_P(imemo_ci, imemo_callinfo) },
"we assume all callinfos with kwargs are on the GC heap");
@@ -5530,7 +5530,7 @@ fn gen_send_cfunc(
// VALUE ret = (cfunc->func)(recv, argv[0], argv[1]);
// cfunc comes from compile-time cme->def, which we assume to be stable.
// Invalidation logic is in yjit_method_lookup_change()
- asm.comment("call C function");
+ asm_comment!(asm, "call C function");
let ret = asm.ccall(unsafe { get_mct_func(cfunc) }.cast(), args);
// Record code position for TracePoint patching. See full_cfunc_return().
@@ -5561,7 +5561,7 @@ fn gen_send_cfunc(
// Generate RARRAY_LEN. For array_opnd, use Opnd::Reg to reduce memory access,
// and use Opnd::Mem to save registers.
fn get_array_len(asm: &mut Assembler, array_opnd: Opnd) -> Opnd {
- asm.comment("get array length for embedded or heap");
+ asm_comment!(asm, "get array length for embedded or heap");
// Pull out the embed flag to check if it's an embedded array.
let array_reg = match array_opnd {
@@ -5594,7 +5594,7 @@ fn get_array_len(asm: &mut Assembler, array_opnd: Opnd) -> Opnd {
// Generate RARRAY_CONST_PTR (part of RARRAY_AREF)
fn get_array_ptr(asm: &mut Assembler, array_reg: Opnd) -> Opnd {
- asm.comment("get array pointer for embedded or heap");
+ asm_comment!(asm, "get array pointer for embedded or heap");
let flags_opnd = Opnd::mem(VALUE_BITS, array_reg, RUBY_OFFSET_RBASIC_FLAGS);
asm.test(flags_opnd, (RARRAY_EMBED_FLAG as u64).into());
@@ -5613,11 +5613,11 @@ fn get_array_ptr(asm: &mut Assembler, array_reg: Opnd) -> Opnd {
/// Pushes arguments from an array to the stack. Differs from push splat because
/// the array can have items left over.
fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) {
- asm.comment("move_rest_args_to_stack");
+ asm_comment!(asm, "move_rest_args_to_stack");
let array_len_opnd = get_array_len(asm, array);
- asm.comment("Side exit if length is less than required");
+ asm_comment!(asm, "Side exit if length is less than required");
asm.cmp(array_len_opnd, num_args.into());
asm.jl(Target::side_exit(Counter::guard_send_iseq_has_rest_and_splat_not_equal));
@@ -5626,7 +5626,7 @@ fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) {
return;
}
- asm.comment("Push arguments from array");
+ asm_comment!(asm, "Push arguments from array");
// Load the address of the embedded array
// (struct RArray *)(obj)->as.ary
@@ -5656,7 +5656,7 @@ fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) {
/// It optimistically compiles to a static size that is the exact number of arguments
/// needed for the function.
fn push_splat_args(required_args: u32, asm: &mut Assembler) {
- asm.comment("push_splat_args");
+ asm_comment!(asm, "push_splat_args");
let array_opnd = asm.stack_opnd(0);
let array_reg = asm.load(array_opnd);
@@ -5668,7 +5668,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) {
Counter::guard_send_splat_not_array,
);
- asm.comment("Get array length for embedded or heap");
+ asm_comment!(asm, "Get array length for embedded or heap");
// Pull out the embed flag to check if it's an embedded array.
let flags_opnd = Opnd::mem(VALUE_BITS, array_reg, RUBY_OFFSET_RBASIC_FLAGS);
@@ -5692,11 +5692,11 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) {
);
let array_len_opnd = asm.csel_nz(emb_len_opnd, array_len_opnd);
- asm.comment("Guard for expected splat length");
+ asm_comment!(asm, "Guard for expected splat length");
asm.cmp(array_len_opnd, required_args.into());
asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal));
- asm.comment("Check last argument is not ruby2keyword hash");
+ asm_comment!(asm, "Check last argument is not ruby2keyword hash");
// Need to repeat this here to deal with register allocation
let array_reg = asm.load(asm.stack_opnd(0));
@@ -5711,7 +5711,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) {
Counter::guard_send_splatarray_last_ruby_2_keywords,
);
- asm.comment("Push arguments from array");
+ asm_comment!(asm, "Push arguments from array");
let array_opnd = asm.stack_pop(1);
if required_args > 0 {
@@ -5738,7 +5738,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) {
asm.mov(top, Opnd::mem(64, ary_opnd, i as i32 * SIZEOF_VALUE_I32));
}
- asm.comment("end push_each");
+ asm_comment!(asm, "end push_each");
}
}
@@ -5995,7 +5995,7 @@ fn gen_send_iseq(
// change and we don't change that dynmically so we side exit.
// On a normal splat without rest and option args this is handled
// elsewhere depending on the case
- asm.comment("Side exit if length doesn't not equal compile time length");
+ asm_comment!(asm, "Side exit if length doesn't not equal compile time length");
let array_len_opnd = get_array_len(asm, asm.stack_opnd(if block_arg { 1 } else { 0 }));
asm.cmp(array_len_opnd, array_length.into());
asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal));
@@ -6051,7 +6051,7 @@ fn gen_send_iseq(
// rest param handling later. Also, since there are C calls that
// come later, we can't hold this value in a register and place it
// near the end when we push a new control frame.
- asm.comment("guard block arg is a proc");
+ asm_comment!(asm, "guard block arg is a proc");
// Simple predicate, no need for jit_prepare_routine_call().
let is_proc = asm.ccall(rb_obj_is_proc as _, vec![asm.stack_opnd(0)]);
asm.cmp(is_proc, Qfalse.into());
@@ -6083,7 +6083,7 @@ fn gen_send_iseq(
if let (None, Some(builtin_info), true, false) = (block, builtin_func, builtin_attrs & BUILTIN_ATTR_LEAF != 0, opt_send_call) {
let builtin_argc = unsafe { (*builtin_info).argc };
if builtin_argc + 1 < (C_ARG_OPNDS.len() as i32) {
- asm.comment("inlined leaf builtin");
+ asm_comment!(asm, "inlined leaf builtin");
// Skip this if it doesn't trigger GC
if builtin_attrs & BUILTIN_ATTR_NO_GC == 0 {
@@ -6118,7 +6118,7 @@ fn gen_send_iseq(
// Stack overflow check
// Note that vm_push_frame checks it against a decremented cfp, hence the multiply by 2.
// #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
- asm.comment("stack overflow check");
+ asm_comment!(asm, "stack overflow check");
let stack_max: i32 = unsafe { get_iseq_body_stack_max(iseq) }.try_into().unwrap();
let locals_offs =
SIZEOF_VALUE_I32 * (num_locals + stack_max) + 2 * (RUBY_SIZEOF_CONTROL_FRAME as i32);
@@ -6172,12 +6172,12 @@ fn gen_send_iseq(
.try_into().unwrap();
// diff is >0 so no need to worry about null pointer
- asm.comment("load pointer to array elements");
+ asm_comment!(asm, "load pointer to array elements");
let offset_magnitude = SIZEOF_VALUE as u32 * diff;
let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize));
let values_ptr = asm.lea(values_opnd);
- asm.comment("prepend stack values to rest array");
+ asm_comment!(asm, "prepend stack values to rest array");
let array = asm.ccall(
rb_ary_unshift_m as *const u8,
vec![Opnd::UImm(diff as u64), values_ptr, array],
@@ -6188,7 +6188,7 @@ fn gen_send_iseq(
} else if non_rest_arg_count < required_num + opt_num {
// If we have fewer arguments than required, we need to take some
// from the array and move them to the stack.
- asm.comment("take items from splat array");
+ asm_comment!(asm, "take items from splat array");
let diff: u32 = (required_num - non_rest_arg_count + opts_filled)
.try_into().unwrap();
@@ -6202,13 +6202,13 @@ fn gen_send_iseq(
sliced
} else {
// The arguments are equal so we can just push to the stack
- asm.comment("same length for splat array and rest param");
+ asm_comment!(asm, "same length for splat array and rest param");
assert!(non_rest_arg_count == required_num + opt_num);
array
}
} else {
- asm.comment("rest parameter without splat");
+ asm_comment!(asm, "rest parameter without splat");
assert!(argc >= required_num);
let n = (argc - required_num - opts_filled) as u32;
@@ -6217,7 +6217,7 @@ fn gen_send_iseq(
let values_ptr = if n == 0 {
Opnd::UImm(0)
} else {
- asm.comment("load pointer to array elements");
+ asm_comment!(asm, "load pointer to array elements");
let offset_magnitude = SIZEOF_VALUE as u32 * n;
let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize));
asm.lea(values_opnd)
@@ -6282,7 +6282,7 @@ fn gen_send_iseq(
// keyword parameters.
let keyword = unsafe { get_iseq_body_param_keyword(iseq) };
- asm.comment("keyword args");
+ asm_comment!(asm, "keyword args");
// This is the list of keyword arguments that the callee specified
// in its initial declaration.
@@ -6417,7 +6417,7 @@ fn gen_send_iseq(
let arg0_reg = asm.load(arg0_opnd);
let array_opnd = get_array_ptr(asm, arg0_reg);
- asm.comment("push splat arg0 onto the stack");
+ asm_comment!(asm, "push splat arg0 onto the stack");
asm.stack_pop(argc.try_into().unwrap());
for i in 0..lead_num {
let stack_opnd = asm.stack_push(Type::Unknown);
@@ -6431,7 +6431,7 @@ fn gen_send_iseq(
return;
}
- asm.comment(comment);
+ asm_comment!(asm, "{}", comment);
for i in fill_range {
let value_slot = asm.ctx.sp_opnd(i * SIZEOF_VALUE as isize);
asm.store(value_slot, Qnil.into());
@@ -6477,7 +6477,7 @@ fn gen_send_iseq(
let sp_offset = (argc as isize) + if captured_self { 0 } else { 1 };
// Store the updated SP on the current frame (pop arguments and receiver)
- asm.comment("store caller sp");
+ asm_comment!(asm, "store caller sp");
let caller_sp = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE as isize) * -sp_offset));
asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP), caller_sp);
@@ -6793,7 +6793,7 @@ fn gen_struct_aref(
// true of the converse.
let embedded = unsafe { FL_TEST_RAW(comptime_recv, VALUE(RSTRUCT_EMBED_LEN_MASK)) };
- asm.comment("struct aref");
+ asm_comment!(asm, "struct aref");
let recv = asm.stack_pop(1);
let recv = asm.load(recv);
@@ -6839,7 +6839,7 @@ fn gen_struct_aset(
assert!(unsafe { RB_TYPE_P(comptime_recv, RUBY_T_STRUCT) });
assert!((off as i64) < unsafe { RSTRUCT_LEN(comptime_recv) });
- asm.comment("struct aset");
+ asm_comment!(asm, "struct aset");
let val = asm.stack_pop(1);
let recv = asm.stack_pop(1);
@@ -6935,7 +6935,7 @@ fn gen_send_general(
let method_name = unsafe { cstr_to_rust_string(rb_id2name(mid)) };
match (class_name, method_name) {
(Some(class_name), Some(method_name)) => {
- asm.comment(&format!("call to {}#{}", class_name, method_name))
+ asm_comment!(asm, "call to {}#{}", class_name, method_name);
}
_ => {}
}
@@ -7201,7 +7201,7 @@ fn gen_send_general(
let symbol_id_opnd = asm.ccall(rb_get_symbol_id as *const u8, vec![name_opnd]);
- asm.comment("chain_guard_send");
+ asm_comment!(asm, "chain_guard_send");
asm.cmp(symbol_id_opnd, mid.into());
jit_chain_guard(
JCC_JNE,
@@ -7358,7 +7358,7 @@ fn gen_send_general(
///
/// We do this for our compiletime context and the actual stack
fn handle_opt_send_shift_stack(asm: &mut Assembler, argc: i32) {
- asm.comment("shift_stack");
+ asm_comment!(asm, "shift_stack");
for j in (0..argc).rev() {
let opnd = asm.stack_opnd(j);
let opnd2 = asm.stack_opnd(j + 1);
@@ -7470,13 +7470,13 @@ fn gen_invokeblock_specialized(
gen_counter_incr(asm, Counter::invokeblock_none);
None
} else if comptime_handler.0 & 0x3 == 0x1 { // VM_BH_ISEQ_BLOCK_P
- asm.comment("get local EP");
+ asm_comment!(asm, "get local EP");
let ep_opnd = gen_get_lep(jit, asm);
let block_handler_opnd = asm.load(
Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL)
);
- asm.comment("guard block_handler type");
+ asm_comment!(asm, "guard block_handler type");
let tag_opnd = asm.and(block_handler_opnd, 0x3.into()); // block_handler is a tagged pointer
asm.cmp(tag_opnd, 0x1.into()); // VM_BH_ISEQ_BLOCK_P
jit_chain_guard(
@@ -7491,7 +7491,7 @@ fn gen_invokeblock_specialized(
let comptime_captured = unsafe { ((comptime_handler.0 & !0x3) as *const rb_captured_block).as_ref().unwrap() };
let comptime_iseq = unsafe { *comptime_captured.code.iseq.as_ref() };
- asm.comment("guard known ISEQ");
+ asm_comment!(asm, "guard known ISEQ");
let captured_opnd = asm.and(block_handler_opnd, Opnd::Imm(!0x3));
let iseq_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32 * 2));
asm.cmp(iseq_opnd, (comptime_iseq as usize).into());
@@ -7529,13 +7529,13 @@ fn gen_invokeblock_specialized(
return None;
}
- asm.comment("get local EP");
+ asm_comment!(asm, "get local EP");
let ep_opnd = gen_get_lep(jit, asm);
let block_handler_opnd = asm.load(
Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL)
);
- asm.comment("guard block_handler type");
+ asm_comment!(asm, "guard block_handler type");
let tag_opnd = asm.and(block_handler_opnd, 0x3.into()); // block_handler is a tagged pointer
asm.cmp(tag_opnd, 0x3.into()); // VM_BH_IFUNC_P
jit_chain_guard(
@@ -7553,7 +7553,7 @@ fn gen_invokeblock_specialized(
extern "C" {
fn rb_vm_yield_with_cfunc(ec: EcPtr, captured: *const rb_captured_block, argc: c_int, argv: *const VALUE) -> VALUE;
}
- asm.comment("call ifunc");
+ asm_comment!(asm, "call ifunc");
let captured_opnd = asm.and(block_handler_opnd, Opnd::Imm(!0x3));
let argv = asm.lea(asm.ctx.sp_opnd((-argc * SIZEOF_VALUE_I32) as isize));
let ret = asm.ccall(
@@ -7693,7 +7693,7 @@ fn gen_invokesuper_specialized(
return None;
}
- asm.comment("guard known me");
+ asm_comment!(asm, "guard known me");
let lep_opnd = gen_get_lep(jit, asm);
let ep_me_opnd = Opnd::mem(
64,
@@ -7749,7 +7749,7 @@ fn gen_leave(
// Pop the current frame (ec->cfp++)
// Note: the return PC is already in the previous CFP
- asm.comment("pop stack frame");
+ asm_comment!(asm, "pop stack frame");
let incr_cfp = asm.add(CFP, RUBY_SIZEOF_CONTROL_FRAME.into());
asm.mov(CFP, incr_cfp);
asm.mov(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP);
@@ -7961,25 +7961,25 @@ fn gen_getspecial(
jit_prepare_routine_call(jit, asm);
// call rb_backref_get()
- asm.comment("rb_backref_get");
+ asm_comment!(asm, "rb_backref_get");
let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
let rt_u8: u8 = (rtype >> 1).try_into().unwrap();
let val = match rt_u8.into() {
'&' => {
- asm.comment("rb_reg_last_match");
+ asm_comment!(asm, "rb_reg_last_match");
asm.ccall(rb_reg_last_match as *const u8, vec![backref])
}
'`' => {
- asm.comment("rb_reg_match_pre");
+ asm_comment!(asm, "rb_reg_match_pre");
asm.ccall(rb_reg_match_pre as *const u8, vec![backref])
}
'\'' => {
- asm.comment("rb_reg_match_post");
+ asm_comment!(asm, "rb_reg_match_post");
asm.ccall(rb_reg_match_post as *const u8, vec![backref])
}
'+' => {
- asm.comment("rb_reg_match_last");
+ asm_comment!(asm, "rb_reg_match_last");
asm.ccall(rb_reg_match_last as *const u8, vec![backref])
}
_ => panic!("invalid back-ref"),
@@ -7996,11 +7996,11 @@ fn gen_getspecial(
jit_prepare_routine_call(jit, asm);
// call rb_backref_get()
- asm.comment("rb_backref_get");
+ asm_comment!(asm, "rb_backref_get");
let backref = asm.ccall(rb_backref_get as *const u8, vec![]);
// rb_reg_nth_match((int)(type >> 1), backref);
- asm.comment("rb_reg_nth_match");
+ asm_comment!(asm, "rb_reg_nth_match");
let val = asm.ccall(
rb_reg_nth_match as *const u8,
vec![
diff --git a/yjit/src/core.rs b/yjit/src/core.rs
index 8261051315..c012bc979e 100644
--- a/yjit/src/core.rs
+++ b/yjit/src/core.rs
@@ -550,7 +550,7 @@ impl BranchGenFn {
asm.jb(target0)
}
BranchGenFn::JITReturn => {
- asm.comment("update cfp->jit_return");
+ asm_comment!(asm, "update cfp->jit_return");
asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), Opnd::const_ptr(target0.unwrap_code_ptr().raw_ptr()));
}
}
@@ -2213,7 +2213,7 @@ pub fn gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exception: bool) -> Option<
// Change the entry's jump target from an entry stub to a next entry
pub fn regenerate_entry(cb: &mut CodeBlock, entryref: &EntryRef, next_entry: CodePtr) {
let mut asm = Assembler::new();
- asm.comment("regenerate_entry");
+ asm_comment!(asm, "regenerate_entry");
// gen_entry_guard generates cmp + jne. We're rewriting only jne.
asm.jne(next_entry.into());
@@ -2322,7 +2322,7 @@ pub fn gen_entry_stub(entry_address: usize, ocb: &mut OutlinedCb) -> Option<Code
let stub_addr = ocb.get_write_ptr();
let mut asm = Assembler::new();
- asm.comment("entry stub hit");
+ asm_comment!(asm, "entry stub hit");
asm.mov(C_ARG_OPNDS[0], entry_address.into());
@@ -2347,7 +2347,7 @@ pub fn gen_entry_stub_hit_trampoline(ocb: &mut OutlinedCb) -> CodePtr {
let mut asm = Assembler::new();
// See gen_entry_guard for how it's used.
- asm.comment("entry_stub_hit() trampoline");
+ asm_comment!(asm, "entry_stub_hit() trampoline");
let jump_addr = asm.ccall(entry_stub_hit as *mut u8, vec![C_ARG_OPNDS[0], EC]);
// Jump to the address returned by the entry_stub_hit() call
@@ -2370,7 +2370,7 @@ fn regenerate_branch(cb: &mut CodeBlock, branch: &Branch) {
// Generate the branch
let mut asm = Assembler::new();
- asm.comment("regenerate_branch");
+ asm_comment!(asm, "regenerate_branch");
branch.gen_fn.call(
&mut asm,
Target::CodePtr(branch.get_target_address(0).unwrap()),
@@ -2623,7 +2623,7 @@ fn gen_branch_stub(
let mut asm = Assembler::new();
asm.ctx = ctx.clone();
asm.set_reg_temps(ctx.reg_temps);
- asm.comment("branch stub hit");
+ asm_comment!(asm, "branch stub hit");
// Save caller-saved registers before C_ARG_OPNDS get clobbered.
// Spill all registers for consistency with the trampoline.
@@ -2668,7 +2668,7 @@ pub fn gen_branch_stub_hit_trampoline(ocb: &mut OutlinedCb) -> CodePtr {
// is the unchanging part.
// Since this trampoline is static, it allows code GC inside
// branch_stub_hit() to free stubs without problems.
- asm.comment("branch_stub_hit() trampoline");
+ asm_comment!(asm, "branch_stub_hit() trampoline");
let jump_addr = asm.ccall(
branch_stub_hit as *mut u8,
vec![
@@ -2793,7 +2793,7 @@ pub fn gen_direct_jump(jit: &mut JITState, ctx: &Context, target0: BlockId, asm:
let block_addr = block.start_addr;
// Call the branch generation function
- asm.comment("gen_direct_jmp: existing block");
+ asm_comment!(asm, "gen_direct_jmp: existing block");
asm.mark_branch_start(&branch);
branch.gen_fn.call(asm, Target::CodePtr(block_addr), None);
asm.mark_branch_end(&branch);
@@ -2801,7 +2801,7 @@ pub fn gen_direct_jump(jit: &mut JITState, ctx: &Context, target0: BlockId, asm:
BranchTarget::Block(blockref)
} else {
// The branch is effectively empty (a noop)
- asm.comment("gen_direct_jmp: fallthrough");
+ asm_comment!(asm, "gen_direct_jmp: fallthrough");
asm.mark_branch_start(&branch);
asm.mark_branch_end(&branch);
branch.gen_fn.set_shape(BranchShape::Next0);
@@ -2847,7 +2847,7 @@ pub fn defer_compilation(
let target0_address = branch.set_target(0, blockid, &next_ctx, ocb);
// Call the branch generation function
- asm.comment("defer_compilation");
+ asm_comment!(asm, "defer_compilation");
asm.mark_branch_start(&branch);
if let Some(dst_addr) = target0_address {
branch.gen_fn.call(asm, Target::CodePtr(dst_addr), None);