diff options
| author | Takashi Kokubun <takashi.kokubun@shopify.com> | 2025-08-27 10:01:07 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-27 10:01:07 -0700 |
| commit | 76810fc34905011535f50c3f8bbcaf39cb80b6cc (patch) | |
| tree | 686b602c371a6436d0ea25cc1a054b641b385db9 /zjit.rb | |
| parent | 61d26c35bf8c744b4c59a44536bc58a6c4653ab6 (diff) | |
ZJIT: Implement side exit stats (#14357)
Diffstat (limited to 'zjit.rb')
| -rw-r--r-- | zjit.rb | 45 |
1 files changed, 32 insertions, 13 deletions
@@ -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 |
