summaryrefslogtreecommitdiff
path: root/zjit.rb
diff options
context:
space:
mode:
authorTakashi Kokubun <takashi.kokubun@shopify.com>2025-08-27 10:01:07 -0700
committerGitHub <noreply@github.com>2025-08-27 10:01:07 -0700
commit76810fc34905011535f50c3f8bbcaf39cb80b6cc (patch)
tree686b602c371a6436d0ea25cc1a054b641b385db9 /zjit.rb
parent61d26c35bf8c744b4c59a44536bc58a6c4653ab6 (diff)
ZJIT: Implement side exit stats (#14357)
Diffstat (limited to 'zjit.rb')
-rw-r--r--zjit.rb45
1 files changed, 32 insertions, 13 deletions
diff --git a/zjit.rb b/zjit.rb
index b20c110046..cf0896e107 100644
--- a/zjit.rb
+++ b/zjit.rb
@@ -29,9 +29,9 @@ class << RubyVM::ZJIT
stats = Primitive.rb_zjit_stats(key)
return stats if stats.nil? || !key.nil?
- if stats.key?(:vm_insns_count) && stats.key?(:zjit_insns_count)
- stats[:total_insns_count] = stats[:vm_insns_count] + stats[:zjit_insns_count]
- stats[:ratio_in_zjit] = 100.0 * stats[:zjit_insns_count] / stats[:total_insns_count]
+ if stats.key?(:vm_insn_count) && stats.key?(:zjit_insn_count)
+ stats[:total_insn_count] = stats[:vm_insn_count] + stats[:zjit_insn_count]
+ stats[:ratio_in_zjit] = 100.0 * stats[:zjit_insn_count] / stats[:total_insn_count]
end
stats
@@ -52,11 +52,13 @@ class << RubyVM::ZJIT
:gc_time_ns,
:invalidation_time_ns,
- :total_insns_count,
- :vm_insns_count,
- :zjit_insns_count,
+ :side_exit_count,
+ :total_insn_count,
+ :vm_insn_count,
+ :zjit_insn_count,
:ratio_in_zjit,
], buf:, stats:)
+ print_counters_with_prefix(prefix: 'exit_', prompt: 'side exit reasons', buf:, stats:, limit: 20)
buf
end
@@ -70,9 +72,9 @@ class << RubyVM::ZJIT
private
def print_counters(keys, buf:, stats:)
- left_pad = keys.map(&:size).max + 1
+ left_pad = keys.map { |key| key.to_s.sub(/_time_ns\z/, '_time').size }.max + 1
keys.each do |key|
- # Some stats like vm_insns_count and ratio_in_zjit are not supported on the release build
+ # Some stats like vm_insn_count and ratio_in_zjit are not supported on the release build
next unless stats.key?(key)
value = stats[key]
@@ -90,11 +92,28 @@ class << RubyVM::ZJIT
end
end
- def print_counters_with_prefix(buf:, stats:, prefix:, prompt:)
- keys = stats.keys.select { |key| key.start_with?(prefix) && stats[key] > 0 }
- unless keys.empty?
- buf << "#{prompt}:\n"
- print_counters(keys, buf:, stats:)
+ def print_counters_with_prefix(buf:, stats:, prefix:, prompt:, limit: nil)
+ counters = stats.select { |key, value| key.start_with?(prefix) && value > 0 }
+ return if stats.empty?
+
+ counters.transform_keys! { |key| key.to_s.delete_prefix!(prefix) }
+ left_pad = counters.keys.map(&:size).max
+ right_pad = counters.values.map { |value| number_with_delimiter(value).size }.max
+ total = counters.values.sum
+ count = counters.size
+
+ counters = counters.to_a
+ counters.sort_by! { |_, value| -value }
+ counters = counters.first(limit) if limit
+
+ buf << "Top-#{counters.size} " if limit
+ buf << "#{prompt}"
+ buf << " (%.1f%% of all #{count})" % (100.0 * counters.map(&:last).sum / total) if limit
+ buf << ":\n"
+ counters.each do |key, value|
+ padded_key = key.rjust(left_pad, ' ')
+ padded_value = number_with_delimiter(value).rjust(right_pad, ' ')
+ buf << " #{padded_key}: #{padded_value} (%4.1f%%)\n" % (100.0 * value / total)
end
end