mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
[JIT] Only call JIT single ractor mode invalidation once per process
Previously, JIT single-ractor mode invalidation happened on every `Ractor.new` call. This invalidation takes the VM lock + VM barrier so slows down these calls. We only need to invalidate compiled code that makes these single-ractor assumptions on the transition from single-ractor to multi-ractor mode. The JITs never make single-ractor assumptions when multi-ractor mode has been enabled. If a process in multi-ractor mode forks, the forked process is set back to single-ractor mode. The JITs can therefore make single-ractor assumptions in this new process, and the invalidation can occur again when the first non-main Ractor is created in that process.
This commit is contained in:
1 parent
70874cc592
commit
f688f1cb2c
5 files changed
+15
-12
Notes:
git
2026-08-05 16:52:57 +00:00
No files matched your search
@@ -415,6 +415,9 @@ cancel_single_ractor_mode(void)
|
||||
RUBY_DEBUG_LOG("enable multi-ractor mode");
|
||||
|
||||
ruby_single_main_ractor = NULL;
|
||||
rb_yjit_invalidate_single_ractor();
|
||||
rb_zjit_invalidate_single_ractor();
|
||||
|
||||
rb_funcall(rb_cRactor, rb_intern("_activated"), 0);
|
||||
}
|
||||
|
||||
@@ -601,8 +604,6 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL
|
||||
r->verbose = cr->verbose;
|
||||
r->debug = cr->debug;
|
||||
|
||||
rb_yjit_before_ractor_spawn();
|
||||
rb_zjit_before_ractor_spawn();
|
||||
rb_thread_create_ractor(r, args, block);
|
||||
|
||||
RB_GC_GUARD(rv);
|
||||
|
||||
@@ -43,7 +43,7 @@ void rb_yjit_constant_state_changed(ID id);
|
||||
void rb_yjit_iseq_mark(void *payload);
|
||||
void rb_yjit_iseq_update_references(const rb_iseq_t *iseq);
|
||||
void rb_yjit_iseq_free(const rb_iseq_t *iseq);
|
||||
void rb_yjit_before_ractor_spawn(void);
|
||||
void rb_yjit_invalidate_single_ractor(void);
|
||||
void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
|
||||
void rb_yjit_tracing_invalidate_all(void);
|
||||
void rb_yjit_show_usage(int help, int highlight, unsigned int width, int columns);
|
||||
@@ -71,7 +71,7 @@ static inline void rb_yjit_constant_state_changed(ID id) {}
|
||||
static inline void rb_yjit_iseq_mark(void *payload) {}
|
||||
static inline void rb_yjit_iseq_update_references(const rb_iseq_t *iseq) {}
|
||||
static inline void rb_yjit_iseq_free(const rb_iseq_t *iseq) {}
|
||||
static inline void rb_yjit_before_ractor_spawn(void) {}
|
||||
static inline void rb_yjit_invalidate_single_ractor(void) {}
|
||||
static inline void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
|
||||
static inline void rb_yjit_tracing_invalidate_all(void) {}
|
||||
static inline void rb_yjit_lazy_push_frame(const VALUE *pc) {}
|
||||
|
||||
@@ -303,10 +303,11 @@ pub extern "C" fn rb_yjit_cme_invalidate(callee_cme: *const rb_callable_method_e
|
||||
});
|
||||
}
|
||||
|
||||
/// Callback for when Ruby is about to spawn a ractor. In that case we need to
|
||||
/// invalidate every block that is assuming single ractor mode.
|
||||
/// Invalidate every block that assumes single-ractor mode. Called when Ruby
|
||||
/// transitions from single-ractor to multi-ractor mode (i.e. a second ractor
|
||||
/// is spawned).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rb_yjit_before_ractor_spawn() {
|
||||
pub extern "C" fn rb_yjit_invalidate_single_ractor() {
|
||||
// If YJIT isn't enabled, do nothing
|
||||
if !yjit_enabled_p() {
|
||||
return;
|
||||
|
||||
@@ -86,7 +86,7 @@ void rb_zjit_iseq_update_references(void *payload);
|
||||
void rb_zjit_mark_all_writable(void);
|
||||
void rb_zjit_mark_all_executable(void);
|
||||
void rb_zjit_iseq_free(const rb_iseq_t *iseq);
|
||||
void rb_zjit_before_ractor_spawn(void);
|
||||
void rb_zjit_invalidate_single_ractor(void);
|
||||
void rb_zjit_tracing_invalidate_all(void);
|
||||
void rb_zjit_invalidate_no_singleton_class(VALUE klass);
|
||||
void rb_zjit_invalidate_root_box(void);
|
||||
@@ -133,7 +133,7 @@ static inline void rb_zjit_bop_redefined(int redefined_flag, enum ruby_basic_ope
|
||||
static inline void rb_zjit_cme_invalidate(const rb_callable_method_entry_t *cme) {}
|
||||
static inline void rb_zjit_invalidate_no_ep_escape(const rb_iseq_t *iseq) {}
|
||||
static inline void rb_zjit_constant_state_changed(ID id) {}
|
||||
static inline void rb_zjit_before_ractor_spawn(void) {}
|
||||
static inline void rb_zjit_invalidate_single_ractor(void) {}
|
||||
static inline void rb_zjit_tracing_invalidate_all(void) {}
|
||||
static inline void rb_zjit_invalidate_no_singleton_class(VALUE klass) {}
|
||||
static inline void rb_zjit_invalidate_root_box(void) {}
|
||||
|
||||
@@ -398,10 +398,11 @@ pub fn track_single_ractor_assumption(
|
||||
));
|
||||
}
|
||||
|
||||
/// Callback for when Ruby is about to spawn a ractor. In that case we need to
|
||||
/// invalidate every block that is assuming single ractor mode.
|
||||
/// Invalidate every block that assumes single-ractor mode. Called when Ruby
|
||||
/// transitions from single-ractor to multi-ractor mode (i.e. a second ractor
|
||||
/// is spawned).
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn rb_zjit_before_ractor_spawn() {
|
||||
pub extern "C" fn rb_zjit_invalidate_single_ractor() {
|
||||
// If ZJIT isn't enabled, do nothing
|
||||
if !zjit_enabled_p() {
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user