diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-08-10 11:13:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-10 14:13:21 -0400 |
commit | 3ad306b4f09665f8555006dd78be38e298f7bd2d (patch) | |
tree | 836e660c49d4d604b2715ef7f8c74812037e7d72 /yjit | |
parent | cc0fca2729368f5d5628829a329eb05a86728ace (diff) |
YJIT: Fallback megamorphic super/yield to dynamic dispatch (#8197)
YJIT: Fallback megamorphic super/yield
to dynamic dispatch
Notes
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/codegen.rs | 21 | ||||
-rw-r--r-- | yjit/src/stats.rs | 2 |
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, |