From ce8f699261bc21970d4a382d79e525f66223c0f1 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 17 Oct 2023 13:22:49 -0400 Subject: [PATCH] YJIT: Add a live ISeq counter It's an estimator for application size and could be used as a compilation heuristic later. Co-authored-by: Maxime Chevalier-Boisvert Co-authored-by: Takashi Kokubun --- common.mk | 1 + compile.c | 6 ++++++ iseq.c | 2 ++ yjit.h | 1 + yjit.rb | 1 + yjit/src/stats.rs | 6 ++++++ 6 files changed, 17 insertions(+) diff --git a/common.mk b/common.mk index fce0cfd8b852f4..cc67e67db8960a 100644 --- a/common.mk +++ b/common.mk @@ -3429,6 +3429,7 @@ compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h compile.$(OBJEXT): {$(VPATH)}vm_core.h compile.$(OBJEXT): {$(VPATH)}vm_debug.h compile.$(OBJEXT): {$(VPATH)}vm_opts.h +compile.$(OBJEXT): {$(VPATH)}yjit.h complex.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h complex.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h complex.$(OBJEXT): $(CCAN_DIR)/list/list.h diff --git a/compile.c b/compile.c index fcae05da9fe809..d7508fbeef1ba7 100644 --- a/compile.c +++ b/compile.c @@ -39,6 +39,7 @@ #include "vm_core.h" #include "vm_callinfo.h" #include "vm_debug.h" +#include "yjit.h" #include "builtin.h" #include "insns.inc" @@ -1019,6 +1020,11 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) } FL_SET((VALUE)iseq, ISEQ_TRANSLATED); #endif + +#if USE_YJIT + rb_yjit_live_iseq_count++; +#endif + return COMPILE_OK; } diff --git a/iseq.c b/iseq.c index 0bd4b2812b1ae9..1c7bafc5a25deb 100644 --- a/iseq.c +++ b/iseq.c @@ -168,6 +168,8 @@ rb_iseq_free(const rb_iseq_t *iseq) rb_rjit_free_iseq(iseq); /* Notify RJIT */ #if USE_YJIT rb_yjit_iseq_free(body->yjit_payload); + RUBY_ASSERT(rb_yjit_live_iseq_count > 0); + rb_yjit_live_iseq_count--; #endif ruby_xfree((void *)body->iseq_encoded); ruby_xfree((void *)body->insns_info.body); diff --git a/yjit.h b/yjit.h index 84a3655156332b..33b9214952e8df 100644 --- a/yjit.h +++ b/yjit.h @@ -27,6 +27,7 @@ // Expose these as declarations since we are building YJIT. extern uint64_t rb_yjit_call_threshold; extern uint64_t rb_yjit_cold_threshold; +extern uint64_t rb_yjit_live_iseq_count; void rb_yjit_incr_counter(const char *counter_name); bool rb_yjit_enabled_p(void); bool rb_yjit_compile_new_iseqs(void); diff --git a/yjit.rb b/yjit.rb index 39c3e6a5094f2e..4f012b70286611 100644 --- a/yjit.rb +++ b/yjit.rb @@ -318,6 +318,7 @@ def _print_stats(out: $stderr) # :nodoc: out.puts "compilation_failure: " + format_number(13, compilation_failure) if compilation_failure != 0 out.puts "compiled_iseq_entry: " + format_number(13, stats[:compiled_iseq_entry]) out.puts "cold_iseq_entry: " + format_number_pct(13, stats[:cold_iseq_entry], stats[:compiled_iseq_entry] + stats[:cold_iseq_entry]) + out.puts "live_iseq_count: " + format_number(13, stats[:live_iseq_count]) out.puts "compiled_iseq_count: " + format_number(13, stats[:compiled_iseq_count]) out.puts "compiled_blockid_count:" + format_number(13, stats[:compiled_blockid_count]) out.puts "compiled_block_count: " + format_number(13, stats[:compiled_block_count]) diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index 7d44b388cd1cfe..d35cdc22a4ad46 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -14,6 +14,10 @@ use crate::cruby::*; use crate::options::*; use crate::yjit::yjit_enabled_p; +/// A running total of how many ISeqs are in the system. +#[no_mangle] +pub static mut rb_yjit_live_iseq_count: u64 = 0; + /// A middleware to count Rust-allocated bytes as yjit_alloc_size. #[global_allocator] static GLOBAL_ALLOCATOR: StatsAlloc = StatsAlloc { alloc_size: AtomicUsize::new(0) }; @@ -635,6 +639,8 @@ fn rb_yjit_gen_stats_dict(context: bool) -> VALUE { // VM instructions count hash_aset_usize!(hash, "vm_insns_count", rb_vm_insns_count as usize); + + hash_aset_usize!(hash, "live_iseq_count", rb_yjit_live_iseq_count as usize); } // If we're not generating stats, put only default counters