diff options
| author | Max Bernstein <ruby@bernsteinbear.com> | 2025-08-27 15:15:08 -0400 |
|---|---|---|
| committer | Max Bernstein <tekknolagi@gmail.com> | 2025-08-27 15:56:13 -0700 |
| commit | fb3d2a2a1977e702e46723ab0ed691b1e9433e7f (patch) | |
| tree | 6d9b5b810b99c06a76ca4694ce0717c9050bc16a | |
| parent | 4652879f4360c5a7a9255e6a0dd75688f8ef47f9 (diff) | |
ZJIT: Increment specific counter on side-exit
| -rw-r--r-- | zjit.rb | 1 | ||||
| -rw-r--r-- | zjit/src/backend/lir.rs | 12 | ||||
| -rw-r--r-- | zjit/src/stats.rs | 38 |
3 files changed, 51 insertions, 0 deletions
@@ -59,6 +59,7 @@ class << RubyVM::ZJIT :ratio_in_zjit, ], buf:, stats:) print_counters_with_prefix(prefix: 'exit_', prompt: 'side exit reasons', buf:, stats:, limit: 20) + print_counters_with_prefix(prefix: 'specific_exit_', prompt: 'specific side exit reasons', buf:, stats:, limit: 20) buf end diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 7e317d4991..0639176fd6 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -1604,6 +1604,18 @@ impl Assembler Opnd::mem(64, SCRATCH_OPND, 0) }; self.incr_counter(counter_opnd, 1.into()); + + asm_comment!(self, "increment a specific exit counter"); + let counter = crate::stats::side_exit_reason_counter(reason); + self.load_into(SCRATCH_OPND, Opnd::const_ptr(crate::stats::counter_ptr(counter))); + let counter_opnd = if cfg!(target_arch = "aarch64") { // See arm64_split() + // Using C_CRET_OPND since arm64_emit uses both SCRATCH0 and SCRATCH1 for IncrCounter. + self.lea_into(C_RET_OPND, Opnd::mem(64, SCRATCH_OPND, 0)); + C_RET_OPND + } else { // x86_emit expects Opnd::Mem + Opnd::mem(64, SCRATCH_OPND, 0) + }; + self.incr_counter(counter_opnd, 1.into()); } asm_comment!(self, "exit to the interpreter"); diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index b754404a66..c6b1ed29d6 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -81,6 +81,23 @@ make_counters! { // exit_: Side exit reasons (ExitCounters shares the same prefix) exit_compilation_failure, + + // specific_exit_: Side exits counted by type, not by PC + specific_exit_unknown_newarray_send, + specific_exit_unknown_call_type, + specific_exit_unknown_opcode, + specific_exit_unhandled_instruction, + specific_exit_fixnum_add_overflow, + specific_exit_fixnum_sub_overflow, + specific_exit_fixnum_mult_overflow, + specific_exit_guard_type_failure, + specific_exit_guard_bit_equals_failure, + specific_exit_patchpoint, + specific_exit_callee_side_exit, + specific_exit_obj_to_string_fallback, + specific_exit_unknown_special_variable, + specific_exit_unhandled_defined_type, + specific_exit_interrupt, } /// Increase a counter by a specified amount @@ -107,6 +124,27 @@ pub fn exit_counter_ptr(pc: *const VALUE) -> *mut u64 { unsafe { exit_counters.get_unchecked_mut(opcode as usize) } } +pub fn side_exit_reason_counter(reason: crate::hir::SideExitReason) -> Counter { + use crate::hir::SideExitReason; + match reason { + SideExitReason::UnknownNewarraySend(_) => Counter::specific_exit_unknown_newarray_send, + SideExitReason::UnknownCallType => Counter::specific_exit_unknown_call_type, + SideExitReason::UnknownOpcode(_) => Counter::specific_exit_unknown_opcode, + SideExitReason::UnhandledInstruction(_) => Counter::specific_exit_unhandled_instruction, + SideExitReason::FixnumAddOverflow => Counter::specific_exit_fixnum_add_overflow, + SideExitReason::FixnumSubOverflow => Counter::specific_exit_fixnum_sub_overflow, + SideExitReason::FixnumMultOverflow => Counter::specific_exit_fixnum_mult_overflow, + SideExitReason::GuardType(_) => Counter::specific_exit_guard_type_failure, + SideExitReason::GuardBitEquals(_) => Counter::specific_exit_guard_bit_equals_failure, + SideExitReason::PatchPoint(_) => Counter::specific_exit_patchpoint, + SideExitReason::CalleeSideExit => Counter::specific_exit_callee_side_exit, + SideExitReason::ObjToStringFallback => Counter::specific_exit_obj_to_string_fallback, + SideExitReason::UnknownSpecialVariable(_) => Counter::specific_exit_unknown_special_variable, + SideExitReason::UnhandledDefinedType(_) => Counter::specific_exit_unhandled_defined_type, + SideExitReason::Interrupt => Counter::specific_exit_interrupt, + } +} + /// Return a Hash object that contains ZJIT statistics #[unsafe(no_mangle)] pub extern "C" fn rb_zjit_stats(_ec: EcPtr, _self: VALUE, target_key: VALUE) -> VALUE { |
