From 3ad306b4f09665f8555006dd78be38e298f7bd2d Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 10 Aug 2023 11:13:21 -0700 Subject: [PATCH] YJIT: Fallback megamorphic super/yield to dynamic dispatch (#8197) YJIT: Fallback megamorphic super/yield to dynamic dispatch --- yjit/src/codegen.rs | 21 ++++++++++++++++++++- yjit/src/stats.rs | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) 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,