模块 RubyVM::YJIT
此模块允许对 YJIT 进行自省,YJIT 是 CRuby 的即时编译器。模块中的所有内容都是高度实现特定的,并且 API 与标准库相比可能不太稳定。
如果 YJIT 不支持构建 CRuby 的特定平台,则此模块可能不存在。
公共类方法
code_gc() 点击切换源代码
丢弃现有的编译代码以回收内存,并允许将来重新编译。
# File ruby_3_3_0/yjit.rb, line 220 def self.code_gc Primitive.rb_yjit_code_gc end
dump_exit_locations(filename) 点击切换源代码
Marshal
将退出位置转储到给定的文件名。
用法
如果传递了 --yjit-exit-locations
,则会自动生成一个名为“yjit_exit_locations.dump”的文件。
如果您想手动收集跟踪,请直接调用 dump_exit_locations
。
请注意,在脚本中调用此方法将在创建转储后生成统计信息,因此统计信息数据可能包括来自转储本身的退出。
在脚本调用中
at_exit do RubyVM::YJIT.dump_exit_locations("my_file.dump") end
然后使用以下选项运行文件
ruby --yjit --yjit-trace-exits test.rb
代码运行完毕后,使用 Stackprof 读取转储文件。有关选项,请参阅 Stackprof 文档。
# File ruby_3_3_0/yjit.rb, line 144 def self.dump_exit_locations(filename) unless trace_exit_locations_enabled? raise ArgumentError, "--yjit-trace-exits must be enabled to use dump_exit_locations." end File.binwrite(filename, Marshal.dump(RubyVM::YJIT.exit_locations)) end
enable(stats: false) 点击切换源代码
启用 YJIT 编译。
# File ruby_3_3_0/yjit.rb, line 32 def self.enable(stats: false) return false if enabled? at_exit { print_and_dump_stats } if stats Primitive.rb_yjit_enable(stats, stats != :quiet) end
enabled?() 点击切换源代码
检查 YJIT 是否已启用。
# File ruby_3_3_0/yjit.rb, line 12 def self.enabled? Primitive.cexpr! 'RBOOL(rb_yjit_enabled_p)' end
reset_stats!() 点击切换源代码
丢弃为 --yjit-stats
收集的统计信息。
# File ruby_3_3_0/yjit.rb, line 27 def self.reset_stats! Primitive.rb_yjit_reset_stats_bang end
runtime_stats(context: false) 点击切换源代码
返回为 --yjit-stats
命令行选项生成的统计信息的哈希。当未传递或不可用时返回 nil
。
# File ruby_3_3_0/yjit.rb, line 154 def self.runtime_stats(context: false) stats = Primitive.rb_yjit_get_stats(context) return stats if stats.nil? stats[:object_shape_count] = Primitive.object_shape_count return stats unless Primitive.rb_yjit_stats_enabled_p side_exits = total_exit_count(stats) total_exits = side_exits + stats[:leave_interp_return] # Number of instructions that finish executing in YJIT. # See :count-placement: about the subtraction. retired_in_yjit = stats[:yjit_insns_count] - side_exits # Average length of instruction sequences executed by YJIT avg_len_in_yjit = total_exits > 0 ? retired_in_yjit.to_f / total_exits : 0 # Proportion of instructions that retire in YJIT total_insns_count = retired_in_yjit + stats[:vm_insns_count] yjit_ratio_pct = 100.0 * retired_in_yjit.to_f / total_insns_count stats[:total_insns_count] = total_insns_count stats[:ratio_in_yjit] = yjit_ratio_pct # Make those stats available in RubyVM::YJIT.runtime_stats as well stats[:side_exit_count] = side_exits stats[:total_exit_count] = total_exits stats[:avg_len_in_yjit] = avg_len_in_yjit stats end
stats_enabled?() 点击切换源代码
检查是否使用了 --yjit-stats
。
# File ruby_3_3_0/yjit.rb, line 17 def self.stats_enabled? Primitive.rb_yjit_stats_enabled_p end
stats_string() 点击切换源代码
将计数器格式化为 String
并打印出来。仅当启用 --yjit-stats
时,此方法才会返回非空内容。
# File ruby_3_3_0/yjit.rb, line 187 def self.stats_string # Lazily require StringIO to avoid breaking miniruby require 'stringio' strio = StringIO.new _print_stats(out: strio) strio.string end
私有类方法
format_number(pad, number) 点击切换源代码
使用逗号分隔符格式化大数字,以提高可读性
# File ruby_3_3_0/yjit.rb, line 476 def format_number(pad, number) s = number.to_s i = s.index('.') || s.size s.insert(i -= 3, ',') while i > 3 s.rjust(pad, ' ') end
format_number_pct(pad, number, total) 点击切换源代码
格式化数字以及相对于总值的百分比
# File ruby_3_3_0/yjit.rb, line 484 def format_number_pct(pad, number, total) padded_count = format_number(pad, number) percentage = number.fdiv(total) * 100 formatted_pct = "%4.1f%%" % percentage "#{padded_count} (#{formatted_pct})" end
print_and_dump_stats() 点击切换源代码
打印统计信息并转储退出位置
# File ruby_3_3_0/yjit.rb, line 237 def print_and_dump_stats if Primitive.rb_yjit_print_stats_p _print_stats end _dump_locations end