RJIT: Break up RJIT send_iseq_complex exit reasons

This commit is contained in:
Takashi Kokubun 2023-03-19 21:18:09 -07:00
parent 59b86da82c
commit 70ea58bd5b
4 changed files with 122 additions and 7 deletions

View File

@ -4705,7 +4705,7 @@ module RubyVM::RJIT
return 0
else
return jit_setup_parameters_complex(jit, ctx, asm, calling.flags, calling.argc, iseq)
return jit_setup_parameters_complex(jit, ctx, asm, calling.flags, calling.argc, iseq, arg_setup_type:)
end
end
@ -4713,10 +4713,99 @@ module RubyVM::RJIT
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
def jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq)
# We don't support setup_parameters_complex
asm.incr_counter(:send_iseq_complex)
return CantCompile
def jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq, arg_setup_type: nil)
min_argc = iseq.body.param.lead_num + iseq.body.param.post_num
max_argc = (iseq.body.param.flags.has_rest == false) ? min_argc + iseq.body.param.opt_num : C::UNLIMITED_ARGUMENTS
kw_flag = flags & (C::VM_CALL_KWARG | C::VM_CALL_KW_SPLAT | C::VM_CALL_KW_SPLAT_MUT)
opt_pc = 0
keyword_hash = nil
flag_keyword_hash = nil
given_argc = argc
if kw_flag & C::VM_CALL_KWARG != 0
asm.incr_counter(:send_iseq_complex_kwarg)
return CantCompile
end
if flags & C::VM_CALL_ARGS_SPLAT != 0 && flags & C::VM_CALL_KW_SPLAT != 0
asm.incr_counter(:send_iseq_complex_kw_splat)
return CantCompile
elsif flags & C::VM_CALL_ARGS_SPLAT != 0
asm.incr_counter(:send_iseq_complex_splat)
return CantCompile
else
if argc > 0 && kw_flag & C::VM_CALL_KW_SPLAT != 0
asm.incr_counter(:send_iseq_complex_kw_splat)
return CantCompile
end
end
if flag_keyword_hash && C.RB_TYPE_P(flag_keyword_hash, C::RUBY_T_HASH)
raise NotImplementedError # unreachable
end
if kw_flag != 0 && iseq.body.param.flags.accepts_no_kwarg
asm.incr_counter(:send_iseq_complex_accepts_no_kwarg)
return CantCompile
end
case arg_setup_type
when :arg_setup_block
asm.incr_counter(:send_iseq_complex_arg_setup_block)
return CantCompile
end
if given_argc < min_argc
asm.incr_counter(:send_iseq_complex_arity)
return CantCompile
end
if given_argc > max_argc && max_argc != C::UNLIMITED_ARGUMENTS
asm.incr_counter(:send_iseq_complex_arity)
return CantCompile
end
if iseq.body.param.flags.has_lead
asm.incr_counter(:send_iseq_complex_has_lead)
return CantCompile
end
if iseq.body.param.flags.has_rest || iseq.body.param.flags.has_post
asm.incr_counter(:send_iseq_complex_has_rest_or_post)
return CantCompile
end
if iseq.body.param.flags.has_post
asm.incr_counter(:send_iseq_complex_has_rest_or_post)
return CantCompile
end
if iseq.body.param.flags.has_opt
asm.incr_counter(:send_iseq_complex_has_opt)
return CantCompile
end
if iseq.body.param.flags.has_rest
asm.incr_counter(:send_iseq_complex_has_rest_or_post)
return CantCompile
end
if iseq.body.param.flags.has_kw
asm.incr_counter(:send_iseq_complex_has_kw)
return CantCompile
elsif iseq.body.param.flags.has_kwrest
asm.incr_counter(:send_iseq_complex_has_kwrest)
return CantCompile
elsif !keyword_hash.nil? && keyword_hash.size > 0 # && arg_setup_type == :arg_setup_method
raise NotImplementedError # unreachable
end
if iseq.body.param.flags.has_block
asm.incr_counter(:send_iseq_complex_has_block)
return CantCompile
end
return opt_pc
end
# CALLER_SETUP_ARG: Return CantCompile if not supported

