From 870a79426bd37bb2eaa068cda3d97f05615ca4d5 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Tue, 29 Jul 2025 16:50:58 -0400 Subject: [PATCH] Skip weak references that are special consts If a reference marked weak becomes a special const, it will crash because it is not a GC handled object. We should skip special consts here. --- gc/mmtk/mmtk.c | 9 +++++++++ gc/mmtk/mmtk.h | 1 + gc/mmtk/src/abi.rs | 1 + gc/mmtk/src/weak_proc.rs | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index c318c6f..1c7d2d9 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -342,6 +342,14 @@ rb_mmtk_update_global_tables(int table) rb_gc_vm_weak_table_foreach(rb_mmtk_update_table_i, NULL, NULL, true, (enum rb_gc_vm_weak_tables)table); } +static bool +rb_mmtk_special_const_p(MMTk_ObjectReference object) +{ + VALUE obj = (VALUE)object; + + return RB_SPECIAL_CONST_P(obj); +} + // Bootup MMTk_RubyUpcalls ruby_upcalls = { rb_mmtk_init_gc_worker_thread, @@ -360,6 +368,7 @@ MMTk_RubyUpcalls ruby_upcalls = { rb_mmtk_update_global_tables, rb_mmtk_global_tables_count, rb_mmtk_update_finalizer_table, + rb_mmtk_special_const_p, }; // Use max 80% of the available memory by default for MMTk diff --git a/gc/mmtk/mmtk.h b/gc/mmtk/mmtk.h index 72b4d9d..b00133a 100644 --- a/gc/mmtk/mmtk.h +++ b/gc/mmtk/mmtk.h @@ -68,6 +68,7 @@ typedef struct MMTk_RubyUpcalls { void (*update_global_tables)(int tbl_idx); int (*global_tables_count)(void); void (*update_finalizer_table)(void); + bool (*special_const_p)(MMTk_ObjectReference object); } MMTk_RubyUpcalls; typedef struct MMTk_RawVecOfObjRef { diff --git a/gc/mmtk/src/abi.rs b/gc/mmtk/src/abi.rs index 81e2467..2214441 100644 --- a/gc/mmtk/src/abi.rs +++ b/gc/mmtk/src/abi.rs @@ -313,6 +313,7 @@ pub struct RubyUpcalls { pub update_global_tables: extern "C" fn(tbl_idx: c_int), pub global_tables_count: extern "C" fn() -> c_int, pub update_finalizer_table: extern "C" fn(), + pub special_const_p: extern "C" fn(object: ObjectReference) -> bool, } unsafe impl Sync for RubyUpcalls {} diff --git a/gc/mmtk/src/weak_proc.rs b/gc/mmtk/src/weak_proc.rs index 204dd20..2a7b0b0 100644 --- a/gc/mmtk/src/weak_proc.rs +++ b/gc/mmtk/src/weak_proc.rs @@ -138,6 +138,10 @@ impl GCWork for ProcessWeakReferences { .expect("Mutators should not be holding the lock."); for ptr_ptr in weak_references.iter_mut() { + if (upcalls().special_const_p)(**ptr_ptr) { + continue; + } + if !(**ptr_ptr).is_reachable() { **ptr_ptr = crate::binding().weak_reference_dead_value; }