Skip to content

Commit 28db75a

Browse files
committed
RJIT: Check stackoverflow earlier for ISEQ
1 parent 249fe18 commit 28db75a

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

lib/ruby_vm/rjit/insn_compiler.rb

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4245,6 +4245,15 @@ def jit_call_iseq(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: n
42454245
end
42464246
end
42474247

4248+
# Stack overflow check
4249+
# Note that vm_push_frame checks it against a decremented cfp, hence the multiply by 2.
4250+
# #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
4251+
asm.comment('stack overflow check')
4252+
locals_offs = C.VALUE.size * (num_locals + iseq.body.stack_max) + 2 * C.rb_control_frame_t.size
4253+
asm.lea(:rax, ctx.sp_opnd(locals_offs))
4254+
asm.cmp(CFP, :rax)
4255+
asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
4256+
42484257
# Check if we need the arg0 splat handling of vm_callee_setup_block_arg
42494258
arg_setup_block = (block_handler == :captured) # arg_setup_type: arg_setup_block (invokeblock)
42504259
block_arg0_splat = arg_setup_block && argc == 1 &&
@@ -4438,6 +4447,14 @@ def jit_call_cfunc_with_frame(jit, ctx, asm, cme, flags, argc, block_handler, kn
44384447
# Check interrupts before SP motion to safely side-exit with the original SP.
44394448
jit_check_ints(jit, ctx, asm)
44404449

4450+
# Stack overflow check
4451+
# #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
4452+
# REG_CFP <= REG_SP + 4 * SIZEOF_VALUE + sizeof(rb_control_frame_t)
4453+
asm.comment('stack overflow check')
4454+
asm.lea(:rax, ctx.sp_opnd(C.VALUE.size * 4 + 2 * C.rb_control_frame_t.size))
4455+
asm.cmp(CFP, :rax)
4456+
asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
4457+
44414458
# Push a callee frame. SP register and ctx are not modified inside this.
44424459
jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler)
44434460

@@ -4835,12 +4852,6 @@ def jit_call_symbol(jit, ctx, asm, cme, calling, known_recv_class, flags)
48354852
# @param ctx [RubyVM::RJIT::Context]
48364853
# @param asm [RubyVM::RJIT::Assembler]
48374854
def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, iseq: nil, local_size: 0, stack_max: 0, prev_ep: nil)
4838-
# CHECK_VM_STACK_OVERFLOW0: next_cfp <= sp + (local_size + stack_max)
4839-
asm.comment('stack overflow check')
4840-
asm.lea(:rax, ctx.sp_opnd(C.rb_control_frame_t.size + C.VALUE.size * (local_size + stack_max)))
4841-
asm.cmp(CFP, :rax)
4842-
asm.jbe(counted_exit(side_exit(jit, ctx), :send_stackoverflow))
4843-
48444855
# Save caller SP and PC before pushing a callee frame for backtrace and side exits
48454856
asm.comment('save SP to caller CFP')
48464857
recv_idx = argc + (flags & C::VM_CALL_ARGS_BLOCKARG != 0 ? 1 : 0) # blockarg is not popped yet

0 commit comments

Comments
 (0)