View File

@ -51,7 +51,18 @@ RJIT_RUNTIME_COUNTERS(
send_block_not_proxy,
send_iseq_kwparam,
send_iseq_complex,
send_iseq_complex_kwarg,
send_iseq_complex_kw_splat,
send_iseq_complex_splat,
send_iseq_complex_accepts_no_kwarg,
send_iseq_complex_arg_setup_block,
send_iseq_complex_arity,
send_iseq_complex_has_lead,
send_iseq_complex_has_rest_or_post,
send_iseq_complex_has_opt,
send_iseq_complex_has_kw,
send_iseq_complex_has_kwrest,
send_iseq_complex_has_block,
send_cfunc_variadic,
send_cfunc_too_many_args,

View File

@ -349,6 +349,7 @@ module RubyVM::RJIT # :nodoc: all
### RJIT bindgen begin ###
C::UNLIMITED_ARGUMENTS = Primitive.cexpr! %q{ LONG2NUM(UNLIMITED_ARGUMENTS) }
C::VM_ENV_DATA_INDEX_ME_CREF = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_ME_CREF) }
C::VM_ENV_DATA_INDEX_SPECVAL = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_SPECVAL) }
C::ARRAY_REDEFINED_OP_FLAG = Primitive.cexpr! %q{ SIZET2NUM(ARRAY_REDEFINED_OP_FLAG) }
@ -419,6 +420,7 @@ module RubyVM::RJIT # :nodoc: all
C::VM_CALL_FCALL = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_FCALL) }
C::VM_CALL_KWARG = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KWARG) }
C::VM_CALL_KW_SPLAT = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT) }
C::VM_CALL_KW_SPLAT_MUT = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT_MUT) }
C::VM_CALL_KW_SPLAT_bit = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_KW_SPLAT_bit) }
C::VM_CALL_OPT_SEND = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_OPT_SEND) }
C::VM_CALL_TAILCALL = Primitive.cexpr! %q{ SIZET2NUM(VM_CALL_TAILCALL) }
@ -1294,7 +1296,18 @@ module RubyVM::RJIT # :nodoc: all
send_block_not_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_nil)")],
send_block_not_proxy: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_block_not_proxy)")],
send_iseq_kwparam: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_kwparam)")],
send_iseq_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex)")],
send_iseq_complex_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_kwarg)")],
send_iseq_complex_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_kw_splat)")],
send_iseq_complex_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_splat)")],
send_iseq_complex_accepts_no_kwarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_accepts_no_kwarg)")],
send_iseq_complex_arg_setup_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_arg_setup_block)")],
send_iseq_complex_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_arity)")],
send_iseq_complex_has_lead: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_lead)")],
send_iseq_complex_has_rest_or_post: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_rest_or_post)")],
send_iseq_complex_has_opt: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_opt)")],
send_iseq_complex_has_kw: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_kw)")],
send_iseq_complex_has_kwrest: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_kwrest)")],
send_iseq_complex_has_block: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_iseq_complex_has_block)")],
send_cfunc_variadic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_variadic)")],
send_cfunc_too_many_args: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_too_many_args)")],
send_cfunc_ruby_array_varg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_cfunc_ruby_array_varg)")],

View File

@ -377,6 +377,7 @@ generator = BindingGenerator.new(
src_path: src_path,
consts: {
LONG: %w[
UNLIMITED_ARGUMENTS
VM_ENV_DATA_INDEX_ME_CREF
VM_ENV_DATA_INDEX_SPECVAL
],
@ -447,6 +448,7 @@ generator = BindingGenerator.new(
VM_CALL_FCALL
VM_CALL_KWARG
VM_CALL_KW_SPLAT
VM_CALL_KW_SPLAT_MUT
VM_CALL_KW_SPLAT_bit
VM_CALL_OPT_SEND
VM_CALL_TAILCALL