зеркало из https://github.com/github/ruby.git
YJIT: Make ratio_in_yjit always available (#8064)
This commit is contained in:
Родитель
e850181acf
Коммит
d814722fb8
|
@ -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
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
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче