[ruby/mmtk] 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.

870a79426b
This commit is contained in:
Peter Zhu 2025-07-29 16:50:58 -04:00 committed by git
parent 66bcb69054
commit 74887a2c12
4 changed files with 15 additions and 0 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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 {}

View file

@ -134,6 +134,10 @@ impl GCWork<Ruby> 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;
}