Skip to content

Commit da3b6ee

Browse files
committed
ZJIT: Add a ccall macro that also adds an LIR comment
This DRYs up the `asm_comment!` + `asm.ccall` combo, and makes ccalls have a comment by default. The macro itself removes visual noise and puts the callee's name and arguments first. `[]` on the outside to make it visually distinctive from the `()` inside.
1 parent 350df4f commit da3b6ee

2 files changed

Lines changed: 22 additions & 60 deletions

File tree

zjit/src/backend/lir.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,15 @@ macro_rules! asm_comment {
22432243
}
22442244
pub(crate) use asm_comment;
22452245

2246+
/// Convenience macro over [`Assembler::ccall`] that also adds a comment with the function name.
2247+
macro_rules! ccall {
2248+
[$fn_name:ident ( $($args:expr),* ) , $asm: ident] => {{
2249+
$crate::backend::lir::asm_comment!($asm, concat!("call ", stringify!($fn_name)));
2250+
$asm.ccall($fn_name as *const u8, vec![$($args),*])
2251+
}};
2252+
}
2253+
pub(crate) use ccall;
2254+
22462255
#[cfg(test)]
22472256
mod tests {
22482257
use super::*;

zjit/src/codegen.rs

Lines changed: 13 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::invariants::track_bop_assumption;
77
use crate::profile::get_or_create_iseq_payload;
88
use crate::state::ZJITState;
99
use crate::{asm::CodeBlock, cruby::*, options::debug, virtualmem::CodePtr};
10-
use crate::backend::lir::{self, asm_comment, Assembler, Opnd, Target, CFP, C_ARG_OPNDS, C_RET_OPND, EC, NATIVE_STACK_PTR, SP};
10+
use crate::backend::lir::{self, asm_comment, ccall, Assembler, Opnd, Target, CFP, C_ARG_OPNDS, C_RET_OPND, EC, NATIVE_STACK_PTR, SP};
1111
use crate::hir::{iseq_to_hir, Block, BlockId, BranchEdge, CallInfo, Invariant, RangeType, SpecialObjectType, SELF_PARAM_IDX};
1212
use crate::hir::{Const, FrameState, Function, Insn, InsnId};
1313
use crate::hir_type::{types::Fixnum, Type};
@@ -396,11 +396,7 @@ fn gen_get_constant_path(asm: &mut Assembler, ic: *const iseq_inline_constant_ca
396396
// Save PC since the call can allocate an IC
397397
gen_save_pc(asm, state);
398398

399-
let val = asm.ccall(
400-
rb_vm_opt_getconstant_path as *const u8,
401-
vec![EC, CFP, Opnd::const_ptr(ic as *const u8)],
402-
);
403-
val
399+
ccall![rb_vm_opt_getconstant_path(EC, CFP, Opnd::const_ptr(ic as *const u8)), asm]
404400
}
405401

406402
fn gen_invokebuiltin(jit: &mut JITState, asm: &mut Assembler, state: &FrameState, bf: &rb_builtin_function, args: &Vec<InsnId>) -> Option<lir::Opnd> {
@@ -454,36 +450,23 @@ fn gen_ccall(jit: &mut JITState, asm: &mut Assembler, cfun: *const u8, args: &[I
454450

455451
/// Emit an uncached instance variable lookup
456452
fn gen_getivar(asm: &mut Assembler, recv: Opnd, id: ID) -> Opnd {
457-
asm_comment!(asm, "call rb_ivar_get");
458-
asm.ccall(
459-
rb_ivar_get as *const u8,
460-
vec![recv, Opnd::UImm(id.0)],
461-
)
453+
ccall![rb_ivar_get(recv, id.0.into()), asm]
462454
}
463455

464456
/// Emit an uncached instance variable store
465457
fn gen_setivar(asm: &mut Assembler, recv: Opnd, id: ID, val: Opnd) -> Option<()> {
466-
asm_comment!(asm, "call rb_ivar_set");
467-
asm.ccall(
468-
rb_ivar_set as *const u8,
469-
vec![recv, Opnd::UImm(id.0), val],
470-
);
458+
ccall![rb_ivar_set(recv, id.0.into(), val), asm];
471459
Some(())
472460
}
473461

474462
/// Look up global variables
475463
fn gen_getglobal(asm: &mut Assembler, id: ID) -> Opnd {
476-
asm_comment!(asm, "call rb_gvar_get");
477-
asm.ccall(
478-
rb_gvar_get as *const u8,
479-
vec![Opnd::UImm(id.0)],
480-
)
464+
ccall![rb_gvar_get(id.0.into()), asm]
481465
}
482466

483467
/// Set global variables
484468
fn gen_setglobal(asm: &mut Assembler, id: ID, val: Opnd) {
485-
asm_comment!(asm, "call rb_gvar_set");
486-
asm.ccall(rb_gvar_set as *const u8, vec![Opnd::UImm(id.0), val]);
469+
ccall![rb_gvar_set(id.0.into(), val), asm];
487470
}
488471

489472
/// Side-exit into the interpreter
@@ -498,11 +481,7 @@ fn gen_putspecialobject(asm: &mut Assembler, value_type: SpecialObjectType) -> O
498481
let ep_opnd = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_EP);
499482
let ep_reg = asm.load(ep_opnd);
500483

501-
asm_comment!(asm, "call rb_vm_get_special_object");
502-
asm.ccall(
503-
rb_vm_get_special_object as *const u8,
504-
vec![ep_reg, Opnd::UImm(u64::from(value_type))],
505-
)
484+
ccall![rb_vm_get_special_object(ep_reg, Opnd::UImm(u64::from(value_type))), asm]
506485
}
507486

508487
/// Compile an interpreter entry block to be inserted into an ISEQ
@@ -773,13 +752,9 @@ fn gen_send_without_block_direct(
773752

774753
/// Compile a string resurrection
775754
fn gen_string_copy(asm: &mut Assembler, recv: Opnd, chilled: bool) -> Opnd {
776-
asm_comment!(asm, "call rb_ec_str_resurrect");
777755
// TODO: split rb_ec_str_resurrect into separate functions
778756
let chilled = if chilled { Opnd::Imm(1) } else { Opnd::Imm(0) };
779-
asm.ccall(
780-
rb_ec_str_resurrect as *const u8,
781-
vec![EC, recv, chilled],
782-
)
757+
ccall![rb_ec_str_resurrect(EC, recv, chilled), asm]
783758
}
784759

785760
/// Compile an array duplication instruction
@@ -791,11 +766,7 @@ fn gen_array_dup(
791766
// Save PC
792767
gen_save_pc(asm, state);
793768

794-
asm_comment!(asm, "call rb_ary_resurrect");
795-
asm.ccall(
796-
rb_ary_resurrect as *const u8,
797-
vec![val],
798-
)
769+
ccall![rb_ary_resurrect(val), asm]
799770
}
800771

801772
/// Compile a new array instruction
@@ -810,20 +781,12 @@ fn gen_new_array(
810781

811782
let length: ::std::os::raw::c_long = elements.len().try_into().expect("Unable to fit length of elements into c_long");
812783

813-
asm_comment!(asm, "call rb_ary_new");
814-
let new_array = asm.ccall(
815-
rb_ary_new_capa as *const u8,
816-
vec![lir::Opnd::Imm(length)],
817-
);
784+
let new_array = ccall![rb_ary_new_capa(length.into()), asm];
818785

819786
for i in 0..elements.len() {
820787
let insn_id = elements.get(i as usize).expect("Element should exist at index");
821788
let val = jit.get_opnd(*insn_id).unwrap();
822-
asm_comment!(asm, "call rb_ary_push");
823-
asm.ccall(
824-
rb_ary_push as *const u8,
825-
vec![new_array, val]
826-
);
789+
ccall![rb_ary_push(new_array, val), asm];
827790
}
828791

829792
new_array
@@ -840,14 +803,8 @@ fn gen_new_range(
840803
// Save PC
841804
gen_save_pc(asm, state);
842805

843-
asm_comment!(asm, "call rb_range_new");
844806
// Call rb_range_new(low, high, flag)
845-
let new_range = asm.ccall(
846-
rb_range_new as *const u8,
847-
vec![low, high, lir::Opnd::Imm(flag as i64)],
848-
);
849-
850-
new_range
807+
ccall![rb_range_new(low, high, lir::Opnd::Imm(flag as i64)), asm]
851808
}
852809

853810
/// Compile code that exits from JIT code with a return value
@@ -955,11 +912,7 @@ fn gen_anytostring(asm: &mut Assembler, val: lir::Opnd, str: lir::Opnd, state: &
955912
// Save PC
956913
gen_save_pc(asm, state);
957914

958-
asm_comment!(asm, "call rb_obj_as_string_result");
959-
Some(asm.ccall(
960-
rb_obj_as_string_result as *const u8,
961-
vec![str, val],
962-
))
915+
Some(ccall![rb_obj_as_string_result(str, val), asm])
963916
}
964917

965918
/// Evaluate if a value is truthy

0 commit comments

Comments
 (0)