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
Source
# File zjit.rb, line 29 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.
Source
# File zjit.rb, line 24 def enabled? Primitive.cexpr! 'RBOOL(rb_zjit_enabled_p)' end
Check if ZJIT is enabled
Source
# File zjit.rb, line 62 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.
Source
# File zjit.rb, line 50 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.
Source
# File zjit.rb, line 57 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.
Source
# File zjit.rb, line 78 def max_compile_time_ns Primitive.rb_zjit_max_compile_time_ns_get end
The maximum amount of time ZJIT is allowed to spend compiling. When total_compile_time_ns goes over max_compile_time_ns, YJIT pause compilation until max_compile_time_ns is raised. If set to 0, there is no limit. This is a best-effort functionality, there are situations in which ZJIT may still compile even when paused. This feature is intended to be used to control how fast the JIT warms up, to spread the compilation overhead over a longer period of time.
# File zjit.rb, line 83 def max_compile_time_ns=(max_compile_time_ns) Primitive.rb_zjit_max_compile_time_ns_set(max_compile_time_ns) end
Set the maximum amount of time YJIT is allowed to spend compiling.
Source
# File zjit.rb, line 98 def reset_stats! Primitive.rb_zjit_reset_stats_bang end
Discard statistics collected for --zjit-stats.
Source
# File zjit.rb, line 93 def stats(target_key = nil) Primitive.rb_zjit_stats(target_key) end
Return ZJIT statistics as a Hash
Source
# File zjit.rb, line 88 def stats_enabled? Primitive.rb_zjit_stats_enabled_p end
Check if --zjit-stats is used
Source
# File zjit.rb, line 103 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_bytes].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_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: 'send_direct_fallback_context_', prompt: 'SendDirect fallback contexts', buf:, stats:, limit: 10) 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: 'inline_reject_', prompt: 'HIR-level inlining rejection reasons', 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) print_counters_with_prefix(prefix: 'caller_splat_profile_', prompt: 'caller splat length profiles', 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, :iseq_optimized_send_count, :inline_cfunc_optimized_send_count, :inline_iseq_optimized_send_count, :inline_method_count, :empty_inline_frame_count, :non_variadic_cfunc_optimized_send_count, :variadic_cfunc_optimized_send_count, :caller_splat_optimized, ], buf:, stats:, right_align: true, base: :send_count) print_counters([ :dynamic_setivar_count, :dynamic_getivar_count, :dynamic_definedivar_count, :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_inline_methods_time_ns, :compile_hir_remove_trivial_block_params_time_ns, :compile_hir_optimize_load_store_time_ns, :compile_hir_canonicalize_time_ns, :compile_hir_fold_constants_time_ns, :compile_hir_clean_cfg_time_ns, :compile_hir_remove_redundant_patch_points_time_ns, :compile_hir_remove_duplicate_check_interrupts_time_ns, :compile_hir_eliminate_dead_code_time_ns, :compile_lir_time_ns, :profile_time_ns, :gc_time_ns, :invalidation_time_ns, :vm_write_jit_frame_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, :throw_count, :side_exit_size_bytes, :side_exit_size_ratio, :jit_frame_heap_bytes, :jit_frame_region_bytes, :code_region_bytes, :zjit_alloc_bytes, :total_mem_bytes, :total_native_stack_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
Source
# File zjit.rb, line 66 def total_compile_time_ns Primitive.rb_zjit_total_compile_time_ns_get end
Monotonically increasing counter representing the amount of wall time nanoseconds spent compiling.
# File zjit.rb, line 41 def trace_exit_locations_enabled? Primitive.rb_zjit_trace_exit_locations_enabled_p end
Check if --zjit-trace-exits is used