summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yjit.rb4
-rw-r--r--yjit/bindgen/src/main.rs2
-rw-r--r--yjit/src/codegen.rs9
-rw-r--r--yjit/src/cruby_bindings.inc.rs14
-rw-r--r--yjit/src/stats.rs5
5 files changed, 34 insertions, 0 deletions
diff --git a/yjit.rb b/yjit.rb
index db7e33cbf2..bb0b8a983a 100644
--- a/yjit.rb
+++ b/yjit.rb
@@ -279,6 +279,10 @@ module RubyVM::YJIT
end
out.puts "num_getivar_megamorphic: " + format_number(13, stats[:num_getivar_megamorphic])
out.puts "num_setivar_megamorphic: " + format_number(13, stats[:num_setivar_megamorphic])
+ out.puts "num_throw: " + format_number(13, stats[:num_throw])
+ out.puts "num_throw_break: " + format_number_pct(13, stats[:num_throw_break], stats[:num_throw])
+ out.puts "num_throw_retry: " + format_number_pct(13, stats[:num_throw_retry], stats[:num_throw])
+ out.puts "num_throw_return: " + format_number_pct(13, stats[:num_throw_return], stats[:num_throw])
out.puts "iseq_stack_too_large: " + format_number(13, stats[:iseq_stack_too_large])
out.puts "iseq_too_long: " + format_number(13, stats[:iseq_too_long])
diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs
index 29f39a7cb4..8a187bf674 100644
--- a/yjit/bindgen/src/main.rs
+++ b/yjit/bindgen/src/main.rs
@@ -290,6 +290,8 @@ fn main() {
.allowlist_var("VM_ENV_DATA_SIZE")
.allowlist_function("rb_iseq_path")
.allowlist_type("rb_builtin_attr")
+ .allowlist_type("ruby_tag_type")
+ .allowlist_type("ruby_vm_throw_flags")
// From yjit.c
.allowlist_function("rb_iseq_(get|set)_yjit_payload")
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 374fdddf3d..4776ff8ce8 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -3875,6 +3875,15 @@ fn gen_throw(
let throwobj = asm.stack_pop(1);
let throwobj = asm.load(throwobj);
+ // Gather some statistics about throw
+ gen_counter_incr(asm, Counter::num_throw);
+ match (throw_state & VM_THROW_STATE_MASK as u64) as u32 {
+ RUBY_TAG_BREAK => gen_counter_incr(asm, Counter::num_throw_break),
+ RUBY_TAG_RETRY => gen_counter_incr(asm, Counter::num_throw_retry),
+ RUBY_TAG_RETURN => gen_counter_incr(asm, Counter::num_throw_return),
+ _ => {},
+ }
+
// THROW_DATA_NEW allocates. Save SP for GC and PC for allocation tracing as
// well as handling the catch table. However, not using jit_prepare_routine_call
// since we don't need a patch point for this implementation.
diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs
index 5f0601f988..91326444ce 100644
--- a/yjit/src/cruby_bindings.inc.rs
+++ b/yjit/src/cruby_bindings.inc.rs
@@ -621,6 +621,20 @@ pub struct rb_id_table {
_unused: [u8; 0],
}
pub type rb_num_t = ::std::os::raw::c_ulong;
+pub const RUBY_TAG_NONE: ruby_tag_type = 0;
+pub const RUBY_TAG_RETURN: ruby_tag_type = 1;
+pub const RUBY_TAG_BREAK: ruby_tag_type = 2;
+pub const RUBY_TAG_NEXT: ruby_tag_type = 3;
+pub const RUBY_TAG_RETRY: ruby_tag_type = 4;
+pub const RUBY_TAG_REDO: ruby_tag_type = 5;
+pub const RUBY_TAG_RAISE: ruby_tag_type = 6;
+pub const RUBY_TAG_THROW: ruby_tag_type = 7;
+pub const RUBY_TAG_FATAL: ruby_tag_type = 8;
+pub const RUBY_TAG_MASK: ruby_tag_type = 15;
+pub type ruby_tag_type = u32;
+pub const VM_THROW_NO_ESCAPE_FLAG: ruby_vm_throw_flags = 32768;
+pub const VM_THROW_STATE_MASK: ruby_vm_throw_flags = 255;
+pub type ruby_vm_throw_flags = u32;
#[repr(C)]
pub struct iseq_inline_constant_cache_entry {
pub flags: VALUE,
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 620a038e32..035564c40d 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -425,6 +425,11 @@ make_counters! {
num_getivar_megamorphic,
num_setivar_megamorphic,
+ num_throw,
+ num_throw_break,
+ num_throw_retry,
+ num_throw_return,
+
iseq_stack_too_large,
iseq_too_long,