Skip to content

Commit f42cf3f

Browse files
committed
RJIT: Migrate invokeblock to jit_call_iseq
1 parent cfea319 commit f42cf3f

File tree

1 file changed

+4
-272
lines changed

1 file changed

+4
-272
lines changed

lib/ruby_vm/rjit/insn_compiler.rb

Lines changed: 4 additions & 272 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,15 +1559,7 @@ def invokeblock(jit, ctx, asm)
15591559
block_changed_exit = counted_exit(side_exit, :invokeblock_iseq_block_changed)
15601560
jit_chain_guard(:jne, jit, ctx, asm, block_changed_exit)
15611561

1562-
opt_pc = jit_callee_setup_block_arg(jit, ctx, asm, calling, comptime_iseq, arg_setup_type: :arg_setup_block)
1563-
if opt_pc == CantCompile
1564-
return CantCompile
1565-
end
1566-
1567-
jit_call_iseq_setup_normal(
1568-
jit, ctx, asm, nil, calling, comptime_iseq, opt_pc,
1569-
frame_type: C::VM_FRAME_MAGIC_BLOCK,
1570-
)
1562+
jit_call_iseq(jit, ctx, asm, nil, calling, comptime_iseq, frame_type: C::VM_FRAME_MAGIC_BLOCK)
15711563
elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
15721564
# We aren't handling CALLER_SETUP_ARG and CALLER_REMOVE_EMPTY_KW_SPLAT yet.
15731565
if calling.flags & C::VM_CALL_ARGS_SPLAT != 0
@@ -4309,68 +4301,6 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
43094301
EndBlock
43104302
end
43114303

4312-
# vm_call_iseq_setup_normal (vm_call_iseq_setup_2 -> vm_call_iseq_setup_normal)
4313-
# @param jit [RubyVM::RJIT::JITState]
4314-
# @param ctx [RubyVM::RJIT::Context]
4315-
# @param asm [RubyVM::RJIT::Assembler]
4316-
def jit_call_iseq_setup_normal(jit, ctx, asm, cme, calling, iseq, opt_pc, frame_type:, prev_ep: nil)
4317-
argc = calling.argc
4318-
flags = calling.flags
4319-
send_shift = calling.send_shift
4320-
block_handler = calling.block_handler
4321-
4322-
# Push splat args, which was skipped in jit_caller_setup_arg.
4323-
if flags & C::VM_CALL_ARGS_SPLAT != 0
4324-
lead_num = iseq.body.param.lead_num
4325-
opt_num = iseq.body.param.opt_num
4326-
4327-
array_length = jit.peek_at_stack(flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0)&.length || 0 # blockarg is not popped yet
4328-
if opt_num == 0 && lead_num != array_length + argc - 1
4329-
asm.incr_counter(:send_args_splat_arity_error)
4330-
return CantCompile
4331-
end
4332-
4333-
remaining_opt = (opt_num + lead_num) - (array_length + argc - 1)
4334-
if opt_num > 0
4335-
# We are going to jump to the correct offset based on how many optional params are remaining.
4336-
opt_pc = iseq.body.param.opt_table[opt_num - remaining_opt]
4337-
end
4338-
4339-
# We are going to assume that the splat fills all the remaining arguments.
4340-
# In the generated code we test if this is true and if not side exit.
4341-
argc = argc - 1 + array_length
4342-
jit_caller_setup_arg_splat(jit, ctx, asm, array_length)
4343-
end
4344-
4345-
# We will not have side exits from here. Adjust the stack, which was skipped in jit_call_opt_send.
4346-
if flags & C::VM_CALL_OPT_SEND != 0
4347-
jit_call_opt_send_shift_stack(ctx, asm, argc, send_shift:)
4348-
end
4349-
4350-
if block_handler == C::VM_BLOCK_HANDLER_NONE && iseq.body.builtin_attrs & C::BUILTIN_ATTR_LEAF != 0
4351-
if jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
4352-
return KeepCompiling
4353-
end
4354-
end
4355-
4356-
frame_type ||= C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
4357-
jit_push_frame(
4358-
jit, ctx, asm, cme, flags, argc, frame_type, block_handler,
4359-
iseq: iseq,
4360-
local_size: iseq.body.local_table_size - iseq.body.param.size,
4361-
stack_max: iseq.body.stack_max,
4362-
prev_ep:,
4363-
push_opts: true,
4364-
)
4365-
4366-
# Jump to a stub for the callee ISEQ
4367-
callee_ctx = Context.new
4368-
pc = (iseq.body.iseq_encoded + opt_pc).to_i
4369-
jit_direct_jump(iseq, pc, callee_ctx, asm)
4370-
4371-
EndBlock
4372-
end
4373-
43744304
def jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
43754305
builtin_func = builtin_function(iseq)
43764306
if builtin_func.nil?
@@ -4728,7 +4658,7 @@ def jit_call_opt_send(jit, ctx, asm, cme, calling, known_recv_class)
47284658
asm.incr_counter(:send_optimized_send_send)
47294659
return CantCompile
47304660
end
4731-
# Lazily handle stack shift in jit_call_iseq_setup_normal
4661+
# Lazily handle stack shift in jit_call_opt_send_shift_stack
47324662
calling.send_shift += 1
47334663

