Skip to content

Commit 57ee627

Browse files
committed
RJIT: Lazily guard block arg
to simplify the implementation
1 parent 66f8efc commit 57ee627

File tree

1 file changed

+23
-28
lines changed

1 file changed

+23
-28
lines changed

lib/ruby_vm/rjit/insn_compiler.rb

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,14 +1359,9 @@ def send(jit, ctx, asm)
13591359
cd = C.rb_call_data.new(jit.operand(0))
13601360
blockiseq = jit.operand(1)
13611361

1362-
block_handler = jit_caller_setup_arg_block(jit, ctx, asm, cd.ci, blockiseq)
1363-
if block_handler == CantCompile
1364-
return CantCompile
1365-
end
1366-
13671362
# calling->ci
13681363
mid = C.vm_ci_mid(cd.ci)
1369-
calling = build_calling(ci: cd.ci, block_handler:)
1364+
calling = build_calling(ci: cd.ci, block_handler: blockiseq)
13701365

13711366
# vm_sendish
13721367
cme, comptime_recv_klass = jit_search_method(jit, ctx, asm, mid, calling)
@@ -3914,35 +3909,28 @@ def jit_write_iv(asm, comptime_receiver, recv_reg, temp_reg, ivar_index, set_val
39143909
end
39153910
end
39163911

3917-
# vm_caller_setup_arg_block
3912+
# vm_caller_setup_arg_block: Handle VM_CALL_ARGS_BLOCKARG cases.
39183913
# @param jit [RubyVM::RJIT::JITState]
39193914
# @param ctx [RubyVM::RJIT::Context]
39203915
# @param asm [RubyVM::RJIT::Assembler]
3921-
def jit_caller_setup_arg_block(jit, ctx, asm, ci, blockiseq)
3922-
side_exit = side_exit(jit, ctx)
3923-
if C.vm_ci_flag(ci) & C::VM_CALL_ARGS_BLOCKARG != 0
3924-
# TODO: Skip cmp + jne using Context?
3916+
def guard_block_arg(jit, ctx, asm, calling)
3917+
if calling.flags & C::VM_CALL_ARGS_BLOCKARG != 0
3918+
# TODO: Skip cmp + jne using Context
39253919
block_code = jit.peek_at_stack(0)
39263920
block_opnd = ctx.stack_opnd(0) # to be popped after eliminating side exit possibility
39273921
if block_code.nil?
39283922
asm.cmp(block_opnd, Qnil)
3929-
jit_chain_guard(:jne, jit, ctx, asm, counted_exit(side_exit, :send_block_not_nil))
3930-
return C::VM_BLOCK_HANDLER_NONE
3923+
jit_chain_guard(:jne, jit, ctx, asm, counted_exit(side_exit(jit, ctx), :send_block_not_nil))
3924+
calling.block_handler = C::VM_BLOCK_HANDLER_NONE
39313925
elsif C.to_value(block_code) == C.rb_block_param_proxy
39323926
asm.mov(:rax, C.rb_block_param_proxy)
39333927
asm.cmp(block_opnd, :rax)
3934-
jit_chain_guard(:jne, jit, ctx, asm, counted_exit(side_exit, :send_block_not_proxy))
3935-
return C.rb_block_param_proxy
3928+
jit_chain_guard(:jne, jit, ctx, asm, counted_exit(side_exit(jit, ctx), :send_block_not_proxy))
3929+
calling.block_handler = C.rb_block_param_proxy
39363930
else
39373931
asm.incr_counter(:send_block_arg)
39383932
return CantCompile
39393933
end
3940-
elsif blockiseq != 0
3941-
return blockiseq
3942-
else
3943-
# Not implemented yet. Is this even necessary?
3944-
asm.incr_counter(:send_block_setup)
3945-
return CantCompile
39463934
end
39473935
end
39483936

@@ -4089,7 +4077,6 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
40894077
argc = calling.argc
40904078
flags = calling.flags
40914079
send_shift = calling.send_shift
4092-
block_handler = calling.block_handler
40934080

40944081
# When you have keyword arguments, there is an extra object that gets
40954082
# placed on the stack the represents a bitmap of the keywords that were not
@@ -4127,7 +4114,7 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
41274114
end
41284115

41294116
iseq_has_rest = iseq.body.param.flags.has_rest
4130-
if iseq_has_rest && block_handler == :captured
4117+
if iseq_has_rest && calling.block_handler == :captured
41314118
asm.incr_counter(:send_iseq_has_rest_and_captured)
41324119
return CantCompile
41334120
end
@@ -4217,7 +4204,11 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
42174204
end
42184205

42194206
block_arg = flags & C::VM_CALL_ARGS_BLOCKARG != 0
4220-
# jit_caller_setup_arg_block already handled send_block_arg
4207+
4208+
# Guard block_arg_type
4209+
if guard_block_arg(jit, ctx, asm, calling) == CantCompile
4210+
return CantCompile
4211+
end
42214212

42224213
# If we have unfilled optional arguments and keyword arguments then we
42234214
# would need to adjust the arguments location to account for that.
@@ -4299,7 +4290,7 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
42994290
end
43004291

43014292
# Check if we need the arg0 splat handling of vm_callee_setup_block_arg
4302-
arg_setup_block = (block_handler == :captured) # arg_setup_type: arg_setup_block (invokeblock)
4293+
arg_setup_block = (calling.block_handler == :captured) # arg_setup_type: arg_setup_block (invokeblock)
43034294
block_arg0_splat = arg_setup_block && argc == 1 &&
43044295
iseq.body.param.flags.has_lead && !iseq.body.param.flags.ambiguous_param0
43054296
if block_arg0_splat
@@ -4336,7 +4327,7 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
43364327
ctx.stack_pop(1)
43374328
end
43384329

4339-
if block_handler == C::VM_BLOCK_HANDLER_NONE && iseq.body.builtin_attrs & C::BUILTIN_ATTR_LEAF != 0
4330+
if calling.block_handler == C::VM_BLOCK_HANDLER_NONE && iseq.body.builtin_attrs & C::BUILTIN_ATTR_LEAF != 0
43404331
if jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
43414332
return KeepCompiling
43424333
end
@@ -4609,7 +4600,7 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
46094600
# Setup the new frame
46104601
frame_type ||= C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
46114602
jit_push_frame(
4612-
jit, ctx, asm, cme, flags, argc, frame_type, block_handler,
4603+
jit, ctx, asm, cme, flags, argc, frame_type, calling.block_handler,
46134604
iseq: iseq,
46144605
local_size: num_locals,
46154606
stack_max: iseq.body.stack_max,
@@ -4773,7 +4764,11 @@ def jit_call_cfunc(jit, ctx, asm, cme, calling, known_recv_class: nil)
47734764
end
47744765

47754766
block_arg = flags & C::VM_CALL_ARGS_BLOCKARG != 0
4776-
# jit_caller_setup_arg_block already handled send_block_arg
4767+
4768+
# Guard block_arg_type
4769+
if guard_block_arg(jit, ctx, asm, calling) == CantCompile
4770+
return CantCompile
4771+
end
47774772

47784773
if block_arg
47794774
ctx.stack_pop(1)

0 commit comments

Comments
 (0)