summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-08-09 10:16:15 -0700
committerGitHub <noreply@github.com>2023-08-09 10:16:15 -0700
commitd3efce69eaabf1ff81bcdf3631350a87ac0dda28 (patch)
tree5332b436af42af8a7a34808b6b92c794cf41b607 /yjit
parentc9b30f9d76ec7c726a703a7f8aad95b5998e7d6c (diff)
YJIT: Count throw instructions for each tag (#8188)
* YJIT: Count throw instructions for each tag * Show % of each throw type
Notes
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
Diffstat (limited to 'yjit')
-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
4 files changed, 30 insertions, 0 deletions
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,