summaryrefslogtreecommitdiff
path: root/ruby.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-10-19 17:18:59 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2022-10-19 17:20:48 -0700
commitd9d9005a3a31d0df0b5432eba5d6f2b9bd647cb1 (patch)
treefac1ad347a511fa970a2bf5d0f8eff1122baacbb /ruby.c
parent0d360ee7ff962ef66667a75a912c3980c4f5b217 (diff)
downloadruby-d9d9005a3a31d0df0b5432eba5d6f2b9bd647cb1.tar.gz
MJIT: Stop using the VM barrier for jit_cont
This solves multiple problems. First, RB_VM_LOCK_ENTER/LEAVE is a barrier. We could at least use the _NO_BARRIER variant. Second, this doesn't need to interfere with GC or other GVL users when multiple Ractors are used. This needs to be used in very few places, so the benefit of fine-grained locking would outweigh its small maintenance cost. Third, it fixes a crash for YJIT. Because YJIT is never disabled until a process exits unlike MJIT that finishes earlier, we could call jit_cont_free when EC no longer exists, which crashes RB_VM_LOCK_ENTER.
Diffstat (limited to 'ruby.c')
-rw-r--r--ruby.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/ruby.c b/ruby.c
index 03aeb9b75b..037d031c52 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1613,8 +1613,13 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
#if USE_MJIT
// rb_call_builtin_inits depends on RubyVM::MJIT.enabled?
- if (opt->mjit.on)
+ if (opt->mjit.on) {
mjit_enabled = true;
+ // rb_threadptr_root_fiber_setup for the initial thread is called before rb_yjit_enabled_p()
+ // or mjit_enabled becomes true, meaning jit_cont_new is skipped for the initial root fiber.
+ // Therefore we need to call this again here to set the initial root fiber's jit_cont.
+ rb_jit_cont_init(); // must be after mjit_enabled = true
+ }
#endif
Init_ext(); /* load statically linked extensions before rubygems */
@@ -1624,10 +1629,6 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
// Make sure the saved_ec of the initial thread's root_fiber is scanned by rb_jit_cont_each_ec.
//
- // rb_threadptr_root_fiber_setup for the initial thread is called before rb_yjit_enabled_p()
- // or mjit_enabled becomes true, meaning jit_cont_new is skipped for the root_fiber.
- // Therefore we need to call this again here to set the root_fiber's jit_cont.
- rb_fiber_init_jit_cont(GET_EC()->fiber_ptr);
#if USE_MJIT
// mjit_init is safe only after rb_call_builtin_inits defines RubyVM::MJIT::Compiler
if (opt->mjit.on)
@@ -1922,6 +1923,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
#if USE_YJIT
if (FEATURE_SET_P(opt->features, yjit)) {
rb_yjit_init();
+ // rb_threadptr_root_fiber_setup for the initial thread is called before rb_yjit_enabled_p()
+ // or mjit_enabled becomes true, meaning jit_cont_new is skipped for the initial root fiber.
+ // Therefore we need to call this again here to set the initial root fiber's jit_cont.
+ rb_jit_cont_init(); // must be after rb_yjit_init(), but before parsing options raises an exception.
}
#endif
#if USE_MJIT