Skip to content

Commit 7c91db9

Browse files
authored
ZJIT: Check arg limit before pushing SendWithoutBLockDirect insn (ruby#15854)
This reduces some processing and makes the HIR more accurate.
1 parent 2daed3c commit 7c91db9

File tree

3 files changed

+15
-29
lines changed

3 files changed

+15
-29
lines changed

zjit/src/codegen.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
401401
&Insn::Send { cd, blockiseq, state, reason, .. } => gen_send(jit, asm, cd, blockiseq, &function.frame_state(state), reason),
402402
&Insn::SendForward { cd, blockiseq, state, reason, .. } => gen_send_forward(jit, asm, cd, blockiseq, &function.frame_state(state), reason),
403403
&Insn::SendWithoutBlock { cd, state, reason, .. } => gen_send_without_block(jit, asm, cd, &function.frame_state(state), reason),
404-
// Give up SendWithoutBlockDirect for 6+ args since asm.ccall() doesn't support it.
405-
Insn::SendWithoutBlockDirect { cd, state, args, .. } if args.len() + 1 > C_ARG_OPNDS.len() => // +1 for self
406-
gen_send_without_block(jit, asm, *cd, &function.frame_state(*state), SendFallbackReason::TooManyArgsForLir),
407404
Insn::SendWithoutBlockDirect { cme, iseq, recv, args, state, .. } => gen_send_without_block_direct(cb, jit, asm, *cme, *iseq, opnd!(recv), opnds!(args), &function.frame_state(*state)),
408405
&Insn::InvokeSuper { cd, blockiseq, state, reason, .. } => gen_invokesuper(jit, asm, cd, blockiseq, &function.frame_state(state), reason),
409406
&Insn::InvokeBlock { cd, state, reason, .. } => gen_invokeblock(jit, asm, cd, &function.frame_state(state), reason),

zjit/src/hir.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,12 @@ fn can_direct_send(function: &mut Function, block: BlockId, iseq: *const rb_iseq
16621662
return false;
16631663
}
16641664

1665+
// asm.ccall() doesn't support 6+ args
1666+
if args.len() + 1 > C_ARG_OPNDS.len() { // +1 for self
1667+
function.set_dynamic_send_reason(send_insn, TooManyArgsForLir);
1668+
return false;
1669+
}
1670+
16651671
// Because we exclude e.g. post parameters above, they are also excluded from the sum below.
16661672
let lead_num = params.lead_num;
16671673
let opt_num = params.opt_num;
@@ -2708,16 +2714,9 @@ impl Function {
27082714
let (send_state, processed_args) = if !kwarg.is_null() {
27092715
match self.reorder_keyword_arguments(&args, kwarg, iseq) {
27102716
Ok(reordered) => {
2711-
// Only use reordered state if args fit in C registers.
2712-
// Fallback to interpreter needs original order for kwarg handling.
2713-
// NOTE: This needs to match with the condition in codegen.rs.
2714-
if reordered.len() + 1 <= C_ARG_OPNDS.len() {
2715-
let new_state = self.frame_state(state).with_reordered_args(&reordered);
2716-
let snapshot = self.push_insn(block, Insn::Snapshot { state: new_state });
2717-
(snapshot, reordered)
2718-
} else {
2719-
(state, reordered)
2720-
}
2717+
let new_state = self.frame_state(state).with_reordered_args(&reordered);
2718+
let snapshot = self.push_insn(block, Insn::Snapshot { state: new_state });
2719+
(snapshot, reordered)
27212720
}
27222721
Err(reason) => {
27232722
self.set_dynamic_send_reason(insn_id, reason);
@@ -2768,16 +2767,9 @@ impl Function {
27682767
let (send_state, processed_args) = if !kwarg.is_null() {
27692768
match self.reorder_keyword_arguments(&args, kwarg, iseq) {
27702769
Ok(reordered) => {
2771-
// Only use reordered state if args fit in C registers.
2772-
// Fallback to interpreter needs original order for kwarg handling.
2773-
// NOTE: This needs to match with the condition in codegen.rs.
2774-
if reordered.len() + 1 <= C_ARG_OPNDS.len() {
2775-
let new_state = self.frame_state(state).with_reordered_args(&reordered);
2776-
let snapshot = self.push_insn(block, Insn::Snapshot { state: new_state });
2777-
(snapshot, reordered)
2778-
} else {
2779-
(state, reordered)
2780-
}
2770+
let new_state = self.frame_state(state).with_reordered_args(&reordered);
2771+
let snapshot = self.push_insn(block, Insn::Snapshot { state: new_state });
2772+
(snapshot, reordered)
27812773
}
27822774
Err(reason) => {
27832775
self.set_dynamic_send_reason(insn_id, reason);

zjit/src/hir/tests.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,11 @@ mod snapshot_tests {
152152
v23:Fixnum[7] = Const Value(7)
153153
v25:Fixnum[8] = Const Value(8)
154154
v26:Any = Snapshot FrameState { pc: 0x1008, stack: [v6, v11, v13, v15, v17, v19, v21, v23, v25], locals: [] }
155-
PatchPoint MethodRedefined(Object@0x1010, foo@0x1018, cme:0x1020)
156-
PatchPoint NoSingletonClass(Object@0x1010)
157-
v34:HeapObject[class_exact*:Object@VALUE(0x1010)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x1010)]
158-
v35:BasicObject = SendWithoutBlockDirect v34, :foo (0x1048), v11, v13, v19, v21, v17, v15, v23, v25
159-
v28:Any = Snapshot FrameState { pc: 0x1050, stack: [v35], locals: [] }
155+
v27:BasicObject = SendWithoutBlock v6, :foo, v11, v13, v15, v17, v19, v21, v23, v25 # SendFallbackReason: Too many arguments for LIR
156+
v28:Any = Snapshot FrameState { pc: 0x1010, stack: [v27], locals: [] }
160157
PatchPoint NoTracePoint
161158
CheckInterrupts
162-
Return v35
159+
Return v27
163160
");
164161
}
165162
}

0 commit comments

Comments
 (0)