@@ -661,6 +661,9 @@ fn gen_ccall_variadic(
661661) -> lir:: Opnd {
662662 gen_prepare_non_leaf_call ( jit, asm, state) ;
663663
664+ let stack_growth = state. stack_size ( ) ;
665+ gen_stack_overflow_check ( jit, asm, state, stack_growth) ;
666+
664667 gen_push_frame ( asm, args. len ( ) , state, ControlFrame {
665668 recv,
666669 iseq : None ,
@@ -1109,17 +1112,8 @@ fn gen_send_without_block_direct(
11091112 state : & FrameState ,
11101113) -> lir:: Opnd {
11111114 let local_size = unsafe { get_iseq_body_local_table_size ( iseq) } . as_usize ( ) ;
1112- // Stack overflow check: fails if CFP<=SP at any point in the callee.
1113- asm_comment ! ( asm, "stack overflow check" ) ;
11141115 let stack_growth = state. stack_size ( ) + local_size + unsafe { get_iseq_body_stack_max ( iseq) } . as_usize ( ) ;
1115- // vm_push_frame() checks it against a decremented cfp, and CHECK_VM_STACK_OVERFLOW0
1116- // adds to the margin another control frame with `&bounds[1]`.
1117- const { assert ! ( RUBY_SIZEOF_CONTROL_FRAME % SIZEOF_VALUE == 0 , "sizeof(rb_control_frame_t) is a multiple of sizeof(VALUE)" ) ; }
1118- let cfp_growth = 2 * ( RUBY_SIZEOF_CONTROL_FRAME / SIZEOF_VALUE ) ;
1119- let peak_offset = SIZEOF_VALUE * ( stack_growth + cfp_growth) ;
1120- let stack_limit = asm. add ( SP , peak_offset. into ( ) ) ;
1121- asm. cmp ( CFP , stack_limit) ;
1122- asm. jbe ( side_exit ( jit, state, StackOverflow ) ) ;
1116+ gen_stack_overflow_check ( jit, asm, state, stack_growth) ;
11231117
11241118 // Save cfp->pc and cfp->sp for the caller frame
11251119 gen_prepare_call_with_gc ( asm, state, false ) ;
@@ -1713,6 +1707,19 @@ fn gen_push_frame(asm: &mut Assembler, argc: usize, state: &FrameState, frame: C
17131707 asm. mov ( cfp_opnd ( RUBY_OFFSET_CFP_BLOCK_CODE ) , 0 . into ( ) ) ;
17141708}
17151709
1710+ /// Stack overflow check: fails if CFP<=SP at any point in the callee.
1711+ fn gen_stack_overflow_check ( jit : & mut JITState , asm : & mut Assembler , state : & FrameState , stack_growth : usize ) {
1712+ asm_comment ! ( asm, "stack overflow check" ) ;
1713+ // vm_push_frame() checks it against a decremented cfp, and CHECK_VM_STACK_OVERFLOW0
1714+ // adds to the margin another control frame with `&bounds[1]`.
1715+ const { assert ! ( RUBY_SIZEOF_CONTROL_FRAME % SIZEOF_VALUE == 0 , "sizeof(rb_control_frame_t) is a multiple of sizeof(VALUE)" ) ; }
1716+ let cfp_growth = 2 * ( RUBY_SIZEOF_CONTROL_FRAME / SIZEOF_VALUE ) ;
1717+ let peak_offset = ( cfp_growth + stack_growth) * SIZEOF_VALUE ;
1718+ let stack_limit = asm. lea ( Opnd :: mem ( 64 , SP , peak_offset as i32 ) ) ;
1719+ asm. cmp ( CFP , stack_limit) ;
1720+ asm. jbe ( side_exit ( jit, state, StackOverflow ) ) ;
1721+ }
1722+
17161723/// Return an operand we use for the basic block argument at a given index
17171724fn param_opnd ( idx : usize ) -> Opnd {
17181725 // To simplify the implementation, allocate a fixed register or a stack slot for each basic block argument for now.
0 commit comments