module RubyVM::YJIT - Documentation for Ruby 3.3

# 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 224
    def self.code_gc
      Primitive.rb_yjit_code_gc
    end

dump_exit_locations(filename) click to toggle source

`Marshal` dumps exit locations to the given filename.

Usage:

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
      RubyVM::YJIT.dump_exit_locations("my_file.dump")
    end

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 148
    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) click to toggle source

Enable YJIT compilation. `stats` option decides whether to enable YJIT stats or not.

- `false`: Disable stats.

- `true`: Enable stats. Print stats at exit.

- `:quiet`: Enable stats. Do not print stats at exit.

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

Check if YJIT is enabled.

    # File yjit.rb, line 12
    def self.enabled?
      Primitive.cexpr! 'RBOOL(rb_yjit_enabled_p)'
    end

reset_stats!() click to toggle source

Discard statistics collected for `--yjit-stats`.

    # File yjit.rb, line 27
    def self.reset_stats!
      Primitive.rb_yjit_reset_stats_bang
    end

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 158
    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?() click to toggle source

Check if `--yjit-stats` is used.

    # File yjit.rb, line 17
    def self.stats_enabled?
      Primitive.rb_yjit_stats_enabled_p
    end

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 191
    def self.stats_string
      # Lazily require StringIO to avoid breaking miniruby
      require 'stringio'
      strio = StringIO.new
      _print_stats(out: strio)
      strio.string
    end

### Private Class Methods

format_number(pad, number) click to toggle source

Format large numbers with comma separators for readability

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

Format a number along with a percentage over a total value

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

Print stats and dump exit locations

    # File yjit.rb, line 241
    def print_and_dump_stats
      if Primitive.rb_yjit_print_stats_p
        _print_stats
      end
      _dump_locations
    end