diff options
| author | Matt Valentine-House <matt@eightbitraptor.com> | 2026-05-07 14:24:58 +0100 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2026-05-08 15:13:14 +0000 |
| commit | 06caa59cc3b2787ade201a5ecbe3339930e85105 (patch) | |
| tree | c2fc3bdad37323fea0867cad3faaaf6b9f2aede6 | |
| parent | 9fefb48643648234a71726e62ea7da2749cb85f4 (diff) | |
[ruby/mmtk] Introduce support for ractor_belonging.
This is a debug mode in Ruby where an extra word is used after each
object to store the address of the Ractor that owns the object, used for
debug purposes only.
While we're working on Ractors, we also need to be able to test with
MMTk enabled, so we should introduce support for this to the MMTk
binding as well.
As implemented we'll default the binding options to have everything
disabled and hardcoded to 0, as was always the case, but if
RACTOR_CHECK_MODE is enabled, we'll build and pass a valid RubyBinding
object to MMTk.
https://github.com/ruby/mmtk/commit/83cb291313
| -rw-r--r-- | gc/mmtk/mmtk.c | 31 | ||||
| -rw-r--r-- | gc/mmtk/mmtk.h | 2 | ||||
| -rw-r--r-- | gc/mmtk/src/api.rs | 12 |
3 files changed, 37 insertions, 8 deletions
diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index e4cd71925c..9b1aed4e5b 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -16,6 +16,22 @@ #include <sys/sysctl.h> #endif +#ifndef VM_CHECK_MODE +# define VM_CHECK_MODE RUBY_DEBUG +#endif + +// From ractor_core.h +#ifndef RACTOR_CHECK_MODE +# define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE) +#endif + +#if RACTOR_CHECK_MODE +# define RVALUE_SUFFIX_SIZE sizeof(VALUE) +void rb_ractor_setup_belonging(VALUE obj); +#else +# define RVALUE_SUFFIX_SIZE 0 +#endif + struct objspace { bool measure_gc_time; bool gc_stress; @@ -557,7 +573,11 @@ void * rb_gc_impl_objspace_alloc(void) { MMTk_Builder *builder = rb_mmtk_builder_init(); - mmtk_init_binding(builder, NULL, &ruby_upcalls); + MMTk_RubyBindingOptions binding_options = { + .ractor_check_mode = RACTOR_CHECK_MODE != 0, + .suffix_size = RVALUE_SUFFIX_SIZE, + }; + mmtk_init_binding(builder, &binding_options, &ruby_upcalls); return calloc(1, sizeof(struct objspace)); } @@ -885,7 +905,8 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags mmtk_handle_user_collection_request(ractor_cache, false, false); } - alloc_size += sizeof(VALUE); + // Layout: [hidden size header (sizeof(VALUE))][payload (alloc_size)][suffix (RVALUE_SUFFIX_SIZE)] + alloc_size += sizeof(VALUE) + RVALUE_SUFFIX_SIZE; VALUE *alloc_obj = (VALUE *)rb_mmtk_alloc_fast_path(objspace, ractor_cache, alloc_size); if (!alloc_obj) { @@ -893,7 +914,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags } alloc_obj++; - alloc_obj[-1] = alloc_size - sizeof(VALUE); + alloc_obj[-1] = alloc_size - sizeof(VALUE) - RVALUE_SUFFIX_SIZE; alloc_obj[0] = flags; alloc_obj[1] = klass; @@ -905,6 +926,10 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags objspace->total_allocated_objects++; +#if RACTOR_CHECK_MODE + rb_ractor_setup_belonging((VALUE)alloc_obj); +#endif + return (VALUE)alloc_obj; } diff --git a/gc/mmtk/mmtk.h b/gc/mmtk/mmtk.h index ee338c87ef..e8f95920dd 100644 --- a/gc/mmtk/mmtk.h +++ b/gc/mmtk/mmtk.h @@ -95,7 +95,7 @@ bool mmtk_is_reachable(MMTk_ObjectReference object); MMTk_Builder *mmtk_builder_default(void); void mmtk_init_binding(MMTk_Builder *builder, - const struct MMTk_RubyBindingOptions *_binding_options, + const struct MMTk_RubyBindingOptions *binding_options, const struct MMTk_RubyUpcalls *upcalls); void mmtk_initialize_collection(MMTk_VMThread tls); diff --git a/gc/mmtk/src/api.rs b/gc/mmtk/src/api.rs index b9797f6fe2..0c73cd74eb 100644 --- a/gc/mmtk/src/api.rs +++ b/gc/mmtk/src/api.rs @@ -181,7 +181,7 @@ pub extern "C" fn mmtk_builder_default() -> *mut MMTKBuilder { #[no_mangle] pub unsafe extern "C" fn mmtk_init_binding( builder: *mut MMTKBuilder, - _binding_options: *const RubyBindingOptions, + binding_options: *const RubyBindingOptions, upcalls: *const RubyUpcalls, ) { crate::MUTATOR_THREAD_PANIC_HANDLER @@ -191,9 +191,13 @@ pub unsafe extern "C" fn mmtk_init_binding( crate::set_panic_hook(); let builder: Box<MMTKBuilder> = unsafe { Box::from_raw(builder) }; - let binding_options = RubyBindingOptions { - ractor_check_mode: false, - suffix_size: 0, + let binding_options = if binding_options.is_null() { + RubyBindingOptions { + ractor_check_mode: false, + suffix_size: 0, + } + } else { + unsafe { (*binding_options).clone() } }; let mmtk_boxed = mmtk_init(&builder); let mmtk_static = Box::leak(Box::new(mmtk_boxed)); |
