@@ -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