47344664
jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, C::VM_CALL_FCALL)
@@ -4904,7 +4834,7 @@ def jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, flags)
49044834
# @param jit [RubyVM::RJIT::JITState]
49054835
# @param ctx [RubyVM::RJIT::Context]
49064836
# @param asm [RubyVM::RJIT::Assembler]
4907-
def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, iseq: nil, local_size: 0, stack_max: 0, prev_ep: nil, push_opts: false)
4837+
def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, iseq: nil, local_size: 0, stack_max: 0, prev_ep: nil)
49084838
# CHECK_VM_STACK_OVERFLOW0: next_cfp <= sp + (local_size + stack_max)
49094839
asm.comment('stack overflow check')
49104840
asm.lea(:rax, ctx.sp_opnd(C.rb_control_frame_t.size + C.VALUE.size * (local_size + stack_max)))
@@ -4932,12 +4862,6 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
49324862
ctx.stack_pop(1)
49334863
end
49344864

4935-
if iseq && push_opts
4936-
# This was not handled in jit_callee_setup_arg
4937-
opts_filled = argc - iseq.body.param.lead_num # TODO: kwarg
4938-
opts_missing = iseq.body.param.opt_num - opts_filled
4939-
local_size += opts_missing
4940-
end
49414865
local_size.times do |i|
49424866
asm.comment('set local variables') if i == 0
49434867
local_index = ctx.sp_offset + i
@@ -5041,198 +4965,6 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
50414965
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], cfp_reg)
50424966
end
50434967

