diff options
author | Takashi Kokubun <[email protected]> | 2023-08-02 07:19:39 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2023-08-02 10:19:39 -0400 |
commit | 81c198b5cfced7f9e8205e726bf686763370ce18 (patch) | |
tree | 9c4565bb102bf2791fd2f50939af0dc00171d1f1 | |
parent | 452debba22cfae0ed61042afb21f2bf86135c1dc (diff) |
YJIT: Distinguish exit and fallback reasons for send (#8159)
Notes
Notes:
Merged-By: maximecb <[email protected]>
-rw-r--r-- | yjit.rb | 3 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 42 | ||||
-rw-r--r-- | yjit/src/stats.rs | 36 |
3 files changed, 42 insertions, 39 deletions
@@ -250,7 +250,8 @@ module RubyVM::YJIT out.puts("***YJIT: Printing YJIT statistics on exit***") - print_counters(stats, out: out, prefix: 'send_', prompt: 'method call exit reasons: ') + print_counters(stats, out: out, prefix: 'send_', prompt: 'method call fallback reasons: ') + print_counters(stats, out: out, prefix: 'guard_send_', prompt: 'method call exit reasons: ') print_counters(stats, out: out, prefix: 'invokeblock_', prompt: 'invokeblock exit reasons: ') print_counters(stats, out: out, prefix: 'invokesuper_', prompt: 'invokesuper exit reasons: ') print_counters(stats, out: out, prefix: 'leave_', prompt: 'leave exit reasons: ') diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index daf898c3cd..6b4c67d31e 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2574,7 +2574,7 @@ fn guard_two_fixnums( asm: &mut Assembler, ocb: &mut OutlinedCb, ) { - let counter = Counter::send_not_fixnums; + let counter = Counter::guard_send_not_fixnums; // Get stack operands without popping them let arg1 = asm.stack_opnd(0); @@ -2779,7 +2779,7 @@ fn gen_equality_specialized( a_opnd.into(), comptime_a, SEND_MAX_DEPTH, - Counter::send_not_string, + Counter::guard_send_not_string, ); let equal = asm.new_label("equal"); @@ -2806,7 +2806,7 @@ fn gen_equality_specialized( b_opnd.into(), comptime_b, SEND_MAX_DEPTH, - Counter::send_not_string, + Counter::guard_send_not_string, ); } @@ -3994,7 +3994,7 @@ fn jit_protected_callee_ancestry_guard( ], ); asm.test(val, val); - asm.jz(Target::side_exit(Counter::send_se_protected_check_failed)) + asm.jz(Target::side_exit(Counter::guard_send_se_protected_check_failed)) } // Codegen for rb_obj_not(). @@ -4109,7 +4109,7 @@ fn jit_rb_kernel_is_a( asm.comment("Kernel#is_a?"); asm.cmp(asm.stack_opnd(0), sample_rhs.into()); - asm.jne(Target::side_exit(Counter::send_is_a_class_mismatch)); + asm.jne(Target::side_exit(Counter::guard_send_is_a_class_mismatch)); asm.stack_pop(2); @@ -4168,7 +4168,7 @@ fn jit_rb_kernel_instance_of( asm.comment("Kernel#instance_of?"); asm.cmp(asm.stack_opnd(0), sample_rhs.into()); - asm.jne(Target::side_exit(Counter::send_instance_of_class_mismatch)); + asm.jne(Target::side_exit(Counter::guard_send_instance_of_class_mismatch)); asm.stack_pop(2); @@ -4544,7 +4544,7 @@ fn jit_rb_str_concat( } // Guard that the concat argument is a string - guard_object_is_string(asm, asm.stack_opnd(0), StackOpnd(0), Counter::send_not_string); + guard_object_is_string(asm, asm.stack_opnd(0), StackOpnd(0), Counter::guard_send_not_string); // Guard buffers from GC since rb_str_buf_append may allocate. During the VM lock on GC, // other Ractors may trigger global invalidation, so we need ctx.clear_local_types(). @@ -4727,7 +4727,7 @@ fn jit_obj_respond_to( // This is necessary because we have no guarantee that sym_opnd is a constant asm.comment("guard known mid"); asm.cmp(sym_opnd, mid_sym.into()); - asm.jne(Target::side_exit(Counter::send_mid_mismatch)); + asm.jne(Target::side_exit(Counter::guard_send_mid_mismatch)); jit_putobject(asm, result); @@ -5070,7 +5070,7 @@ fn gen_send_cfunc( } // Check for interrupts - gen_check_ints(asm, Counter::send_interrupted); + gen_check_ints(asm, Counter::guard_send_interrupted); // Stack overflow check // #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin) @@ -5078,7 +5078,7 @@ fn gen_send_cfunc( asm.comment("stack overflow check"); let stack_limit = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE * 4 + 2 * RUBY_SIZEOF_CONTROL_FRAME) as isize)); asm.cmp(CFP, stack_limit); - asm.jbe(Target::side_exit(Counter::send_se_cf_overflow)); + asm.jbe(Target::side_exit(Counter::guard_send_se_cf_overflow)); // Number of args which will be passed through to the callee // This is adjusted by the kwargs being combined into a hash. @@ -5339,7 +5339,7 @@ fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) { asm.comment("Side exit if length is less than required"); asm.cmp(array_len_opnd, num_args.into()); - asm.jl(Target::side_exit(Counter::send_iseq_has_rest_and_splat_not_equal)); + asm.jl(Target::side_exit(Counter::guard_send_iseq_has_rest_and_splat_not_equal)); asm.comment("Push arguments from array"); @@ -5380,7 +5380,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { asm, array_reg, array_opnd.into(), - Counter::send_splat_not_array, + Counter::guard_send_splat_not_array, ); asm.comment("Get array length for embedded or heap"); @@ -5409,7 +5409,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { asm.comment("Side exit if length doesn't not equal remaining args"); asm.cmp(array_len_opnd, required_args.into()); - asm.jne(Target::side_exit(Counter::send_splatarray_length_not_equal)); + asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal)); asm.comment("Check last argument is not ruby2keyword hash"); @@ -5423,7 +5423,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { guard_object_is_not_ruby2_keyword_hash( asm, last_array_value, - Counter::send_splatarray_last_ruby_2_keywords, + Counter::guard_send_splatarray_last_ruby_2_keywords, ); asm.comment("Push arguments from array"); @@ -5720,7 +5720,7 @@ fn gen_send_iseq( asm.comment("Side exit if length doesn't not equal compile time length"); let array_len_opnd = get_array_len(asm, asm.stack_opnd(if block_arg { 1 } else { 0 })); asm.cmp(array_len_opnd, array_length.into()); - asm.jne(Target::side_exit(Counter::send_splatarray_length_not_equal)); + asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal)); } Some(array_length) @@ -5834,7 +5834,7 @@ fn gen_send_iseq( SIZEOF_VALUE_I32 * (num_locals + stack_max) + 2 * (RUBY_SIZEOF_CONTROL_FRAME as i32); let stack_limit = asm.lea(asm.ctx.sp_opnd(locals_offs as isize)); asm.cmp(CFP, stack_limit); - asm.jbe(Target::side_exit(Counter::send_se_cf_overflow)); + asm.jbe(Target::side_exit(Counter::guard_send_se_cf_overflow)); // push_splat_args does stack manipulation so we can no longer side exit if let Some(array_length) = splat_array_length { @@ -6626,7 +6626,7 @@ fn gen_send_general( recv_opnd, comptime_recv, SEND_MAX_DEPTH, - Counter::send_klass_megamorphic, + Counter::guard_send_klass_megamorphic, ); // Do method lookup @@ -6834,12 +6834,12 @@ fn gen_send_general( if compile_time_name.string_p() { ( unsafe { rb_cString }, - Counter::send_send_chain_not_string, + Counter::guard_send_send_chain_not_string, ) } else { ( unsafe { rb_cSymbol }, - Counter::send_send_chain_not_sym, + Counter::guard_send_send_chain_not_sym, ) } }; @@ -6871,7 +6871,7 @@ fn gen_send_general( asm, ocb, SEND_MAX_CHAIN_DEPTH, - Counter::send_send_chain, + Counter::guard_send_send_chain, ); // We have changed the argc, flags, mid, and cme, so we need to re-enter the match @@ -8575,7 +8575,7 @@ mod tests { fn test_gen_check_ints() { let (_jit, _ctx, mut asm, _cb, _ocb) = setup_codegen(); asm.set_side_exit_context(0 as _, 0); - gen_check_ints(&mut asm, Counter::send_interrupted); + gen_check_ints(&mut asm, Counter::guard_send_interrupted); } #[test] diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index b1773df359..686516cb9b 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -204,8 +204,8 @@ pub(crate) use ptr_to_counter; make_counters! { yjit_insns_count, + // Method calls that fallback to dynamic dispatch send_keywords, - send_klass_megamorphic, send_kw_splat, send_args_splat_super, send_iseq_zsuper, @@ -245,11 +245,6 @@ make_counters! { send_iseq_too_many_kwargs, send_not_implemented_method, send_getter_arity, - send_se_cf_overflow, - send_se_protected_check_failed, - send_splatarray_length_not_equal, - send_splatarray_last_ruby_2_keywords, - send_splat_not_array, send_args_splat_non_iseq, send_args_splat_ivar, send_args_splat_attrset, @@ -268,10 +263,7 @@ make_counters! { send_send_null_mid, send_send_null_cme, send_send_nested, - send_send_chain, send_send_chain_string, - send_send_chain_not_string, - send_send_chain_not_sym, send_send_chain_not_string_or_sym, send_send_getter, send_send_builtin, @@ -279,17 +271,27 @@ make_counters! { send_iseq_has_rest_and_send, send_iseq_has_rest_and_kw_supplied, send_iseq_has_rest_opt_and_block, - send_iseq_has_rest_and_splat_not_equal, - send_is_a_class_mismatch, - send_instance_of_class_mismatch, - send_interrupted, - send_not_fixnums, - send_not_string, - send_mid_mismatch, - send_bmethod_ractor, send_bmethod_block_arg, + // Method calls that exit to the interpreter + guard_send_klass_megamorphic, + guard_send_se_cf_overflow, + guard_send_se_protected_check_failed, + guard_send_splatarray_length_not_equal, + guard_send_splatarray_last_ruby_2_keywords, + guard_send_splat_not_array, + guard_send_send_chain, + guard_send_send_chain_not_string, + guard_send_send_chain_not_sym, + guard_send_iseq_has_rest_and_splat_not_equal, + guard_send_is_a_class_mismatch, + guard_send_instance_of_class_mismatch, + guard_send_interrupted, + guard_send_not_fixnums, + guard_send_not_string, + guard_send_mid_mismatch, + traced_cfunc_return, invokesuper_me_changed, |