module RubyVM::YJIT

This module allows for introspection of YJIT, CRuby’s just-in-time compiler. Everything in the module is highly implementation specific and the API might be less stable compared to the standard library.

This module may not exist if YJIT does not support the particular platform for which CRuby is built.

Public Class Methods

code_gc() click to toggle source

Discard existing compiled code to reclaim memory and allow for recompilations in the future.

# File yjit.rb, line 218
def self.code_gc
dump_exit_locations(filename) click to toggle source

Marshal dumps exit locations to the given filename.


If --yjit-exit-locations is passed, a file named “yjit_exit_locations.dump” will automatically be generated.

If you want to collect traces manually, call dump_exit_locations directly.

Note that calling this in a script will generate stats after the dump is created, so the stats data may include exits from the dump itself.

In a script call:

at_exit do

Then run the file with the following options:

ruby --yjit --yjit-trace-exits test.rb

Once the code is done running, use Stackprof to read the dump file. See Stackprof documentation for options.

# File yjit.rb, line 142
def self.dump_exit_locations(filename)
  unless trace_exit_locations_enabled?
    raise ArgumentError, "--yjit-trace-exits must be enabled to use dump_exit_locations."

  File.binwrite(filename, Marshal.dump(RubyVM::YJIT.exit_locations))
enable() click to toggle source

Enable YJIT compilation.

# File yjit.rb, line 32
def self.enable
enabled?() click to toggle source

Check if YJIT is enabled.

# File yjit.rb, line 12
def self.enabled?
  Primitive.cexpr! 'RBOOL(rb_yjit_enabled_p)'
reset_stats!() click to toggle source

Discard statistics collected for --yjit-stats.

# File yjit.rb, line 27
def self.reset_stats!
runtime_stats(context: false) click to toggle source

Return a hash for statistics generated for the --yjit-stats command line option. Return nil when option is not passed or unavailable.

# File yjit.rb, line 152
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_enabled?() click to toggle source

Check if --yjit-stats is used.

# File yjit.rb, line 17
def self.stats_enabled?
stats_string() click to toggle source

Format and print out counters as a String. This returns a non-empty content only when --yjit-stats is enabled.

# File yjit.rb, line 185
def self.stats_string
  # Lazily require StringIO to avoid breaking miniruby
  require 'stringio'
  strio =
  _print_stats(out: strio)

Private Class Methods

format_number(pad, number) click to toggle source

Format large numbers with comma separators for readability

# File yjit.rb, line 471
def format_number(pad, number)
  s = number.to_s
  i = s.index('.') || s.size
  s.insert(i -= 3, ',') while i > 3
  s.rjust(pad, ' ')
format_number_pct(pad, number, total) click to toggle source

Format a number along with a percentage over a total value

# File yjit.rb, line 479
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})"