From 04edf3d9939d08f4e724cb91b9be374032cb662e Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Tue, 16 Dec 2025 13:02:33 +0100 Subject: [PATCH] ZJIT: Add a VALUE#write_barrier helper method to deduplicate logic --- zjit/src/cruby.rs | 8 ++++++++ zjit/src/gc.rs | 4 +--- zjit/src/profile.rs | 12 +++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 2bd44d2144..68b6810125 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -681,6 +681,14 @@ impl VALUE { let k: isize = item.wrapping_add(item.wrapping_add(1)); VALUE(k as usize) } + + /// Call the write barrier after separately writing val to self. + pub fn write_barrier(self, val: VALUE) { + // rb_gc_writebarrier() asserts it is not called with a special constant + if !val.special_const_p() { + unsafe { rb_gc_writebarrier(self, val) }; + } + } } pub type IseqParameters = rb_iseq_constant_body_rb_iseq_parameters; diff --git a/zjit/src/gc.rs b/zjit/src/gc.rs index 0d2e1350a7..40230ccc8d 100644 --- a/zjit/src/gc.rs +++ b/zjit/src/gc.rs @@ -183,9 +183,7 @@ pub fn append_gc_offsets(iseq: IseqPtr, mut version: IseqVersionRef, offsets: &V let value_ptr = value_ptr as *const VALUE; unsafe { let object = value_ptr.read_unaligned(); - if !object.special_const_p() { - rb_gc_writebarrier(iseq.into(), object); - } + VALUE::from(iseq).write_barrier(object); } } } diff --git a/zjit/src/profile.rs b/zjit/src/profile.rs index a4b893b2d7..867d97641b 100644 --- a/zjit/src/profile.rs +++ b/zjit/src/profile.rs @@ -124,9 +124,7 @@ fn profile_operands(profiler: &mut Profiler, profile: &mut IseqProfile, n: usize // TODO(max): Handle GC-hidden classes like Array, Hash, etc and make them look normal or // drop them or something let ty = ProfiledType::new(obj); - if !ty.class().special_const_p() { - unsafe { rb_gc_writebarrier(profiler.iseq.into(), ty.class()) }; - } + VALUE::from(profiler.iseq).write_barrier(ty.class()); profile_type.observe(ty); } } @@ -140,9 +138,7 @@ fn profile_self(profiler: &mut Profiler, profile: &mut IseqProfile) { // TODO(max): Handle GC-hidden classes like Array, Hash, etc and make them look normal or // drop them or something let ty = ProfiledType::new(obj); - if !ty.class().special_const_p() { - unsafe { rb_gc_writebarrier(profiler.iseq.into(), ty.class()) }; - } + VALUE::from(profiler.iseq).write_barrier(ty.class()); types[0].observe(ty); } @@ -153,9 +149,7 @@ fn profile_block_handler(profiler: &mut Profiler, profile: &mut IseqProfile) { } let obj = profiler.peek_at_block_handler(); let ty = ProfiledType::object(obj); - if !ty.class().special_const_p() { - unsafe { rb_gc_writebarrier(profiler.iseq.into(), ty.class()) }; - } + VALUE::from(profiler.iseq).write_barrier(ty.class()); types[0].observe(ty); }