module RubyVM::ZJIT - Documentation for Ruby 4.1
Description: module RubyVM::ZJIT: This module allows for introspection of ZJIT, CRuby's just-in-time compiler. Everything in the module is highly implementation specific and the API mi
Keywords: ruby,module,RubyVM::ZJIT

🔍

No recent searches

# module RubyVM::ZJIT

This module allows for introspection of ZJIT, 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 ZJIT does not support the particular platform for which CRuby is built.

### Public Class Methods

enable ()
Source

    # File zjit.rb, line 28
    def enable
      return false if enabled?

      if Primitive.cexpr! 'RBOOL(rb_yjit_enabled_p)'
        warn("Only one JIT can be enabled at the same time.")
        return false
      end

      Primitive.rb_zjit_enable
    end

Enable ZJIT compilation.

enabled? ()
Source

    # File zjit.rb, line 23
    def enabled?
      Primitive.cexpr! 'RBOOL(rb_zjit_enabled_p)'
    end

Check if ZJIT is enabled

induce_breakpoint! ()
Source

    # File zjit.rb, line 61
    def induce_breakpoint! = nil

A directive for the compiler to emit a breakpoint instruction at the call site of this method. To show this to ZJIT, say `::RubyVM::ZJIT.induce_breakpoint!` verbatim. Other forms are too dynamic to detect during compilation.

induce_compile_failure! ()
Source

    # File zjit.rb, line 49
    def induce_compile_failure! = nil

A directive for the compiler to fail to compile the call to this method. To show this to ZJIT, say `::RubyVM::ZJIT.induce_compile_failure!` verbatim. Other forms are too dynamic to detect during compilation.

Actually running this method does nothing, whether ZJIT sees the call or not.

induce_side_exit! ()
Source

    # File zjit.rb, line 56
    def induce_side_exit! = nil

A directive for the compiler to exit out of compiled code at the call site of this method. To show this to ZJIT, say `::RubyVM::ZJIT.induce_side_exit!` verbatim. Other forms are too dynamic to detect during compilation.

Actually running this method does nothing, whether ZJIT sees the call or not.

reset_stats! ()
Source

    # File zjit.rb, line 74
    def reset_stats!
      Primitive.rb_zjit_reset_stats_bang
    end

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

stats (target_key = nil)
Source

    # File zjit.rb, line 69
    def stats(target_key = nil)
      Primitive.rb_zjit_stats(target_key)
    end

Return ZJIT statistics as a `Hash`

stats_enabled? ()
Source

    # File zjit.rb, line 64
    def stats_enabled?
      Primitive.rb_zjit_stats_enabled_p
    end

Check if `--zjit-stats` is used

