summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-26 18:18:45 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-26 18:32:01 -0700
commitff44e32f929d089fb3a9ce33bc4c7e59f2e0e588 (patch)
treebd5393957dadd0ed9a877487022d92414dc586f8
parentdc270fc6320829c8a5dd8be801702e26806fcf27 (diff)
downloadruby-ff44e32f929d089fb3a9ce33bc4c7e59f2e0e588.tar.gz
RJIT: Store caller sp after stack overflow check
and share some code between ISEQ and C calls.
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb32
1 files changed, 15 insertions, 17 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
index 64a1d1a148..9572daaa87 100644
--- a/lib/ruby_vm/rjit/insn_compiler.rb
+++ b/lib/ruby_vm/rjit/insn_compiler.rb
@@ -4103,15 +4103,6 @@ module RubyVM::RJIT
jit_call_opt_send_shift_stack(ctx, asm, argc, send_shift:)
end
- # Save caller SP and PC before pushing a callee frame for backtrace and side exits
- asm.comment('save SP to caller CFP')
- recv_idx = argc + (flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0) # blockarg is not popped yet
- recv_idx += (block_handler == :captured) ? 0 : 1 # receiver is not on stack when captured->self is used
- # Skip setting this to SP register. This cfp->sp will be copied to SP on leave insn.
- asm.lea(:rax, ctx.sp_opnd(C.VALUE.size * -recv_idx)) # Pop receiver and arguments to prepare for side exits
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], :rax)
- jit_save_pc(jit, asm, comment: 'save PC to caller CFP')
-
frame_type ||= C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
jit_push_frame(
jit, ctx, asm, cme, flags, argc, frame_type, block_handler,
@@ -4218,14 +4209,6 @@ module RubyVM::RJIT
# Check interrupts before SP motion to safely side-exit with the original SP.
jit_check_ints(jit, ctx, asm)
- # Save caller SP and PC before pushing a callee frame for backtrace and side exits
- asm.comment('save SP to caller CFP')
- sp_index = -(1 + argc + (flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0)) # Pop receiver and arguments for side exits. blockarg is not popped yet
- asm.lea(SP, ctx.sp_opnd(C.VALUE.size * sp_index))
- asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP)
- ctx.sp_offset = -sp_index
- jit_save_pc(jit, asm, comment: 'save PC to caller CFP')
-
# Push a callee frame. SP register and ctx are not modified inside this.
jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler)
@@ -4620,6 +4603,21 @@ module RubyVM::RJIT
asm.cmp(CFP, :rax)
asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
+ # Save caller SP and PC before pushing a callee frame for backtrace and side exits
+ asm.comment('save SP to caller CFP')
+ recv_idx = argc + (flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0) # blockarg is not popped yet
+ recv_idx += (block_handler == :captured) ? 0 : 1 # receiver is not on stack when captured->self is used
+ if iseq
+ # Skip setting this to SP register. This cfp->sp will be copied to SP on leave insn.
+ asm.lea(:rax, ctx.sp_opnd(C.VALUE.size * -recv_idx)) # Pop receiver and arguments to prepare for side exits
+ asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], :rax)
+ else
+ asm.lea(SP, ctx.sp_opnd(C.VALUE.size * -recv_idx))
+ asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP)
+ ctx.sp_offset = recv_idx
+ end
+ jit_save_pc(jit, asm, comment: 'save PC to caller CFP')
+
# Pop blockarg after all side exits
if flags & C::VM_CALL_ARGS_BLOCKARG != 0
ctx.stack_pop(1)