diff options
author | Peter Zhu <[email protected]> | 2023-12-19 14:38:57 -0500 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2023-12-19 13:09:36 -0800 |
commit | 28a6e4ea9d9379a654a8f7c4b37fa33aa3ccd0b7 (patch) | |
tree | 4f8aa54b7e5166d61e917ee6e5fbfde50aaf00ca /class.c | |
parent | 50d39219a9b5f19a536c02ec47b54b79efa015f5 (diff) |
Set m_tbl right after allocation
We should set the m_tbl right after allocation before anything that can
trigger GC to avoid clone_p from becoming old and needing to fire write
barriers.
Co-authored-by: Aaron Patterson <[email protected]>
Diffstat (limited to 'class.c')
-rw-r--r-- | class.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -578,9 +578,12 @@ rb_mod_init_copy(VALUE clone, VALUE orig) rb_bug("non iclass between module/class and origin"); } clone_p = class_alloc(RBASIC(p)->flags, METACLASS_OF(p)); + /* We should set the m_tbl right after allocation before anything + * that can trigger GC to avoid clone_p from becoming old and + * needing to fire write barriers. */ + RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p)); RCLASS_SET_SUPER(prev_clone_p, clone_p); prev_clone_p = clone_p; - RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p); RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p); RCLASS_SET_ALLOCATOR(clone_p, RCLASS_ALLOCATOR(p)); if (RB_TYPE_P(clone, T_CLASS)) { @@ -1134,7 +1137,7 @@ rb_include_class_new(VALUE module, VALUE super) { VALUE klass = class_alloc(T_ICLASS, rb_cClass); - RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); + RCLASS_SET_M_TBL(klass, RCLASS_M_TBL(module)); RCLASS_SET_ORIGIN(klass, klass); if (BUILTIN_TYPE(module) == T_ICLASS) { @@ -1410,10 +1413,10 @@ ensure_origin(VALUE klass) VALUE origin = RCLASS_ORIGIN(klass); if (origin == klass) { origin = class_alloc(T_ICLASS, klass); + RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass)); RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); RCLASS_SET_SUPER(klass, origin); RCLASS_SET_ORIGIN(klass, origin); - RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); RCLASS_M_TBL_INIT(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); |