5044-
# vm_callee_setup_arg (ISEQ only): Set up args and return opt_pc (or CantCompile)
5045-
# @param jit [RubyVM::RJIT::JITState]
5046-
# @param ctx [RubyVM::RJIT::Context]
5047-
# @param asm [RubyVM::RJIT::Assembler]
5048-
def jit_callee_setup_arg(jit, ctx, asm, flags, argc, iseq)
5049-
if flags & C::VM_CALL_KW_SPLAT == 0
5050-
if C.rb_simple_iseq_p(iseq)
5051-
if jit_caller_setup_arg(jit, ctx, asm, flags, splat: true) == CantCompile
5052-
return CantCompile
5053-
end
5054-
if jit_caller_remove_empty_kw_splat(jit, ctx, asm, flags) == CantCompile
5055-
return CantCompile
5056-
end
5057-
5058-
if argc != iseq.body.param.lead_num
5059-
# argument_arity_error
5060-
return CantCompile
5061-
end
5062-
5063-
return 0
5064-
elsif C.rb_iseq_only_optparam_p(iseq)
5065-
if jit_caller_setup_arg(jit, ctx, asm, flags, splat: true) == CantCompile
5066-
return CantCompile
5067-
end
5068-
if jit_caller_remove_empty_kw_splat(jit, ctx, asm, flags) == CantCompile
5069-
return CantCompile
5070-
end
5071-
5072-
lead_num = iseq.body.param.lead_num
5073-
opt_num = iseq.body.param.opt_num
5074-
opt = argc - lead_num
5075-
5076-
if opt < 0 || opt > opt_num
5077-
asm.incr_counter(:send_arity)
5078-
return CantCompile
5079-
end
5080-
5081-
# Qnil push is handled in jit_push_frame
5082-
5083-
return iseq.body.param.opt_table[opt]
5084-
elsif C.rb_iseq_only_kwparam_p(iseq) && (flags & C::VM_CALL_ARGS_SPLAT) == 0
5085-
asm.incr_counter(:send_iseq_kwparam)
5086-
return CantCompile
5087-
end
5088-
end
5089-
5090-
return jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq)
5091-
end
5092-
5093-
# vm_callee_setup_block_arg (ISEQ only): Set up args and return opt_pc (or CantCompile)
5094-
# @param jit [RubyVM::RJIT::JITState]
5095-
# @param ctx [RubyVM::RJIT::Context]
5096-
# @param asm [RubyVM::RJIT::Assembler]
5097-
def jit_callee_setup_block_arg(jit, ctx, asm, calling, iseq, arg_setup_type:)
5098-
if C.rb_simple_iseq_p(iseq)
5099-
if jit_caller_setup_arg(jit, ctx, asm, calling.flags, splat: true) == CantCompile
5100-
return CantCompile
5101-
end
5102-
5103-
if arg_setup_type == :arg_setup_block &&
5104-
calling.argc == 1 &&
5105-
iseq.body.param.flags.has_lead &&
5106-
!iseq.body.param.flags.ambiguous_param0
5107-
asm.incr_counter(:invokeblock_iseq_arg0_splat)
5108-
return CantCompile
5109-
end
5110-
5111-
if calling.argc != iseq.body.param.lead_num
5112-
if arg_setup_type == :arg_setup_block
5113-
if calling.argc < iseq.body.param.lead_num
5114-
(iseq.body.param.lead_num - calling.argc).times do
5115-
asm.mov(ctx.stack_push, Qnil)
5116-
end
5117-
calling.argc = iseq.body.param.lead_num # fill rest parameters
5118-
elsif calling.argc > iseq.body.param.lead_num
5119-
ctx.stack_pop(calling.argc - iseq.body.param.lead_num)
5120-
calling.argc = iseq.body.param.lead_num # simply truncate arguments
5121-
end
5122-
else # not used yet
5123-
asm.incr_counter(:invokeblock_iseq_arity)
5124-
return CantCompile
5125-
end
5126-
end
5127-
5128-
return 0
5129-
else
5130-
return jit_setup_parameters_complex(jit, ctx, asm, calling.flags, calling.argc, iseq, arg_setup_type:)
5131-
end
5132-
end
5133-
5134-
# setup_parameters_complex (ISEQ only)
5135-
# @param jit [RubyVM::RJIT::JITState]
5136-
# @param ctx [RubyVM::RJIT::Context]
5137-
# @param asm [RubyVM::RJIT::Assembler]
5138-
def jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq, arg_setup_type: nil)
5139-
min_argc = iseq.body.param.lead_num + iseq.body.param.post_num
5140-
max_argc = (iseq.body.param.flags.has_rest == false) ? min_argc + iseq.body.param.opt_num : C::UNLIMITED_ARGUMENTS
5141-
kw_flag = flags & (C::VM_CALL_KWARG | C::VM_CALL_KW_SPLAT | C::VM_CALL_KW_SPLAT_MUT)
5142-
opt_pc = 0
5143-
keyword_hash = nil
5144-
flag_keyword_hash = nil
5145-
given_argc = argc
5146-
5147-
if kw_flag & C::VM_CALL_KWARG != 0
5148-
asm.incr_counter(:send_iseq_complex_kwarg)
5149-
return CantCompile
5150-
end
5151-
5152-
if flags & C::VM_CALL_ARGS_SPLAT != 0 && flags & C::VM_CALL_KW_SPLAT != 0
5153-
asm.incr_counter(:send_iseq_complex_kw_splat)
5154-
return CantCompile
5155-
elsif flags & C::VM_CALL_ARGS_SPLAT != 0
5156-
# Lazily handle splat in jit_call_iseq_setup_normal
5157-
else
5158-
if argc > 0 && kw_flag & C::VM_CALL_KW_SPLAT != 0
5159-
asm.incr_counter(:send_iseq_complex_kw_splat)
5160-
return CantCompile
5161-
end
5162-
end
5163-
5164-
if flag_keyword_hash && C.RB_TYPE_P(flag_keyword_hash, C::RUBY_T_HASH)
5165-
raise NotImplementedError # unreachable
5166-
end
5167-
5168-
if kw_flag != 0 && iseq.body.param.flags.accepts_no_kwarg
5169-
asm.incr_counter(:send_iseq_complex_accepts_no_kwarg)
5170-
return CantCompile
5171-
end
5172-
5173-
case arg_setup_type
5174-
when :arg_setup_block
5175-
asm.incr_counter(:send_iseq_complex_arg_setup_block)
5176-
return CantCompile
5177-
end
5178-
5179-
if given_argc < min_argc
5180-
asm.incr_counter(:send_iseq_complex_arity)
5181-
return CantCompile
5182-
end
5183-
5184-
if given_argc > max_argc && max_argc != C::UNLIMITED_ARGUMENTS
5185-
asm.incr_counter(:send_iseq_complex_arity)
5186-
return CantCompile
5187-
end
5188-
5189-
if iseq.body.param.flags.has_lead
5190-
asm.incr_counter(:send_iseq_complex_has_lead)
5191-
return CantCompile
5192-
end
5193-
5194-
if iseq.body.param.flags.has_rest || iseq.body.param.flags.has_post
5195-
asm.incr_counter(iseq.body.param.flags.has_rest ? :send_iseq_complex_has_rest : :send_iseq_complex_has_post)
5196-
return CantCompile
5197-
end
5198-
5199-
if iseq.body.param.flags.has_post
5200-
asm.incr_counter(:send_iseq_complex_has_post)
5201-
return CantCompile
5202-
end
5203-
5204-
if iseq.body.param.flags.has_opt
5205-
asm.incr_counter(:send_iseq_complex_has_opt)
5206-
return CantCompile
5207-
end
5208-
5209-
if iseq.body.param.flags.has_rest
5210-
asm.incr_counter(:send_iseq_complex_has_rest)
5211-
return CantCompile
5212-
end
5213-
5214-
if iseq.body.param.flags.has_kw
5215-
asm.incr_counter(:send_iseq_complex_has_kw)
5216-
return CantCompile
5217-
elsif iseq.body.param.flags.has_kwrest
5218-
asm.incr_counter(:send_iseq_complex_has_kwrest)
5219-
return CantCompile
5220-
elsif !keyword_hash.nil? && keyword_hash.size > 0 # && arg_setup_type == :arg_setup_method
5221-
raise NotImplementedError # unreachable
5222-
end
5223-
5224-
if iseq.body.param.flags.has_block
5225-
if iseq.body.local_iseq.to_i == iseq.to_i
5226-
# Do nothing
5227-
else
5228-
asm.incr_counter(:send_iseq_complex_has_block)
5229-
return CantCompile
5230-
end
5231-
end
5232-
5233-
return opt_pc
5234-
end
5235-
52364968
# CALLER_SETUP_ARG: Return CantCompile if not supported
52374969
# @param jit [RubyVM::RJIT::JITState]
52384970
# @param ctx [RubyVM::RJIT::Context]
@@ -5243,7 +4975,7 @@ def jit_caller_setup_arg(jit, ctx, asm, flags, splat: false)
52434975
return CantCompile
52444976
elsif flags & C::VM_CALL_ARGS_SPLAT != 0
52454977
if splat
5246-
# Lazily handle splat in jit_call_iseq_setup_normal, jit_call_cfunc_with_frame
4978+
# Lazily handle splat in jit_call_cfunc_with_frame
52474979
else
52484980
# splat is not supported in this path
52494981
asm.incr_counter(:send_args_splat)

0 commit comments

Comments
 (0)