summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <ruby@bernsteinbear.com>2025-10-22 16:13:57 -0700
committerMax Bernstein <tekknolagi@gmail.com>2025-10-22 17:10:14 -0700
commitc3404d736fa4fe7e330f3fbbeb4103f9206254d0 (patch)
treef17959ed41b9ef58c64ea5ae3f5834a3db174e77
parentfa5481bc063fb54bd2735c6253224349419399e7 (diff)
ZJIT: Use InvokeBuiltin leaf attribute in codegen
-rw-r--r--zjit/src/codegen.rs12
1 files changed, 8 insertions, 4 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index 848249d774..c00bdb474e 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -386,7 +386,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
// Ensure we have enough room fit ec, self, and arguments
// TODO remove this check when we have stack args (we can use Time.new to test it)
Insn::InvokeBuiltin { bf, state, .. } if bf.argc + 2 > (C_ARG_OPNDS.len() as i32) => return Err(*state),
- Insn::InvokeBuiltin { bf, args, state, .. } => gen_invokebuiltin(jit, asm, &function.frame_state(*state), bf, opnds!(args)),
+ Insn::InvokeBuiltin { bf, leaf, args, state, .. } => gen_invokebuiltin(jit, asm, &function.frame_state(*state), bf, *leaf, opnds!(args)),
&Insn::EntryPoint { jit_entry_idx } => no_output!(gen_entry_point(jit, asm, jit_entry_idx)),
Insn::Return { val } => no_output!(gen_return(asm, opnd!(val))),
Insn::FixnumAdd { left, right, state } => gen_fixnum_add(jit, asm, opnd!(left), opnd!(right), &function.frame_state(*state)),
@@ -640,13 +640,17 @@ fn gen_get_constant_path(jit: &JITState, asm: &mut Assembler, ic: *const iseq_in
asm_ccall!(asm, rb_vm_opt_getconstant_path, EC, CFP, Opnd::const_ptr(ic))
}
-fn gen_invokebuiltin(jit: &JITState, asm: &mut Assembler, state: &FrameState, bf: &rb_builtin_function, args: Vec<Opnd>) -> lir::Opnd {
+fn gen_invokebuiltin(jit: &JITState, asm: &mut Assembler, state: &FrameState, bf: &rb_builtin_function, leaf: bool, args: Vec<Opnd>) -> lir::Opnd {
assert!(bf.argc + 2 <= C_ARG_OPNDS.len() as i32,
"gen_invokebuiltin should not be called for builtin function {} with too many arguments: {}",
unsafe { std::ffi::CStr::from_ptr(bf.name).to_str().unwrap() },
bf.argc);
- // Anything can happen inside builtin functions
- gen_prepare_non_leaf_call(jit, asm, state);
+ if leaf {
+ gen_prepare_leaf_call_with_gc(asm, state);
+ } else {
+ // Anything can happen inside builtin functions
+ gen_prepare_non_leaf_call(jit, asm, state);
+ }
let mut cargs = vec![EC];
cargs.extend(args);