diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2023-09-29 22:29:24 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2023-10-05 15:53:05 -0400 |
commit | 41a6e4bdf9738e2cf1ea356422a429efeeb5a8f0 (patch) | |
tree | 1e046d638aca5e1b94e27c4b72391cab821e1cdc /yjit/src/backend/ir.rs | |
parent | a5cc6341c0688c346f70098652b2375c03df40aa (diff) | |
download | ruby-41a6e4bdf9738e2cf1ea356422a429efeeb5a8f0.tar.gz |
YJIT: Avoid writing return value to memory in `leave`
Previously, at the end of `leave` we did
`*caller_cfp->sp = return_value`, like the interpreter.
With future changes that leaves the SP field uninitialized for C frames,
this will become problematic. For cases like returning from
`rb_funcall()`, the return value was written above the stack and
never read anyway (callers use the copy in the return register).
Leave the return value in a register at the end of `leave` and have the
code at `cfp->jit_return` decide what to do with it. This avoids the
unnecessary memory write mentioned above. For JIT-to-JIT returns, it goes
through `asm.stack_push()` and benefits from register allocation for
stack temporaries.
Mostly flat on benchmarks, with maybe some marginal speed improvements.
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Diffstat (limited to 'yjit/src/backend/ir.rs')
-rw-r--r-- | yjit/src/backend/ir.rs | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index 10e463885b..67b5547bf9 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -22,6 +22,7 @@ pub const SP: Opnd = _SP; pub const C_ARG_OPNDS: [Opnd; 6] = _C_ARG_OPNDS; pub const C_RET_OPND: Opnd = _C_RET_OPND; +pub use crate::backend::current::{Reg, C_RET_REG}; // Memory operand base #[derive(Clone, Copy, PartialEq, Eq, Debug)] @@ -955,6 +956,7 @@ pub struct SideExitContext { pub stack_size: u8, pub sp_offset: i8, pub reg_temps: RegTemps, + pub is_return_landing: bool, } impl SideExitContext { @@ -965,6 +967,7 @@ impl SideExitContext { stack_size: ctx.get_stack_size(), sp_offset: ctx.get_sp_offset(), reg_temps: ctx.get_reg_temps(), + is_return_landing: ctx.is_return_landing(), }; if cfg!(debug_assertions) { // Assert that we're not losing any mandatory metadata @@ -979,6 +982,9 @@ impl SideExitContext { ctx.set_stack_size(self.stack_size); ctx.set_sp_offset(self.sp_offset); ctx.set_reg_temps(self.reg_temps); + if self.is_return_landing { + ctx.set_as_return_landing(); + } ctx } } |