8000 YJIT: Support arity=-2 cfuncs (#10268) · jeremyevans/ruby@802e857 · GitHub
[go: up one dir, main page]

Skip to content

Commit 802e857

Browse files
XrXrmaximecb
andauthored
YJIT: Support arity=-2 cfuncs (ruby#10268)
This type of cfuncs shows up as consume a lot of cycles in profiles of the lobsters benchmark, even though in the stats they don't happen that frequently. Might be a bug in the profiling, but these calls are not too bad to support, so might as well do it. Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
1 parent 97810cb commit 802e857

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

bootstraptest/test_yjit.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4678,3 +4678,19 @@ def test(klass, args)
46784678
46794679
test(KwInit, [Hash.ruby2_keywords_hash({1 => 1})])
46804680
}
4681+
4682+
# arity=-2 cfuncs
4683+
assert_equal '["", "1/2", [0, [:ok, 1]]]', %q{
4684+
def test_cases(file, chain)
4685+
new_chain = chain.allocate # to call initialize directly
4686+
new_chain.send(:initialize, [0], ok: 1)
4687+
4688+
[
4689+
file.join,
4690+
file.join("1", "2"),
4691+
new_chain.to_a,
4692+
]
4693+
end
4694+
4695+
test_cases(File, Enumerator::Chain)
4696+
}

yjit/src/codegen.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6174,9 +6174,9 @@ fn gen_send_cfunc(
61746174
let variable_splat = flags & VM_CALL_ARGS_SPLAT != 0 && cfunc_argc == -1;
61756175
let block_arg = flags & VM_CALL_ARGS_BLOCKARG != 0;
61766176

6177-
// If the function expects a Ruby array of arguments
6178-
if cfunc_argc < 0 && cfunc_argc != -1 {
6179-
gen_counter_incr(asm, Counter::send_cfunc_ruby_array_varg);
6177+
// If it's a splat and the method expects a Ruby array of arguments
6178+
if cfunc_argc == -2 && flags & VM_CALL_ARGS_SPLAT != 0 {
6179+
gen_counter_incr(asm, Counter::send_cfunc_splat_neg2);
61806180
return None;
61816181
}
61826182

@@ -6461,7 +6461,19 @@ fn gen_send_cfunc(
64616461
asm.stack_opnd(argc),
64626462
]
64636463
}
6464-
else {
6464+
// Variadic method taking a Ruby array
6465+
else if cfunc_argc == -2 {
6466+
// Slurp up all the arguments into an array
6467+
let stack_args = asm.lea(asm.ctx.sp_opnd(-argc * SIZEOF_VALUE_I32));
6468+
let args_array = asm.ccall(
6469+
rb_ec_ary_new_from_values as _,
6470+
vec![EC, passed_argc.into(), stack_args]
6471+
);
6472+
6473+
// Example signature:
6474+
// VALUE neg2_method(VALUE self, VALUE argv)
6475+
vec![asm.stack_opnd(argc), args_array]
6476+
} else {
64656477
panic!("unexpected cfunc_args: {}", cfunc_argc)
64666478
};
64676479

yjit/src/stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ make_counters! {
354354
send_refined_method,
355355
send_private_not_fcall,
356356
send_cfunc_kw_splat_non_nil,
357-
send_cfunc_ruby_array_varg,
357+
send_cfunc_splat_neg2,
358358
send_cfunc_argc_mismatch,
359359
send_cfunc_block_arg,
360360
send_cfunc_toomany_args,

0 commit comments

Comments
 (0)
0