summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2024-03-13 09:22:35 -0700
committerGitHub <noreply@github.com>2024-03-13 12:22:35 -0400
commit207b00239297ce8284fec6ace4cac2cdf733d6a7 (patch)
tree99160b40b50b9cf9d8297155e98813ec7ef1b041
parentc843afbf6f841bfb18afef3e7c87e48591fd4689 (diff)
YJIT: Fallback cfunc varg splat for ruby2_keywords (#10226)
-rw-r--r--yjit/src/codegen.rs13
-rw-r--r--yjit/src/stats.rs3
2 files changed, 12 insertions, 4 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index fee7c30fd5..292de96f70 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -6247,7 +6247,14 @@ fn gen_send_cfunc(
// Guard for variable length splat call before any modifications to the stack
if variable_splat {
- let splat_array = asm.stack_opnd(i32::from(kw_splat) + i32::from(block_arg));
+ let splat_array_idx = i32::from(kw_splat) + i32::from(block_arg);
+ let comptime_splat_array = jit.peek_at_stack(&asm.ctx, splat_array_idx as isize);
+ if unsafe { rb_yjit_ruby2_keywords_splat_p(comptime_splat_array) } != 0 {
+ gen_counter_incr(asm, Counter::send_cfunc_splat_varg_ruby2_keywords);
+ return None;
+ }
+
+ let splat_array = asm.stack_opnd(splat_array_idx);
guard_object_is_array(asm, splat_array, splat_array.into(), Counter::guard_send_splat_not_array);
asm_comment!(asm, "guard variable length splat call servicable");
@@ -6627,7 +6634,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) {
guard_object_is_not_ruby2_keyword_hash(
asm,
last_array_value,
- Counter::guard_send_splatarray_last_ruby_2_keywords,
+ Counter::guard_send_splatarray_last_ruby2_keywords,
);
asm_comment!(asm, "Push arguments from array");
@@ -7051,7 +7058,7 @@ fn gen_send_iseq(
asm_comment!(asm, "guard no ruby2_keywords hash in splat");
let bad_splat = asm.ccall(rb_yjit_ruby2_keywords_splat_p as _, vec![asm.stack_opnd(splat_pos)]);
asm.cmp(bad_splat, 0.into());
- asm.jnz(Target::side_exit(Counter::guard_send_splatarray_last_ruby_2_keywords));
+ asm.jnz(Target::side_exit(Counter::guard_send_splatarray_last_ruby2_keywords));
}
match block_arg_type {
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 882730e405..5fa2bfedfb 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -360,6 +360,7 @@ make_counters! {
send_cfunc_toomany_args,
send_cfunc_tracing,
send_cfunc_splat_with_kw,
+ send_cfunc_splat_varg_ruby2_keywords,
send_attrset_kwargs,
send_attrset_block_arg,
send_iseq_tailcall,
@@ -431,7 +432,7 @@ make_counters! {
guard_send_se_cf_overflow,
guard_send_se_protected_check_failed,
guard_send_splatarray_length_not_equal,
- guard_send_splatarray_last_ruby_2_keywords,
+ guard_send_splatarray_last_ruby2_keywords,
guard_send_splat_not_array,
guard_send_send_name_chain,
guard_send_iseq_has_rest_and_splat_too_few,