aboutsummaryrefslogtreecommitdiffstats
path: root/yjit/src
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-08-10 11:13:21 -0700
committerGitHub <noreply@github.com>2023-08-10 14:13:21 -0400
commit3ad306b4f09665f8555006dd78be38e298f7bd2d (patch)
tree836e660c49d4d604b2715ef7f8c74812037e7d72 /yjit/src
parentcc0fca2729368f5d5628829a329eb05a86728ace (diff)
downloadruby-3ad306b4f09665f8555006dd78be38e298f7bd2d.tar.gz
YJIT: Fallback megamorphic super/yield to dynamic dispatch (#8197)
YJIT: Fallback megamorphic super/yield to dynamic dispatch
Diffstat (limited to 'yjit/src')
-rw-r--r--yjit/src/codegen.rs21
-rw-r--r--yjit/src/stats.rs2
2 files changed, 22 insertions, 1 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index cfa4241c77..b3139253ad 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -7226,6 +7226,12 @@ fn gen_invokeblock_specialized(
return Some(EndBlock);
}
+ // Fallback to dynamic dispatch if this callsite is megamorphic
+ if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_CHAIN_DEPTH {
+ gen_counter_incr(asm, Counter::invokeblock_megamorphic);
+ return None;
+ }
+
// Get call info
let ci = unsafe { get_call_data_ci(cd) };
let argc: i32 = unsafe { vm_ci_argc(ci) }.try_into().unwrap();
@@ -7389,6 +7395,12 @@ fn gen_invokesuper_specialized(
return Some(EndBlock);
}
+ // Fallback to dynamic dispatch if this callsite is megamorphic
+ if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_CHAIN_DEPTH {
+ gen_counter_incr(asm, Counter::invokesuper_megamorphic);
+ return None;
+ }
+
let me = unsafe { rb_vm_frame_method_entry(jit.get_cfp()) };
if me.is_null() {
gen_counter_incr(asm, Counter::invokesuper_no_me);
@@ -7463,7 +7475,14 @@ fn gen_invokesuper_specialized(
let me_as_value = VALUE(me as usize);
asm.cmp(ep_me_opnd, me_as_value.into());
- asm.jne(Target::side_exit(Counter::guard_invokesuper_me_changed));
+ jit_chain_guard(
+ JCC_JNE,
+ jit,
+ asm,
+ ocb,
+ SEND_MAX_CHAIN_DEPTH,
+ Counter::guard_invokesuper_me_changed,
+ );
// gen_send_* currently support the first two branches in vm_caller_setup_arg_block:
// * VM_CALL_ARGS_BLOCKARG
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 007706fee7..66b36a61c5 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -277,11 +277,13 @@ make_counters! {
invokesuper_defined_class_mismatch,
invokesuper_kw_splat,
invokesuper_kwarg,
+ invokesuper_megamorphic,
invokesuper_no_cme,
invokesuper_no_me,
invokesuper_not_iseq_or_cfunc,
invokesuper_refinement,
+ invokeblock_megamorphic,
invokeblock_none,
invokeblock_iseq_arg0_optional,
invokeblock_iseq_arg0_has_kw,