diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 3fb04f20d4..df15c27e4b 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -521,6 +521,7 @@ vm_env_write_slowpath(const VALUE *ep, int index, VALUE v) RB_DEBUG_COUNTER_INC(lvar_set_slowpath); } +// YJIT assumes this function never runs GC static inline void vm_env_write(const VALUE *ep, int index, VALUE v) { diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index eb85239998..c150d48666 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2179,16 +2179,11 @@ fn gen_setlocal_generic( let ep_opnd = gen_get_ep(asm, level); // Fallback because of write barrier - if asm.ctx.get_chain_depth() > 0 - { - // Save the PC and SP because it runs GC - jit_prepare_call_with_gc(jit, asm); - - // Pop the value to write from the stack - let value_opnd = asm.stack_opnd(0); - + if asm.ctx.get_chain_depth() > 0 { + // This function should not yield to the GC. // void rb_vm_env_write(const VALUE *ep, int index, VALUE v) let index = -(ep_offset as i64); + let value_opnd = asm.stack_opnd(0); asm.ccall( rb_vm_env_write as *const u8, vec![ @@ -2197,7 +2192,7 @@ fn gen_setlocal_generic( value_opnd, ] ); - asm.stack_pop(1); // Keep it on stack during ccall for GC + asm.stack_pop(1); return Some(KeepCompiling); }