module ZJIT
Dieses Modul ermöglicht die Introspektion von ZJIT, dem Just-in-Time-Compiler von CRuby. Alles in diesem Modul ist stark implementierungsspezifisch und die API ist möglicherweise weniger stabil als die Standardbibliothek.
Dieses Modul existiert möglicherweise nicht, wenn ZJIT die spezielle Plattform, für die CRuby erstellt wurde, nicht unterstützt.
Öffentliche Klassenmethoden
Source
# File zjit.rb, line 140 def dump_exit_locations(filename) unless trace_exit_locations_enabled? raise ArgumentError, "--zjit-trace-exits must be enabled to use dump_exit_locations." end File.open(filename, "wb") do |file| Marshal.dump(RubyVM::ZJIT.exit_locations, file) file.size end end
Marshal speichert Ausstiegsorte in der angegebenen Datei.
Verwendung
In einem Skriptaufruf
RubyVM::ZJIT.dump_exit_locations("my_file.dump")
Führen Sie die Datei dann mit den folgenden Optionen aus
ruby --zjit --zjit-stats --zjit-trace-exits test.rb
Nachdem der Code beendet ist, verwenden Sie Stackprof, um die Dump-Datei zu lesen. Weitere Optionen finden Sie in der Stackprof-Dokumentation.
Source
# File zjit.rb, line 31 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
Aktiviert die ZJIT-Kompilierung.
Source
# File zjit.rb, line 26 def enabled? Primitive.cexpr! 'RBOOL(rb_zjit_enabled_p)' end
Prüft, ob ZJIT aktiviert ist.
Source
# File zjit.rb, line 51 def exit_locations return unless trace_exit_locations_enabled? results = Primitive.rb_zjit_get_exit_locations raw_samples = results[:raw] line_samples = results[:lines] frames = results[:frames] samples_count = 0 # Use nonexistent.def as a dummy file name. frame_template = { samples: 0, total_samples: 0, edges: {}, name: name, file: "nonexistent.def", line: nil, lines: {} } # Loop through all possible instructions and setup the frame hash. RubyVM::INSTRUCTION_NAMES.each_with_index do |name, frame_id| frames[frame_id] = frame_template.dup.tap { |h| h[:name] = name } end # Loop through the raw_samples and build the hashes for StackProf. # The loop is based off an example in the StackProf documentation and therefore # this functionality can only work with that library. # # Raw Samples: # [ length, frame1, frame2, frameN, ..., instruction, count # # Line Samples # [ length, line_1, line_2, line_n, ..., dummy value, count i = 0 while i < raw_samples.length stack_length = raw_samples[i] i += 1 # consume the stack length sample_count = raw_samples[i + stack_length] prev_frame_id = nil stack_length.times do |idx| idx += i frame_id = raw_samples[idx] if prev_frame_id prev_frame = frames[prev_frame_id] prev_frame[:edges][frame_id] ||= 0 prev_frame[:edges][frame_id] += sample_count end frame_info = frames[frame_id] frame_info[:total_samples] += sample_count frame_info[:lines][line_samples[idx]] ||= [0, 0] frame_info[:lines][line_samples[idx]][0] += sample_count prev_frame_id = frame_id end i += stack_length # consume the stack top_frame_id = prev_frame_id top_frame_line = 1 frames[top_frame_id][:samples] += sample_count frames[top_frame_id][:lines] ||= {} frames[top_frame_id][:lines][top_frame_line] ||= [0, 0] frames[top_frame_id][:lines][top_frame_line][1] += sample_count samples_count += sample_count i += 1 end results[:samples] = samples_count # These values are mandatory to include for stackprof, but we don't use them. results[:missed_samples] = 0 results[:gc_samples] = 0 results end
Wenn –zjit-trace-exits aktiviert ist, werden die Hashes von Primitive.rb_zjit_get_exit_locations in ein von Stackprof lesbares Format geparst. Dies ermöglicht es uns, den genauen Ort eines Seiten-Ausstiegs in ZJIT basierend auf der aussteigenden Anweisung zu finden.
Source
# File zjit.rb, line 162 def reset_stats! Primitive.rb_zjit_reset_stats_bang end
Verwirft die für „–zjit-stats“ gesammelten Statistiken.
Source
# File zjit.rb, line 157 def stats(target_key = nil) Primitive.rb_zjit_stats(target_key) end
Gibt ZJIT-Statistiken als Hash zurück.
Source
# File zjit.rb, line 152 def stats_enabled? Primitive.rb_zjit_stats_enabled_p end
Prüft, ob „–zjit-stats“ verwendet wird.
Source
# File zjit.rb, line 167 def stats_string buf = +"***ZJIT: Printing ZJIT statistics on exit***\n" stats = self.stats 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 # 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) # 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: '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) # 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, :failed_iseq_count, :compile_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, :vm_read_from_parent_iseq_local_count, :guard_type_count, :guard_type_exit_ratio, :guard_shape_count, :guard_shape_exit_ratio, :code_region_bytes, :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
Ruft die Zusammenfassung der ZJIT-Statistiken als String ab.
Source
# File zjit.rb, line 43 def trace_exit_locations_enabled? Primitive.rb_zjit_trace_exit_locations_enabled_p end
Prüft, ob „–zjit-trace-exits“ verwendet wird.