diff options
| author | John Hawthorn <john@hawthorn.email> | 2025-06-09 11:26:49 -0700 |
|---|---|---|
| committer | John Hawthorn <john@hawthorn.email> | 2025-07-23 14:33:55 -0700 |
| commit | d67eb07f7549508da09e6f3aa2dbe55ad0ba2da1 (patch) | |
| tree | bdad5253f90cfcbbedb6fec79eabe9227e820f10 /class.c | |
| parent | 54a578e72a9a13b88683fd4d12921da86c3e9cf2 (diff) | |
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.
Diffstat (limited to 'class.c')
| -rw-r--r-- | class.c | 5 |
1 files changed, 5 insertions, 0 deletions
@@ -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); |
