From d67eb07f7549508da09e6f3aa2dbe55ad0ba2da1 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 9 Jun 2025 11:26:49 -0700 Subject: [PATCH] Fix missing write barrier through M_TBL When creating a new origin in ensure_origin, we need to fire a write barrier after RCLASS_WRITE_ORIGIN. rb_class_set_super allocates, so GC could happen there, either incrementally marking or promoting the newly allocated class, and only after RCLASS_WRITE_ORIGIN will origin mark object in the M_TBL. --- class.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/class.c b/class.c index bef54eae2f..5184a96ad9 100644 --- a/class.c +++ b/class.c @@ -1931,6 +1931,11 @@ ensure_origin(VALUE klass) rb_class_set_super(origin, RCLASS_SUPER(klass)); rb_class_set_super(klass, origin); // writes origin into RCLASS_SUPER(klass) RCLASS_WRITE_ORIGIN(klass, origin); + + // RCLASS_WRITE_ORIGIN marks origin as an origin, so this is the first + // point that it sees M_TBL and may mark it + rb_gc_writebarrier_remember(origin); + class_clear_method_table(klass); rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass); rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);