Skip to content

Commit bf4d608

Browse files
committed
Skip GC relocation of stale block_code on C frames with JITFrame
When CFP_JIT_RETURN is true for a C frame (iseq is NULL in JITFrame), block_code in the CFP is stale and must not be passed to rb_gc_location during GC compaction. Only relocate iseq and block_code for ISEQ frames with JITFrame.
1 parent 00c9a4e commit bf4d608

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

vm.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3671,11 +3671,16 @@ rb_execution_context_update(rb_execution_context_t *ec)
36713671
const VALUE *ep = cfp->ep;
36723672
cfp->self = rb_gc_location(cfp->self);
36733673
if (rb_zjit_enabled_p && CFP_JIT_RETURN(cfp)) {
3674-
rb_zjit_jit_return_set_iseq(cfp->jit_return, (rb_iseq_t *)rb_gc_location((VALUE)rb_zjit_cfp_iseq(cfp)));
3675-
// block_code may have been written by the JIT caller (gen_block_handler_specval)
3676-
// for passing blocks. It must be relocated even when jit_return is set, because
3677-
// Proc creation (block_setup) copies it from the CFP's captured block.
3678-
cfp->block_code = (void *)rb_gc_location((VALUE)cfp->block_code);
3674+
const rb_iseq_t *iseq = rb_zjit_jit_return_iseq(cfp->jit_return);
3675+
if (iseq) {
3676+
// ISEQ frame with JITFrame: relocate iseq in JITFrame and block_code in CFP
3677+
rb_zjit_jit_return_set_iseq(cfp->jit_return, (rb_iseq_t *)rb_gc_location((VALUE)iseq));
3678+
// block_code may have been written by the JIT caller (gen_block_handler_specval)
3679+
// for passing blocks. It must be relocated even when jit_return is set, because
3680+
// Proc creation (block_setup) copies it from the CFP's captured block.
3681+
cfp->block_code = (void *)rb_gc_location((VALUE)cfp->block_code);
3682+
}
3683+
// C frame with JITFrame: iseq is NULL, block_code is stale — skip relocation
36793684
}
36803685
else {
36813686
cfp->iseq = (rb_iseq_t *)rb_gc_location((VALUE)cfp->iseq);

0 commit comments

Comments
 (0)