YJIT: Distinguish exit and fallback reasons for invokesuper/invokeblock (#8194)

YJIT: Distinguish exit and fallback reasons

for invokesuper/invokeblock
This commit is contained in:
Takashi Kokubun 2023-08-09 12:34:30 -07:00 коммит произвёл GitHub
Родитель 0b8f15575a
Коммит 493acaf4d4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 43 добавлений и 27 удалений

Просмотреть файл

@ -251,9 +251,11 @@ module RubyVM::YJIT
out.puts("***YJIT: Printing YJIT statistics on exit***")
print_counters(stats, out: out, prefix: 'send_', prompt: 'method call fallback reasons: ')
print_counters(stats, out: out, prefix: 'invokeblock_', prompt: 'invokeblock fallback reasons: ')
print_counters(stats, out: out, prefix: 'invokesuper_', prompt: 'invokesuper 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: 'guard_invokeblock_', prompt: 'invokeblock exit reasons: ')
print_counters(stats, out: out, prefix: 'guard_invokesuper_', prompt: 'invokesuper exit reasons: ')
print_counters(stats, out: out, prefix: 'leave_', prompt: 'leave exit reasons: ')
print_counters(stats, out: out, prefix: 'gbpp_', prompt: 'getblockparamproxy exit reasons: ')
print_counters(stats, out: out, prefix: 'getivar_', prompt: 'getinstancevariable exit reasons:')

Просмотреть файл

@ -7248,7 +7248,7 @@ fn gen_invokeblock_specialized(
asm,
ocb,
SEND_MAX_CHAIN_DEPTH,
Counter::invokeblock_tag_changed,
Counter::guard_invokeblock_tag_changed,
);
let comptime_captured = unsafe { ((comptime_handler.0 & !0x3) as *const rb_captured_block).as_ref().unwrap() };
@ -7264,7 +7264,7 @@ fn gen_invokeblock_specialized(
asm,
ocb,
SEND_MAX_CHAIN_DEPTH,
Counter::invokeblock_iseq_block_changed,
Counter::guard_invokeblock_iseq_block_changed,
);
gen_send_iseq(
@ -7307,7 +7307,7 @@ fn gen_invokeblock_specialized(
asm,
ocb,
SEND_MAX_CHAIN_DEPTH,
Counter::invokeblock_tag_changed,
Counter::guard_invokeblock_tag_changed,
);
// The cfunc may not be leaf
@ -7383,6 +7383,7 @@ fn gen_invokesuper_specialized(
let me = unsafe { rb_vm_frame_method_entry(jit.get_cfp()) };
if me.is_null() {
gen_counter_incr(asm, Counter::invokesuper_no_me);
return None;
}
@ -7395,6 +7396,7 @@ fn gen_invokesuper_specialized(
if current_defined_class.builtin_type() == RUBY_T_ICLASS
&& unsafe { RB_TYPE_P((*rbasic_ptr).klass, RUBY_T_MODULE) && FL_TEST_RAW((*rbasic_ptr).klass, VALUE(RMODULE_IS_REFINEMENT.as_usize())) != VALUE(0) }
{
gen_counter_incr(asm, Counter::invokesuper_refinement);
return None;
}
let comptime_superclass =
@ -7409,15 +7411,15 @@ fn gen_invokesuper_specialized(
// Note, not using VM_CALL_ARGS_SIMPLE because sometimes we pass a block.
if ci_flags & VM_CALL_KWARG != 0 {
gen_counter_incr(asm, Counter::send_keywords);
gen_counter_incr(asm, Counter::invokesuper_kwarg);
return None;
}
if ci_flags & VM_CALL_KW_SPLAT != 0 {
gen_counter_incr(asm, Counter::send_kw_splat);
gen_counter_incr(asm, Counter::invokesuper_kw_splat);
return None;
}
if ci_flags & VM_CALL_ARGS_BLOCKARG != 0 {
gen_counter_incr(asm, Counter::send_block_arg);
gen_counter_incr(asm, Counter::invokesuper_blockarg);
return None;
}
@ -7428,13 +7430,14 @@ fn gen_invokesuper_specialized(
// check and side exit.
let comptime_recv = jit.peek_at_stack(&asm.ctx, argc as isize);
if unsafe { rb_obj_is_kind_of(comptime_recv, current_defined_class) } == VALUE(0) {
gen_counter_incr(asm, Counter::invokesuper_defined_class_mismatch);
return None;
}
// Do method lookup
let cme = unsafe { rb_callable_method_entry(comptime_superclass, mid) };
if cme.is_null() {
gen_counter_incr(asm, Counter::invokesuper_no_cme);
return None;
}
@ -7442,6 +7445,7 @@ fn gen_invokesuper_specialized(
let cme_def_type = unsafe { get_cme_def_type(cme) };
if cme_def_type != VM_METHOD_TYPE_ISEQ && cme_def_type != VM_METHOD_TYPE_CFUNC {
// others unimplemented
gen_counter_incr(asm, Counter::invokesuper_not_iseq_or_cfunc);
return None;
}
@ -7455,7 +7459,7 @@ 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::invokesuper_me_changed));
asm.jne(Target::side_exit(Counter::guard_invokesuper_me_changed));
if block.is_none() {
// Guard no block passed
@ -7471,7 +7475,7 @@ fn gen_invokesuper_specialized(
SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL,
);
asm.cmp(ep_specval_opnd, VM_BLOCK_HANDLER_NONE.into());
asm.jne(Target::side_exit(Counter::invokesuper_block));
asm.jne(Target::side_exit(Counter::guard_invokesuper_block_given));
}
// We need to assume that both our current method entry and the super

Просмотреть файл

@ -274,6 +274,26 @@ make_counters! {
send_bmethod_ractor,
send_bmethod_block_arg,
invokesuper_blockarg,
invokesuper_defined_class_mismatch,
invokesuper_kw_splat,
invokesuper_kwarg,
invokesuper_no_cme,
invokesuper_no_me,
invokesuper_not_iseq_or_cfunc,
invokesuper_refinement,
invokeblock_none,
invokeblock_iseq_arg0_optional,
invokeblock_iseq_arg0_has_kw,
invokeblock_iseq_arg0_args_splat,
invokeblock_iseq_arg0_not_array,
invokeblock_iseq_arg0_wrong_len,
invokeblock_ifunc_args_splat,
invokeblock_ifunc_kw_splat,
invokeblock_proc,
invokeblock_symbol,
// Method calls that exit to the interpreter
guard_send_klass_megamorphic,
guard_send_se_cf_overflow,
@ -292,24 +312,14 @@ make_counters! {
guard_send_not_string,
guard_send_mid_mismatch,
guard_invokesuper_me_changed,
guard_invokesuper_block_given,
guard_invokeblock_tag_changed,
guard_invokeblock_iseq_block_changed,
traced_cfunc_return,
invokesuper_me_changed,
invokesuper_block,
invokeblock_none,
invokeblock_iseq_arg0_optional,
invokeblock_iseq_arg0_has_kw,
invokeblock_iseq_arg0_args_splat,
invokeblock_iseq_arg0_not_array,
invokeblock_iseq_arg0_wrong_len,
invokeblock_iseq_block_changed,
invokeblock_tag_changed,
invokeblock_ifunc_args_splat,
invokeblock_ifunc_kw_splat,
invokeblock_proc,
invokeblock_symbol,
leave_se_interrupt,
leave_interp_return,