stats_string ()
Source

    # File zjit.rb, line 79
    def stats_string
      return unless stats = self.stats
      buf = +"***ZJIT: Printing ZJIT statistics on exit***\n"

      if stats[:guard_type_count]&.nonzero?
        stats[:guard_type_exit_ratio] = stats[:exit_guard_type_failure].to_f / stats[:guard_type_count] * 100
      end
      if stats[:guard_shape_count]&.nonzero?
        stats[:guard_shape_exit_ratio] = stats[:exit_guard_shape_failure].to_f / stats[:guard_shape_count] * 100
      end
      if stats[:code_region_bytes]&.nonzero?
        stats[:side_exit_size_ratio] = stats[:side_exit_size].to_f / stats[:code_region_bytes] * 100
      end
      if stats[:compile_time_ns]&.nonzero?
        stats[:compile_side_exit_time_ratio] = stats[:compile_side_exit_time_ns].to_f / stats[:compile_time_ns] * 100
      end

      # Show counters independent from exit_* or dynamic_send_*
      print_counters_with_prefix(prefix: 'not_inlined_cfuncs_', prompt: 'not inlined C methods', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'ccall_', prompt: 'calls to C functions from JIT code', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'iseq_calls_count_', prompt: 'most called JIT functions', buf:, stats:, limit: 20)
      # Don't show not_annotated_cfuncs right now because it mostly duplicates not_inlined_cfuncs
      # print_counters_with_prefix(prefix: 'not_annotated_cfuncs_', prompt: 'not annotated C methods', buf:, stats:, limit: 20)

      # Show fallback counters, ordered by the typical amount of fallbacks for the prefix at the time
      print_counters_with_prefix(prefix: 'unspecialized_send_def_type_', prompt: 'not optimized method types for send', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'unspecialized_send_without_block_def_type_', prompt: 'not optimized method types for send_without_block', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'unspecialized_super_def_type_', prompt: 'not optimized method types for super', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'uncategorized_fallback_yarv_insn_', prompt: 'instructions with uncategorized fallback reason', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'send_fallback_', prompt: 'send fallback reasons', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'setivar_fallback_', prompt: 'setivar fallback reasons', buf:, stats:, limit: 5)
      print_counters_with_prefix(prefix: 'getivar_fallback_', prompt: 'getivar fallback reasons', buf:, stats:, limit: 5)
      print_counters_with_prefix(prefix: 'definedivar_fallback_', prompt: 'definedivar fallback reasons', buf:, stats:, limit: 5)
      print_counters_with_prefix(prefix: 'invokeblock_handler_', prompt: 'invokeblock handler', buf:, stats:, limit: 10)
      print_counters_with_prefix(prefix: 'getblockparamproxy_handler_', prompt: 'getblockparamproxy handler', buf:, stats:, limit: 10)

      # Show most popular unsupported call features. Because each call can
      # use multiple complex features, a decrease in this number does not
      # necessarily mean an increase in number of optimized calls.
      print_counters_with_prefix(prefix: 'complex_arg_pass_', prompt: 'popular complex argument-parameter features not optimized', buf:, stats:, limit: 10)

      # Show exit counters, ordered by the typical amount of exits for the prefix at the time
      print_counters_with_prefix(prefix: 'compile_error_', prompt: 'compile error reasons', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'unhandled_yarv_insn_', prompt: 'unhandled YARV insns', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'unhandled_hir_insn_', prompt: 'unhandled HIR insns', buf:, stats:, limit: 20)
      print_counters_with_prefix(prefix: 'exit_', prompt: 'side exit reasons', buf:, stats:, limit: 20)

      # Show no-prefix counters, having the most important stat `ratio_in_zjit` at the end
      print_counters([
        :send_count,
        :dynamic_send_count,
        :optimized_send_count,
        :dynamic_setivar_count,
        :dynamic_getivar_count,
        :dynamic_definedivar_count,
        :iseq_optimized_send_count,
        :inline_cfunc_optimized_send_count,
        :inline_iseq_optimized_send_count,
        :non_variadic_cfunc_optimized_send_count,
        :variadic_cfunc_optimized_send_count,
      ], buf:, stats:, right_align: true, base: :send_count)
      print_counters([
        :compiled_iseq_count,
        :compiled_side_exit_count,
        :failed_iseq_count,

        :compile_time_ns,
        :compile_side_exit_time_ns,
        :compile_side_exit_time_ratio,
        :compile_hir_time_ns,
        :compile_hir_build_time_ns,
        :compile_hir_strength_reduce_time_ns,
        :compile_hir_fold_constants_time_ns,
        :compile_hir_clean_cfg_time_ns,
        :compile_hir_eliminate_dead_code_time_ns,
        :compile_lir_time_ns,
        :profile_time_ns,
        :gc_time_ns,
        :invalidation_time_ns,

        :vm_write_pc_count,
        :vm_write_sp_count,
        :vm_write_locals_count,
        :vm_write_stack_count,
        :vm_write_to_parent_iseq_local_count,

        :guard_type_count,
        :guard_type_exit_ratio,
        :guard_shape_count,
        :guard_shape_exit_ratio,

        :load_field_count,
        :store_field_count,

        :side_exit_size,
        :code_region_bytes,
        :side_exit_size_ratio,
        :zjit_alloc_bytes,
        :total_mem_bytes,

        :side_exit_count,
        :total_insn_count,
        :vm_insn_count,
        :zjit_insn_count,
        :ratio_in_zjit,
      ], buf:, stats:)

      buf
    end

Get the summary of ZJIT statistics as a `String`

trace_exit_locations_enabled? ()
Source

    # File zjit.rb, line 40
    def trace_exit_locations_enabled?
      Primitive.rb_zjit_trace_exit_locations_enabled_p
    end

Check if `--zjit-trace-exits` is used