From cc07159fbad13978641fb86943b810f6d55f08fd Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 29 Aug 2025 15:32:57 -0400 Subject: [PATCH 1/6] [DOC] rb_str_resurrect(): Reword to remove wrong guess; used by zlib --- include/ruby/internal/intern/string.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/ruby/internal/intern/string.h b/include/ruby/internal/intern/string.h index 7b1bf5cc543f45..75a28143fb8f1e 100644 --- a/include/ruby/internal/intern/string.h +++ b/include/ruby/internal/intern/string.h @@ -591,10 +591,9 @@ void rb_must_asciicompat(VALUE obj); VALUE rb_str_dup(VALUE str); /** - * I guess there is no use case of this function in extension libraries, but - * this is a routine identical to rb_str_dup(), except it always creates an - * instance of ::rb_cString regardless of the given object's class. This makes - * the most sense when the passed string is formerly hidden by rb_obj_hide(). + * Like rb_str_dup(), but always create an instance of ::rb_cString + * regardless of the given object's class. This makes the most sense + * when the passed string is formerly hidden by rb_obj_hide(). * * @param[in] str A string, possibly hidden. * @return A duplicated new instance of ::rb_cString. From 2f6a9c51670dd6dcc1cae52e4a793143fb148eb6 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Fri, 29 Aug 2025 19:03:53 +0100 Subject: [PATCH 2/6] Add rb_jit_multi_ractor_p and share it in ZJIT and YJIT --- jit.c | 7 +++++++ yjit.c | 7 ------- yjit/bindgen/src/main.rs | 2 +- yjit/src/cruby_bindings.inc.rs | 2 +- yjit/src/invariants.rs | 4 ++-- zjit.c | 7 ------- zjit/bindgen/src/main.rs | 2 +- zjit/src/cruby_bindings.inc.rs | 2 +- zjit/src/hir.rs | 2 +- 9 files changed, 14 insertions(+), 21 deletions(-) diff --git a/jit.c b/jit.c index 7d7b5fd4fd0b2f..b24da7d8febc92 100644 --- a/jit.c +++ b/jit.c @@ -13,6 +13,7 @@ #include "insns_info.inc" #include "iseq.h" #include "internal/gc.h" +#include "vm_sync.h" // Field offsets for the RObject struct enum robject_offsets { @@ -466,3 +467,9 @@ rb_jit_shape_too_complex_p(shape_id_t shape_id) { return rb_shape_too_complex_p(shape_id); } + +bool +rb_jit_multi_ractor_p(void) +{ + return rb_multi_ractor_p(); +} diff --git a/yjit.c b/yjit.c index cadae3a5df5f83..ee78d12e115c51 100644 --- a/yjit.c +++ b/yjit.c @@ -21,7 +21,6 @@ #include "builtin.h" #include "insns.inc" #include "insns_info.inc" -#include "vm_sync.h" #include "yjit.h" #include "zjit.h" #include "vm_insnhelper.h" @@ -638,12 +637,6 @@ rb_ENCODING_GET(VALUE obj) return RB_ENCODING_GET(obj); } -bool -rb_yjit_multi_ractor_p(void) -{ - return rb_multi_ractor_p(); -} - bool rb_yjit_constcache_shareable(const struct iseq_inline_constant_cache_entry *ice) { diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 5cf5caeb9af433..371a37ae0c8872 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -326,7 +326,6 @@ fn main() { .allowlist_function("rb_yjit_iseq_inspect") .allowlist_function("rb_yjit_builtin_function") .allowlist_function("rb_set_cfp_(pc|sp)") - .allowlist_function("rb_yjit_multi_ractor_p") .allowlist_function("rb_c_method_tracing_currently_enabled") .allowlist_function("rb_full_cfunc_return") .allowlist_function("rb_yjit_vm_lock_then_barrier") @@ -355,6 +354,7 @@ fn main() { // From jit.c .allowlist_function("rb_assert_holding_vm_lock") .allowlist_function("rb_jit_shape_too_complex_p") + .allowlist_function("rb_jit_multi_ractor_p") .allowlist_type("robject_offsets") // from vm_sync.h diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index c22f4490db8a0c..32a38135ec0fee 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1218,7 +1218,6 @@ extern "C" { pub fn rb_yjit_iseq_inspect(iseq: *const rb_iseq_t) -> *mut ::std::os::raw::c_char; pub fn rb_RSTRUCT_SET(st: VALUE, k: ::std::os::raw::c_int, v: VALUE); pub fn rb_ENCODING_GET(obj: VALUE) -> ::std::os::raw::c_int; - pub fn rb_yjit_multi_ractor_p() -> bool; pub fn rb_yjit_constcache_shareable(ice: *const iseq_inline_constant_cache_entry) -> bool; pub fn rb_yjit_for_each_iseq(callback: rb_iseq_callback, data: *mut ::std::os::raw::c_void); pub fn rb_yjit_obj_written( @@ -1328,4 +1327,5 @@ extern "C" { pub fn rb_set_cfp_pc(cfp: *mut rb_control_frame_struct, pc: *const VALUE); 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; } diff --git a/yjit/src/invariants.rs b/yjit/src/invariants.rs index 6ae1342ce38977..0f22fba6b84e4d 100644 --- a/yjit/src/invariants.rs +++ b/yjit/src/invariants.rs @@ -206,7 +206,7 @@ pub fn assume_method_basic_definition( /// Tracks that a block is assuming it is operating in single-ractor mode. #[must_use] pub fn assume_single_ractor_mode(jit: &mut JITState, asm: &mut Assembler) -> bool { - if unsafe { rb_yjit_multi_ractor_p() } { + if unsafe { rb_jit_multi_ractor_p() } { false } else { if jit_ensure_block_entry_exit(jit, asm).is_none() { @@ -495,7 +495,7 @@ pub extern "C" fn rb_yjit_constant_ic_update(iseq: *const rb_iseq_t, ic: IC, ins return; }; - if !unsafe { (*(*ic).entry).ic_cref }.is_null() || unsafe { rb_yjit_multi_ractor_p() } { + if !unsafe { (*(*ic).entry).ic_cref }.is_null() || unsafe { rb_jit_multi_ractor_p() } { // We can't generate code in these situations, so no need to invalidate. // See gen_opt_getinlinecache. return; diff --git a/zjit.c b/zjit.c index 8a7314cb7f92f4..a5fcc7e1c8b4d2 100644 --- a/zjit.c +++ b/zjit.c @@ -16,7 +16,6 @@ #include "insns.inc" #include "insns_info.inc" #include "zjit.h" -#include "vm_sync.h" #include "vm_insnhelper.h" #include "probes.h" #include "probes_helper.h" @@ -176,12 +175,6 @@ rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit extern VALUE *rb_vm_base_ptr(struct rb_control_frame_struct *cfp); -bool -rb_zjit_multi_ractor_p(void) -{ - return rb_multi_ractor_p(); -} - bool rb_zjit_constcache_shareable(const struct iseq_inline_constant_cache_entry *ice) { diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index ef8537cbbbdd0f..13a8b76b392eb8 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -367,6 +367,7 @@ fn main() { // From jit.c .allowlist_function("rb_assert_holding_vm_lock") .allowlist_function("rb_jit_shape_too_complex_p") + .allowlist_function("rb_jit_multi_ractor_p") .allowlist_type("robject_offsets") // from vm_sync.h @@ -433,7 +434,6 @@ fn main() { .allowlist_function("rb_get_cfp_ep") .allowlist_function("rb_get_cfp_ep_level") .allowlist_function("rb_get_cme_def_type") - .allowlist_function("rb_zjit_multi_ractor_p") .allowlist_function("rb_zjit_constcache_shareable") .allowlist_function("rb_get_cme_def_body_attr_id") .allowlist_function("rb_get_symbol_id") diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index c2f4b37a7ade2a..95596d6982111e 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -920,7 +920,6 @@ unsafe extern "C" { pub fn rb_zjit_reserve_addr_space(mem_size: u32) -> *mut u8; pub fn rb_zjit_profile_disable(iseq: *const rb_iseq_t); pub fn rb_vm_base_ptr(cfp: *mut rb_control_frame_struct) -> *mut VALUE; - pub fn rb_zjit_multi_ractor_p() -> bool; pub fn rb_zjit_constcache_shareable(ice: *const iseq_inline_constant_cache_entry) -> bool; pub fn rb_zjit_vm_unlock( recursive_lock_level: *mut ::std::os::raw::c_uint, @@ -1029,4 +1028,5 @@ unsafe extern "C" { pub fn rb_set_cfp_pc(cfp: *mut rb_control_frame_struct, pc: *const VALUE); 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; } diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index c55b5bbbf2015e..4a07a1aa742c71 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -1732,7 +1732,7 @@ impl Function { self.push_insn_id(block, insn_id); continue; } let cref_sensitive = !unsafe { (*ice).ic_cref }.is_null(); - let multi_ractor_mode = unsafe { rb_zjit_multi_ractor_p() }; + let multi_ractor_mode = unsafe { rb_jit_multi_ractor_p() }; if cref_sensitive || multi_ractor_mode { self.push_insn_id(block, insn_id); continue; } From 561050496c602ebc41d844db9fee91017f132d3a Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Fri, 29 Aug 2025 19:13:42 +0100 Subject: [PATCH 3/6] Add rb_jit_vm_lock_then_barrier and share it in ZJIT and YJIT --- jit.c | 11 +++++++++++ yjit.c | 11 ----------- yjit/bindgen/src/main.rs | 2 +- yjit/src/cruby.rs | 2 +- yjit/src/cruby_bindings.inc.rs | 10 +++++----- zjit.c | 11 ----------- zjit/bindgen/src/main.rs | 2 +- zjit/src/cruby.rs | 2 +- zjit/src/cruby_bindings.inc.rs | 10 +++++----- 9 files changed, 25 insertions(+), 36 deletions(-) diff --git a/jit.c b/jit.c index b24da7d8febc92..a5e90f29fdba31 100644 --- a/jit.c +++ b/jit.c @@ -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(); +} diff --git a/yjit.c b/yjit.c index ee78d12e115c51..8c94b59dbf98fc 100644 --- a/yjit.c +++ b/yjit.c @@ -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 diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 371a37ae0c8872..543f9992d6d528 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -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 diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 38d931b8ae1986..493a92bff511d4 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -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, diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 32a38135ec0fee..f7971310f35631 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -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, + ); } diff --git a/zjit.c b/zjit.c index a5fcc7e1c8b4d2..25f840232d7d0e 100644 --- a/zjit.c +++ b/zjit.c @@ -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) diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index 13a8b76b392eb8..859dab1862e821 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -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 diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 5a34e5a8de61c8..394bb7bb0f990b 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -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, diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 95596d6982111e..fb642aba879efa 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -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, + ); } From 3f3a54efff040e1f5dbbd296abe9ab0cb9304e4e Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Fri, 29 Aug 2025 19:16:43 +0100 Subject: [PATCH 4/6] Add rb_jit_vm_unlock and share it in ZJIT and YJIT --- jit.c | 8 ++++++++ yjit.c | 8 -------- yjit/bindgen/src/main.rs | 2 +- yjit/src/cruby.rs | 2 +- yjit/src/cruby_bindings.inc.rs | 10 +++++----- zjit.c | 7 ------- zjit/bindgen/src/main.rs | 2 +- zjit/src/cruby.rs | 2 +- zjit/src/cruby_bindings.inc.rs | 10 +++++----- 9 files changed, 22 insertions(+), 29 deletions(-) diff --git a/jit.c b/jit.c index a5e90f29fdba31..0709c6d8f03561 100644 --- a/jit.c +++ b/jit.c @@ -484,3 +484,11 @@ rb_jit_vm_lock_then_barrier(unsigned int *recursive_lock_level, const char *file 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 +rb_jit_vm_unlock(unsigned int *recursive_lock_level, const char *file, int line) +{ + rb_vm_lock_leave(recursive_lock_level, file, line); +} diff --git a/yjit.c b/yjit.c index 8c94b59dbf98fc..bca0df96fdf33f 100644 --- a/yjit.c +++ b/yjit.c @@ -686,14 +686,6 @@ rb_yjit_obj_written(VALUE old, VALUE young, const char *file, int line) rb_obj_written(old, Qundef, young, file, line); } -// Release the VM lock. The lock level must point to the same integer used to -// acquire the lock. -void -rb_yjit_vm_unlock(unsigned int *recursive_lock_level, const char *file, int line) -{ - rb_vm_lock_leave(recursive_lock_level, file, line); -} - void rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit_exception) { diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 543f9992d6d528..d30fb6c7796448 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -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_unlock") .allowlist_function("rb_assert_(iseq|cme)_handle") .allowlist_function("rb_IMEMO_TYPE_P") .allowlist_function("rb_yjit_constcache_shareable") @@ -355,6 +354,7 @@ fn main() { .allowlist_function("rb_jit_shape_too_complex_p") .allowlist_function("rb_jit_multi_ractor_p") .allowlist_function("rb_jit_vm_lock_then_barrier") + .allowlist_function("rb_jit_vm_unlock") .allowlist_type("robject_offsets") // from vm_sync.h diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 493a92bff511d4..36baecd5358031 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -697,7 +697,7 @@ where } }; - unsafe { rb_yjit_vm_unlock(&mut recursive_lock_level, file, line) }; + unsafe { rb_jit_vm_unlock(&mut recursive_lock_level, file, line) }; ret } diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index f7971310f35631..4d52b675a0de1f 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1226,11 +1226,6 @@ extern "C" { 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, - line: ::std::os::raw::c_int, - ); pub fn rb_object_shape_count() -> VALUE; pub fn rb_yjit_shape_obj_too_complex_p(obj: VALUE) -> bool; pub fn rb_yjit_shape_capacity(shape_id: shape_id_t) -> attr_index_t; @@ -1328,4 +1323,9 @@ extern "C" { file: *const ::std::os::raw::c_char, line: ::std::os::raw::c_int, ); + pub fn rb_jit_vm_unlock( + recursive_lock_level: *mut ::std::os::raw::c_uint, + file: *const ::std::os::raw::c_char, + line: ::std::os::raw::c_int, + ); } diff --git a/zjit.c b/zjit.c index 25f840232d7d0e..7b4952a93eb810 100644 --- a/zjit.c +++ b/zjit.c @@ -181,13 +181,6 @@ rb_zjit_constcache_shareable(const struct iseq_inline_constant_cache_entry *ice) return (ice->flags & IMEMO_CONST_CACHE_SHAREABLE) != 0; } -// Release the VM lock. The lock level must point to the same integer used to -// acquire the lock. -void -rb_zjit_vm_unlock(unsigned int *recursive_lock_level, const char *file, int line) -{ - rb_vm_lock_leave(recursive_lock_level, file, line); -} bool rb_zjit_mark_writable(void *mem_block, uint32_t mem_size) diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index 859dab1862e821..e57d0ae0154c48 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -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_unlock") .allowlist_function("rb_assert_(iseq|cme)_handle") .allowlist_function("rb_IMEMO_TYPE_P") .allowlist_function("rb_iseq_reset_jit_func") @@ -368,6 +367,7 @@ fn main() { .allowlist_function("rb_jit_shape_too_complex_p") .allowlist_function("rb_jit_multi_ractor_p") .allowlist_function("rb_jit_vm_lock_then_barrier") + .allowlist_function("rb_jit_vm_unlock") .allowlist_type("robject_offsets") // from vm_sync.h diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 394bb7bb0f990b..4208af03f55857 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -845,7 +845,7 @@ where } }; - unsafe { rb_zjit_vm_unlock(&mut recursive_lock_level, file, line) }; + unsafe { rb_jit_vm_unlock(&mut recursive_lock_level, file, line) }; ret } diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index fb642aba879efa..88b90976975bc8 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -921,11 +921,6 @@ unsafe extern "C" { pub fn rb_zjit_profile_disable(iseq: *const rb_iseq_t); pub fn rb_vm_base_ptr(cfp: *mut rb_control_frame_struct) -> *mut VALUE; pub fn rb_zjit_constcache_shareable(ice: *const iseq_inline_constant_cache_entry) -> bool; - pub fn rb_zjit_vm_unlock( - 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_mark_writable(mem_block: *mut ::std::os::raw::c_void, mem_size: u32) -> bool; pub fn rb_zjit_mark_executable(mem_block: *mut ::std::os::raw::c_void, mem_size: u32); pub fn rb_zjit_mark_unused(mem_block: *mut ::std::os::raw::c_void, mem_size: u32) -> bool; @@ -1029,4 +1024,9 @@ unsafe extern "C" { file: *const ::std::os::raw::c_char, line: ::std::os::raw::c_int, ); + pub fn rb_jit_vm_unlock( + recursive_lock_level: *mut ::std::os::raw::c_uint, + file: *const ::std::os::raw::c_char, + line: ::std::os::raw::c_int, + ); } From d4d510da1888d2b731ee85470e316673a1112b4a Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 29 Aug 2025 18:05:48 -0400 Subject: [PATCH 5/6] Document Makefile rules in tool/enc-unicode.rb [ci skip] --- tool/enc-unicode.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tool/enc-unicode.rb b/tool/enc-unicode.rb index 493a6f91c14380..a89390ad8fe997 100755 --- a/tool/enc-unicode.rb +++ b/tool/enc-unicode.rb @@ -12,6 +12,9 @@ # You can get source file for gperf. After this, simply make ruby. # Or directly run: # tool/enc-unicode.rb --header data_dir emoji_data_dir > enc/unicode//name2ctype.h +# +# There are Makefile rules that automate steps above: `make update-unicode` and +# `make enc/unicode//name2ctype.h`. while arg = ARGV.shift case arg From 96c8938535ff0cb2bf65943d7472a6702a121e16 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 29 Aug 2025 18:34:11 -0400 Subject: [PATCH 6/6] Shrink ruby_bug version guard in anticipation of 3.4.6 release Fix for this bug was merged into ruby_3_4 in 5a42d267bfabc86f86cae2e83de24b1b86bc316a and should go out in the next 3.4.x release. --- spec/ruby/language/regexp/character_classes_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb index 80cf88c7bdb1a9..018757db41fdf6 100644 --- a/spec/ruby/language/regexp/character_classes_spec.rb +++ b/spec/ruby/language/regexp/character_classes_spec.rb @@ -562,7 +562,7 @@ "\u{16EE}".match(/[[:word:]]/).to_a.should == ["\u{16EE}"] end - ruby_bug "#19417", ""..."3.5" do + ruby_bug "#19417", ""..."3.4.6" do it "matches Unicode join control characters with [[:word:]]" do "\u{200C}".match(/[[:word:]]/).to_a.should == ["\u{200C}"] "\u{200D}".match(/[[:word:]]/).to_a.should == ["\u{200D}"]