Skip to content

Commit ff33ff4

Browse files
committed
Fix env debug assertion failure w/ Ractors+JITs
Previously when using a JIT and Ractors at the same time with debug assertions turned on this could rarely fail with: vm_core.h:1448: Assertion Failed: VM_ENV_FLAGS:FIXNUM_P(flags) When using Ractors, any time the VM lock is acquired, that may join a barrier as another Ractor initiates GC. This could be made to happen reliably by replacing the invalidation with a call to rb_gc(). This assertion failure happens because VM_STACK_ENV_WRITE(ep, 0, (VALUE)env); Is setting VM_ENV_DATA_INDEX_FLAGS to the environment, which is not a valid set of flags (it should be a fixnum). Although we update cfp->ep, rb_execution_context_mark will also mark the PREV_EP, and until the recursive calls to vm_make_env_each all finish the "next" ep may still be pointing to the stack env we've just escaped. I'm not completely sure why we need to store this on the stack - why is setting cfp->ep not enough? I'm also not sure why rb_execution_context_mark needs to mark the prev_ep.
1 parent 5a73339 commit ff33ff4

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

vm.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,13 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
992992
local_size += VM_ENV_DATA_SIZE;
993993
}
994994

995+
// Invalidate JIT code that assumes cfp->ep == vm_base_ptr(cfp).
996+
// This is done before creating the imemo_env because VM_STACK_ENV_WRITE
997+
// below leaves the on-stack ep in a state that is unsafe to GC.
998+
if (VM_FRAME_RUBYFRAME_P(cfp)) {
999+
rb_yjit_invalidate_ep_is_bp(cfp->iseq);
1000+
}
1001+
9951002
/*
9961003
* # local variables on a stack frame (N == local_size)
9971004
* [lvar1, lvar2, ..., lvarN, SPECVAL]
@@ -1035,11 +1042,6 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
10351042
}
10361043
#endif
10371044

1038-
// Invalidate JIT code that assumes cfp->ep == vm_base_ptr(cfp).
1039-
if (env->iseq) {
1040-
rb_yjit_invalidate_ep_is_bp(env->iseq);
1041-
}
1042-
10431045
return (VALUE)env;
10441046
}
10451047

0 commit comments

Comments
 (0)