Add rb_jit_vm_lock_then_barrier and share it in ZJIT and YJIT

This commit is contained in:
Stan Lo 2025-08-29 19:13:42 +01:00 committed by Takashi Kokubun
parent 2f6a9c5167
commit 561050496c
9 changed files with 25 additions and 36 deletions

11
jit.c
View File

@ -473,3 +473,14 @@ rb_jit_multi_ractor_p(void)
{
return rb_multi_ractor_p();
}
// Acquire the VM lock and then signal all other Ruby threads (ractors) to
// contend for the VM lock, putting them to sleep. ZJIT and YJIT use this to
// evict threads running inside generated code so among other things, it can
// safely change memory protection of regions housing generated code.
void
rb_jit_vm_lock_then_barrier(unsigned int *recursive_lock_level, const char *file, int line)
{
rb_vm_lock_enter(recursive_lock_level, file, line);
rb_vm_barrier();
}

11
yjit.c
View File

@ -686,17 +686,6 @@ rb_yjit_obj_written(VALUE old, VALUE young, const char *file, int line)
rb_obj_written(old, Qundef, young, file, line);
}
// Acquire the VM lock and then signal all other Ruby threads (ractors) to
// contend for the VM lock, putting them to sleep. YJIT uses this to evict
// threads running inside generated code so among other things, it can
// safely change memory protection of regions housing generated code.
void
rb_yjit_vm_lock_then_barrier(unsigned int *recursive_lock_level, const char *file, int line)
{
rb_vm_lock_enter(recursive_lock_level, file, line);
rb_vm_barrier();
}
// Release the VM lock. The lock level must point to the same integer used to
// acquire the lock.
void

View File

@ -328,7 +328,6 @@ fn main() {
.allowlist_function("rb_set_cfp_(pc|sp)")
.allowlist_function("rb_c_method_tracing_currently_enabled")
.allowlist_function("rb_full_cfunc_return")
.allowlist_function("rb_yjit_vm_lock_then_barrier")
.allowlist_function("rb_yjit_vm_unlock")
.allowlist_function("rb_assert_(iseq|cme)_handle")
.allowlist_function("rb_IMEMO_TYPE_P")
@ -355,6 +354,7 @@ fn main() {
.allowlist_function("rb_assert_holding_vm_lock")
.allowlist_function("rb_jit_shape_too_complex_p")
.allowlist_function("rb_jit_multi_ractor_p")
.allowlist_function("rb_jit_vm_lock_then_barrier")
.allowlist_type("robject_offsets")
// from vm_sync.h

View File

@ -677,7 +677,7 @@ where
let line = loc.line;
let mut recursive_lock_level: c_uint = 0;
unsafe { rb_yjit_vm_lock_then_barrier(&mut recursive_lock_level, file, line) };
unsafe { rb_jit_vm_lock_then_barrier(&mut recursive_lock_level, file, line) };
let ret = match catch_unwind(func) {
Ok(result) => result,

View File

@ -1226,11 +1226,6 @@ extern "C" {
file: *const ::std::os::raw::c_char,
line: ::std::os::raw::c_int,
);
pub fn rb_yjit_vm_lock_then_barrier(
recursive_lock_level: *mut ::std::os::raw::c_uint,
file: *const ::std::os::raw::c_char,
line: ::std::os::raw::c_int,
);
pub fn rb_yjit_vm_unlock(
recursive_lock_level: *mut ::std::os::raw::c_uint,
file: *const ::std::os::raw::c_char,
@ -1328,4 +1323,9 @@ extern "C" {
pub fn rb_set_cfp_sp(cfp: *mut rb_control_frame_struct, sp: *mut VALUE);
pub fn rb_jit_shape_too_complex_p(shape_id: shape_id_t) -> bool;
pub fn rb_jit_multi_ractor_p() -> bool;
pub fn rb_jit_vm_lock_then_barrier(
recursive_lock_level: *mut ::std::os::raw::c_uint,
file: *const ::std::os::raw::c_char,
line: ::std::os::raw::c_int,
);
}

11
zjit.c
View File

@ -238,17 +238,6 @@ rb_zjit_icache_invalidate(void *start, void *end)
#endif
}
// Acquire the VM lock and then signal all other Ruby threads (ractors) to
// contend for the VM lock, putting them to sleep. ZJIT uses this to evict
// threads running inside generated code so among other things, it can
// safely change memory protection of regions housing generated code.
void
rb_zjit_vm_lock_then_barrier(unsigned int *recursive_lock_level, const char *file, int line)
{
rb_vm_lock_enter(recursive_lock_level, file, line);
rb_vm_barrier();
}
// Convert a given ISEQ's instructions to zjit_* instructions
void
rb_zjit_profile_enable(const rb_iseq_t *iseq)

View File

@ -347,7 +347,6 @@ fn main() {
.allowlist_function("rb_set_cfp_(pc|sp)")
.allowlist_function("rb_c_method_tracing_currently_enabled")
.allowlist_function("rb_full_cfunc_return")
.allowlist_function("rb_zjit_vm_lock_then_barrier")
.allowlist_function("rb_zjit_vm_unlock")
.allowlist_function("rb_assert_(iseq|cme)_handle")
.allowlist_function("rb_IMEMO_TYPE_P")
@ -368,6 +367,7 @@ fn main() {
.allowlist_function("rb_assert_holding_vm_lock")
.allowlist_function("rb_jit_shape_too_complex_p")
.allowlist_function("rb_jit_multi_ractor_p")
.allowlist_function("rb_jit_vm_lock_then_barrier")
.allowlist_type("robject_offsets")
// from vm_sync.h

View File

@ -825,7 +825,7 @@ where
let line = loc.line;
let mut recursive_lock_level: c_uint = 0;
unsafe { rb_zjit_vm_lock_then_barrier(&mut recursive_lock_level, file, line) };
unsafe { rb_jit_vm_lock_then_barrier(&mut recursive_lock_level, file, line) };
let ret = match catch_unwind(func) {
Ok(result) => result,

View File

@ -933,11 +933,6 @@ unsafe extern "C" {
start: *mut ::std::os::raw::c_void,
end: *mut ::std::os::raw::c_void,
);
pub fn rb_zjit_vm_lock_then_barrier(
recursive_lock_level: *mut ::std::os::raw::c_uint,
file: *const ::std::os::raw::c_char,
line: ::std::os::raw::c_int,
);
pub fn rb_zjit_iseq_insn_set(
iseq: *const rb_iseq_t,
insn_idx: ::std::os::raw::c_uint,
@ -1029,4 +1024,9 @@ unsafe extern "C" {
pub fn rb_set_cfp_sp(cfp: *mut rb_control_frame_struct, sp: *mut VALUE);
pub fn rb_jit_shape_too_complex_p(shape_id: shape_id_t) -> bool;
pub fn rb_jit_multi_ractor_p() -> bool;
pub fn rb_jit_vm_lock_then_barrier(
recursive_lock_level: *mut ::std::os::raw::c_uint,
file: *const ::std::os::raw::c_char,
line: ::std::os::raw::c_int,
);
}