Skip to content

Commit 701e097

Browse files
authored
ZJIT: Count writes to the VM frame (ruby#14597)
This is a) a lot of memory traffic and b) is another good proxy for our ability to strength reduce method calls.
1 parent f72d0f3 commit 701e097

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

zjit.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def stats_string
5858
:gc_time_ns,
5959
:invalidation_time_ns,
6060

61+
:vm_write_pc_count,
62+
:vm_write_sp_count,
63+
:vm_write_locals_count,
64+
:vm_write_stack_count,
65+
6166
:code_region_bytes,
6267
:side_exit_count,
6368
:total_insn_count,

zjit/src/codegen.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,7 @@ fn gen_prepare_call_with_gc(asm: &mut Assembler, state: &FrameState, leaf: bool)
15931593
let opcode: usize = state.get_opcode().try_into().unwrap();
15941594
let next_pc: *const VALUE = unsafe { state.pc.offset(insn_len(opcode) as isize) };
15951595

1596+
gen_incr_counter(asm, Counter::vm_write_pc_count);
15961597
asm_comment!(asm, "save PC to CFP");
15971598
asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), Opnd::const_ptr(next_pc));
15981599

@@ -1611,6 +1612,7 @@ fn gen_save_sp(asm: &mut Assembler, stack_size: usize) {
16111612
// code, and ZJIT's codegen currently assumes the SP register doesn't move, e.g. gen_param().
16121613
// So we don't update the SP register here. We could update the SP register to avoid using
16131614
// an extra register for asm.lea(), but you'll need to manage the SP offset like YJIT does.
1615+
gen_incr_counter(asm, Counter::vm_write_sp_count);
16141616
asm_comment!(asm, "save SP to CFP: {}", stack_size);
16151617
let sp_addr = asm.lea(Opnd::mem(64, SP, stack_size as i32 * SIZEOF_VALUE_I32));
16161618
let cfp_sp = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP);
@@ -1620,6 +1622,7 @@ fn gen_save_sp(asm: &mut Assembler, stack_size: usize) {
16201622
/// Spill locals onto the stack.
16211623
fn gen_spill_locals(jit: &JITState, asm: &mut Assembler, state: &FrameState) {
16221624
// TODO: Avoid spilling locals that have been spilled before and not changed.
1625+
gen_incr_counter(asm, Counter::vm_write_locals_count);
16231626
asm_comment!(asm, "spill locals");
16241627
for (idx, &insn_id) in state.locals().enumerate() {
16251628
asm.mov(Opnd::mem(64, SP, (-local_idx_to_ep_offset(jit.iseq, idx) - 1) * SIZEOF_VALUE_I32), jit.get_opnd(insn_id));
@@ -1630,6 +1633,7 @@ fn gen_spill_locals(jit: &JITState, asm: &mut Assembler, state: &FrameState) {
16301633
fn gen_spill_stack(jit: &JITState, asm: &mut Assembler, state: &FrameState) {
16311634
// This function does not call gen_save_sp() at the moment because
16321635
// gen_send_without_block_direct() spills stack slots above SP for arguments.
1636+
gen_incr_counter(asm, Counter::vm_write_stack_count);
16331637
asm_comment!(asm, "spill stack");
16341638
for (idx, &insn_id) in state.stack().enumerate() {
16351639
asm.mov(Opnd::mem(64, SP, idx as i32 * SIZEOF_VALUE_I32), jit.get_opnd(insn_id));

zjit/src/stats.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ make_counters! {
150150
send_fallback_optimized,
151151
send_fallback_missing,
152152
send_fallback_refined,
153+
154+
// Writes to the VM frame
155+
vm_write_pc_count,
156+
vm_write_sp_count,
157+
vm_write_locals_count,
158+
vm_write_stack_count,
153159
}
154160

155161
/// Increase a counter by a specified amount

0 commit comments

Comments
 (0)