From ea77aa2fd0899820752df7de6077a3b847a20aee Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 3 Nov 2022 10:41:35 -0700 Subject: YJIT: Make Code GC metrics available for non-stats builds (#6665) --- NEWS.md | 3 +++ test/ruby/test_yjit.rb | 8 ++++---- yjit/src/asm/mod.rs | 2 -- yjit/src/codegen.rs | 11 ++++++++++- yjit/src/stats.rs | 4 +++- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9156ef7a68..0367e8bfd0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -330,6 +330,9 @@ The following deprecated APIs are removed. memory pages until actually utilized by JIT code. * Introduce Code GC that frees all code pages when the memory consumption by JIT code reaches `--yjit-exec-mem-size`. +* `RubyVM::YJIT.runtime_stats` returns Code GC metrics in addition to + existing `inline_code_size` and `outlined_code_size` keys: + `code_gc_count`, `live_page_count`, `freed_page_count`, and `freed_code_size`. ### MJIT diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 57a60db89b..1a564889af 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -837,7 +837,7 @@ class TestYJIT < Test::Unit::TestCase return :not_compiled2 unless compiles { nil } # should be JITable again code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count] - return :"code_gc_#{code_gc_count}" if code_gc_count && code_gc_count != 2 + return :"code_gc_#{code_gc_count}" if code_gc_count != 2 :ok RUBY @@ -858,7 +858,7 @@ class TestYJIT < Test::Unit::TestCase return :broken_resume2 if fiber.resume != 0 # The code should be still callable code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count] - return :"code_gc_#{code_gc_count}" if code_gc_count && code_gc_count != 1 + return :"code_gc_#{code_gc_count}" if code_gc_count != 1 :ok RUBY @@ -890,7 +890,7 @@ class TestYJIT < Test::Unit::TestCase return :not_paged4 unless add_pages(100) # check everything still works code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count] - return :"code_gc_#{code_gc_count}" if code_gc_count && code_gc_count != 3 + return :"code_gc_#{code_gc_count}" if code_gc_count != 3 :ok RUBY @@ -912,7 +912,7 @@ class TestYJIT < Test::Unit::TestCase return :broken_resume2 if fiber.resume != 0 # on-stack code should be callable code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count] - return :"code_gc_#{code_gc_count}" if code_gc_count && code_gc_count == 0 + return :"code_gc_#{code_gc_count}" if code_gc_count == 0 :ok RUBY diff --git a/yjit/src/asm/mod.rs b/yjit/src/asm/mod.rs index 1be4488006..3d7de7cd79 100644 --- a/yjit/src/asm/mod.rs +++ b/yjit/src/asm/mod.rs @@ -10,7 +10,6 @@ use crate::core::IseqPayload; use crate::core::for_each_off_stack_iseq_payload; use crate::core::for_each_on_stack_iseq_payload; use crate::invariants::rb_yjit_tracing_invalidate_all; -use crate::stats::incr_counter; use crate::virtualmem::WriteError; #[cfg(feature = "disasm")] @@ -605,7 +604,6 @@ impl CodeBlock { } CodegenGlobals::set_freed_pages(freed_pages); - incr_counter!(code_gc_count); } pub fn inline(&self) -> bool { diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 8e36c44823..46f5ed64d3 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -6724,6 +6724,9 @@ pub struct CodegenGlobals { /// Freed page indexes. None if code GC has not been used. freed_pages: Option>, + + /// How many times code GC has been executed. + code_gc_count: usize, } /// For implementing global code invalidation. A position in the inline @@ -6816,6 +6819,7 @@ impl CodegenGlobals { method_codegen_table: HashMap::new(), ocb_pages, freed_pages: None, + code_gc_count: 0, }; // Register the method codegen functions @@ -6961,7 +6965,12 @@ impl CodegenGlobals { } pub fn set_freed_pages(freed_pages: Vec) { - CodegenGlobals::get_instance().freed_pages = Some(freed_pages) + CodegenGlobals::get_instance().freed_pages = Some(freed_pages); + CodegenGlobals::get_instance().code_gc_count += 1; + } + + pub fn get_code_gc_count() -> usize { + CodegenGlobals::get_instance().code_gc_count } } diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index b6b2d92b6d..a60fcaf836 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -261,7 +261,6 @@ make_counters! { compiled_block_count, compilation_failure, freed_iseq_count, - code_gc_count, exit_from_branch_stub, @@ -391,6 +390,9 @@ fn rb_yjit_gen_stats_dict() -> VALUE { // Live pages hash_aset_usize!(hash, "live_page_count", cb.num_mapped_pages() - freed_page_count); + + // Code GC count + hash_aset_usize!(hash, "code_gc_count", CodegenGlobals::get_code_gc_count()); } // If we're not generating stats, the hash is done -- cgit v1.2.3