summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-19 21:18:09 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-19 23:58:14 -0700
commit70ea58bd5ba42b26ff39f51079af0efa422ac036 (patch)
tree3e975252e1f894cd81057f5271e7c84e69a51569
parent59b86da82c7e175b1a479c82bffe32d6fe394ecb (diff)
downloadruby-70ea58bd5ba42b26ff39f51079af0efa422ac036.tar.gz
RJIT: Break up RJIT send_iseq_complex exit reasons
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb99
-rw-r--r--rjit_c.h13
-rw-r--r--rjit_c.rb15
-rwxr-xr-xtool/rjit/bindgen.rb2
4 files changed, 122 insertions, 7 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
index 013f961829..80d09376d3 100644
--- a/lib/ruby_vm/rjit/insn_compiler.rb
+++ b/lib/ruby_vm/rjit/insn_compiler.rb
@@ -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
diff --git a/rjit_c.h b/rjit_c.h
index 9a7f2ba542..384b517480 100644
--- a/rjit_c.h
+++ b/rjit_c.h
@@ -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,
diff --git a/rjit_c.rb b/rjit_c.rb
index c50911c55a..d87dbb8aab 100644
--- a/rjit_c.rb
+++ b/rjit_c.rb
@@ -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)")],
diff --git a/tool/rjit/bindgen.rb b/tool/rjit/bindgen.rb
index cd8502a2a7..66d45af361 100755
--- a/tool/rjit/bindgen.rb
+++ b/tool/rjit/bindgen.rb
@@ -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