@@ -5216,13 +5216,12 @@ struct ControlFrame {
5216
5216
// * Provided sp should point to the new frame's sp, immediately following locals and the environment
5217
5217
// * At entry, CFP points to the caller (not callee) frame
5218
5218
// * At exit, ec->cfp is updated to the pushed CFP
5219
- // * CFP and SP registers are updated only if set_sp_cfp is set
5219
+ // * SP register is updated only if frame.iseq is set
5220
5220
// * Stack overflow is not checked (should be done by the caller)
5221
5221
// * Interrupts are not checked (should be done by the caller)
5222
5222
fn gen_push_frame (
5223
5223
jit : & mut JITState ,
5224
5224
asm : & mut Assembler ,
5225
- set_sp_cfp : bool , // if true CFP and SP will be switched to the callee
5226
5225
frame : ControlFrame ,
5227
5226
) {
5228
5227
let sp = frame. sp ;
@@ -5314,7 +5313,7 @@ fn gen_push_frame(
5314
5313
asm. mov ( cfp_opnd ( RUBY_OFFSET_CFP_SELF ) , frame. recv ) ;
5315
5314
asm. mov ( cfp_opnd ( RUBY_OFFSET_CFP_BLOCK_CODE ) , 0 . into ( ) ) ;
5316
5315
5317
- if set_sp_cfp {
5316
+ if frame . iseq . is_some ( ) {
5318
5317
// Spill stack temps to let the callee use them (must be done before changing the SP register)
5319
5318
asm. spill_temps ( ) ;
5320
5319
@@ -5324,16 +5323,6 @@ fn gen_push_frame(
5324
5323
}
5325
5324
let ep = asm. sub ( sp, SIZEOF_VALUE . into ( ) ) ;
5326
5325
asm. mov ( cfp_opnd ( RUBY_OFFSET_CFP_EP ) , ep) ;
5327
-
5328
- let new_cfp = asm. lea ( cfp_opnd ( 0 ) ) ;
5329
- if set_sp_cfp {
5330
- asm_comment ! ( asm, "switch to new CFP" ) ;
5331
- asm. mov ( CFP , new_cfp) ;
5332
- asm. store ( Opnd :: mem ( 64 , EC , RUBY_OFFSET_EC_CFP ) , CFP ) ;
5333
- } else {
5334
- asm_comment ! ( asm, "set ec->cfp" ) ;
5335
- asm. store ( Opnd :: mem ( 64 , EC , RUBY_OFFSET_EC_CFP ) , new_cfp) ;
5336
- }
5337
5326
}
5338
5327
5339
5328
fn gen_send_cfunc (
@@ -5561,7 +5550,7 @@ fn gen_send_cfunc(
5561
5550
frame_type |= VM_FRAME_FLAG_CFRAME_KW
5562
5551
}
5563
5552
5564
- gen_push_frame ( jit, asm, false , ControlFrame {
5553
+ gen_push_frame ( jit, asm, ControlFrame {
5565
5554
frame_type,
5566
5555
specval,
5567
5556
cme,
@@ -5575,6 +5564,10 @@ fn gen_send_cfunc(
5575
5564
iseq : None ,
5576
5565
} ) ;
5577
5566
5567
+ asm_comment ! ( asm, "set ec->cfp" ) ;
5568
+ let new_cfp = asm. lea ( Opnd :: mem ( 64 , CFP , -( RUBY_SIZEOF_CONTROL_FRAME as i32 ) ) ) ;
5569
+ asm. store ( Opnd :: mem ( 64 , EC , RUBY_OFFSET_EC_CFP ) , new_cfp) ;
5570
+
5578
5571
if !kw_arg. is_null ( ) {
5579
5572
// Build a hash from all kwargs passed
5580
5573
asm_comment ! ( asm, "build_kwhash" ) ;
@@ -6659,7 +6652,7 @@ fn gen_send_iseq(
6659
6652
} ;
6660
6653
6661
6654
// Setup the new frame
6662
- gen_push_frame ( jit, asm, true , ControlFrame {
6655
+ gen_push_frame ( jit, asm, ControlFrame {
6663
6656
frame_type,
6664
6657
specval,
6665
6658
cme,
@@ -6721,6 +6714,12 @@ fn gen_send_iseq(
6721
6714
BranchGenFn :: JITReturn ,
6722
6715
) ;
6723
6716
6717
+ // ec->cfp is updated after cfp->jit_return for rb_profile_frames() safety
6718
+ asm_comment ! ( asm, "switch to new CFP" ) ;
6719
+ let new_cfp = asm. sub ( CFP , RUBY_SIZEOF_CONTROL_FRAME . into ( ) ) ;
6720
+ asm. mov ( CFP , new_cfp) ;
6721
+ asm. store ( Opnd :: mem ( 64 , EC , RUBY_OFFSET_EC_CFP ) , CFP ) ;
6722
+
6724
6723
// Directly jump to the entry point of the callee
6725
6724
gen_direct_jump (
6726
6725
jit,
0 commit comments