Skip to content

Commit

Permalink
YJIT: Speculate block arg for c_func_method(&nil) calls
Browse files Browse the repository at this point in the history
A good amount of call sites always pass nil as block argument, but the
nil doesn't show up in the context. Put a runtime guard for those
cases to handle it. Particular relevant for the `ruby-lsp` benchmark in
`yjit-bench`. Up to a 2% speedup across headline benchmarks.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Co-authored-by: Kevin Menard <kevin@nirvdrum.com>
Co-authored-by: Randy Stauner <randy.stauner@shopify.com>
  • Loading branch information
6 people committed Dec 13, 2024
1 parent c0caf1c commit cd696ba
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 18 deletions.
28 changes: 10 additions & 18 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6949,41 +6949,33 @@ fn gen_send_cfunc(
return None;
}

let block_arg_type = if block_arg {
let mut block_arg_type = if block_arg {
Some(asm.ctx.get_opnd_type(StackOpnd(0)))
} else {
None
};

match block_arg_type {
Some(Type::Nil | Type::BlockParamProxy) => {
// We'll handle this later
}
None => {
// Nothing to do
}
_ => {
gen_counter_incr(jit, asm, Counter::send_cfunc_block_arg);
return None;
}
}

match block_arg_type {
Some(Type::Nil) => {
// We have a nil block arg, so let's pop it off the args
// We don't need the actual stack value for these
asm.stack_pop(1);
}
Some(Type::BlockParamProxy) => {
// We don't need the actual stack value
Some(Type::Unknown | Type::UnknownImm) if jit.peek_at_stack(&asm.ctx, 0).nil_p() => {
// The sample blockarg is nil, so speculate that's the case.
asm.cmp(asm.stack_opnd(0), Qnil.into());
asm.jne(Target::side_exit(Counter::guard_send_cfunc_block_not_nil));
block_arg_type = Some(Type::Nil);
asm.stack_pop(1);
}
None => {
// Nothing to do
}
_ => {
assert!(false);
gen_counter_incr(jit, asm, Counter::send_cfunc_block_arg);
return None;
}
}
let block_arg_type = block_arg_type; // drop `mut`

// Pop the empty kw_splat hash
if kw_splat {
Expand Down
1 change: 1 addition & 0 deletions yjit/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ make_counters! {
guard_send_str_aref_not_fixnum,

guard_send_cfunc_bad_splat_vargs,
guard_send_cfunc_block_not_nil,

guard_invokesuper_me_changed,

Expand Down

0 comments on commit cd696ba

Please sign in to comment.