YJIT: Make ratio_in_yjit always available (#8064)

This commit is contained in:
Takashi Kokubun 2023-07-13 15:14:43 -07:00 коммит произвёл GitHub
Родитель e850181acf
Коммит d814722fb8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 30 добавлений и 34 удалений

Просмотреть файл

@ -76,6 +76,11 @@ VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
VALUE data2);
void rb_check_stack_overflow(void);
#if USE_YJIT
/* vm_exec.c */
extern uint64_t rb_vm_insns_count;
#endif
/* vm_insnhelper.c */
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
VALUE rb_eql_opt(VALUE obj1, VALUE obj2);

Просмотреть файл

@ -11,6 +11,11 @@
#include <math.h>
#if USE_YJIT
// The number of instructions executed on vm_exec_core. --yjit-stats uses this.
uint64_t rb_vm_insns_count = 0;
#endif
#if VM_COLLECT_USAGE_DETAILS
static void vm_analysis_insn(int insn);
#endif

Просмотреть файл

@ -20,8 +20,11 @@ RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
# define RJIT_STATS RUBY_DEBUG
#endif
#if YJIT_STATS
#define YJIT_COLLECT_USAGE_INSN(insn) rb_yjit_collect_vm_usage_insn(insn)
#if USE_YJIT // We want vm_insns_count on any YJIT-enabled build
// Increment vm_insns_count for --yjit-stats. We increment this even when
// --yjit or --yjit-stats is not used because branching to skip it is slower.
// We also don't use ATOMIC_INC for performance, allowing inaccuracy on Ractors.
#define YJIT_COLLECT_USAGE_INSN(insn) rb_vm_insns_count++
#else
#define YJIT_COLLECT_USAGE_INSN(insn) // none
#endif

2
yjit.h
Просмотреть файл

@ -30,7 +30,6 @@ bool rb_yjit_compile_new_iseqs(void);
unsigned rb_yjit_call_threshold(void);
void rb_yjit_invalidate_all_method_lookup_assumptions(void);
void rb_yjit_cme_invalidate(rb_callable_method_entry_t *cme);
void rb_yjit_collect_vm_usage_insn(int insn);
void rb_yjit_collect_binding_alloc(void);
void rb_yjit_collect_binding_set(void);
bool rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec);
@ -53,7 +52,6 @@ static inline bool rb_yjit_compile_new_iseqs(void) { return false; }
static inline unsigned rb_yjit_call_threshold(void) { return UINT_MAX; }
static inline void rb_yjit_invalidate_all_method_lookup_assumptions(void) {}
static inline void rb_yjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
static inline void rb_yjit_collect_vm_usage_insn(int insn) {}
static inline void rb_yjit_collect_binding_alloc(void) {}
static inline void rb_yjit_collect_binding_set(void) {}
static inline bool rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec) { return false; }

23
yjit.rb
Просмотреть файл

@ -167,14 +167,11 @@ module RubyVM::YJIT
# Average length of instruction sequences executed by YJIT
avg_len_in_yjit = total_exits > 0 ? retired_in_yjit.to_f / total_exits : 0
# This only available on yjit stats builds
if stats.key?(:vm_insns_count)
# 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
end
# 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
@ -318,14 +315,10 @@ module RubyVM::YJIT
out.puts "object_shape_count: " + format_number(13, stats[:object_shape_count])
out.puts "side_exit_count: " + format_number(13, stats[:side_exit_count])
out.puts "total_exit_count: " + format_number(13, stats[:total_exit_count])
out.puts "total_insns_count: " + format_number(13, stats[:total_insns_count]) if stats.key?(:total_insns_count)
if stats.key?(:vm_insns_count)
out.puts "vm_insns_count: " + format_number(13, stats[:vm_insns_count])
end
out.puts "total_insns_count: " + format_number(13, stats[:total_insns_count])
out.puts "vm_insns_count: " + format_number(13, stats[:vm_insns_count])
out.puts "yjit_insns_count: " + format_number(13, stats[:exec_instruction])
if stats.key?(:ratio_in_yjit)
out.puts "ratio_in_yjit: " + ("%12.1f" % stats[:ratio_in_yjit]) + "%"
end
out.puts "ratio_in_yjit: " + ("%12.1f" % stats[:ratio_in_yjit]) + "%"
out.puts "avg_len_in_yjit: " + ("%13.1f" % stats[:avg_len_in_yjit])
print_sorted_exit_counts(stats, out: out, prefix: "exit_")

Просмотреть файл

@ -357,6 +357,9 @@ fn main() {
.allowlist_function("rb_ivar_defined")
.allowlist_function("rb_ivar_get")
// From internal/vm.h
.allowlist_var("rb_vm_insns_count")
// From include/ruby/internal/intern/vm.h
.allowlist_function("rb_get_alloc_func")

Просмотреть файл

@ -1135,6 +1135,7 @@ extern "C" {
n: ::std::os::raw::c_long,
elts: *const VALUE,
) -> VALUE;
pub static mut rb_vm_insns_count: u64;
pub fn rb_method_entry_at(obj: VALUE, id: ID) -> *const rb_method_entry_t;
pub fn rb_callable_method_entry(klass: VALUE, id: ID) -> *const rb_callable_method_entry_t;
pub fn rb_callable_method_entry_or_negative(

Просмотреть файл

@ -369,7 +369,6 @@ make_counters! {
binding_allocations,
binding_set,
vm_insns_count,
compiled_iseq_entry,
compiled_iseq_count,
compiled_blockid_count,
@ -507,7 +506,6 @@ fn rb_yjit_gen_stats_dict(context: bool) -> VALUE {
let hash = unsafe { rb_hash_new() };
// CodeBlock stats
unsafe {
// Get the inline and outlined code blocks
let cb = CodegenGlobals::get_inline_cb();
@ -547,6 +545,9 @@ fn rb_yjit_gen_stats_dict(context: bool) -> VALUE {
hash_aset_usize!(hash, "live_context_count", live_context_count);
hash_aset_usize!(hash, "live_context_size", live_context_count * context_size);
}
// VM instructions count
hash_aset_usize!(hash, "vm_insns_count", rb_vm_insns_count as usize);
}
// If we're not generating stats, the hash is done
@ -566,13 +567,6 @@ fn rb_yjit_gen_stats_dict(context: bool) -> VALUE {
let counter_ptr = get_counter_ptr(counter_name);
let counter_val = *counter_ptr;
#[cfg(not(feature = "stats"))]
if counter_name == &"vm_insns_count" {
// If the stats feature is disabled, we don't have vm_insns_count
// so we are going to exclude the key
continue;
}
// Put counter into hash
let key = rust_str_to_sym(counter_name);
let value = VALUE::fixnum_from_usize(counter_val as usize);
@ -750,12 +744,6 @@ pub extern "C" fn rb_yjit_reset_stats_bang(_ec: EcPtr, _ruby_self: VALUE) -> VAL
return Qnil;
}
/// Increment the number of instructions executed by the interpreter
#[no_mangle]
pub extern "C" fn rb_yjit_collect_vm_usage_insn() {
incr_counter!(vm_insns_count);
}
#[no_mangle]
pub extern "C" fn rb_yjit_collect_binding_alloc() {
incr_counter!(binding_allocations);