summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2023-12-19 14:38:57 -0500
committerAaron Patterson <[email protected]>2023-12-19 13:09:36 -0800
commit28a6e4ea9d9379a654a8f7c4b37fa33aa3ccd0b7 (patch)
tree4f8aa54b7e5166d61e917ee6e5fbfde50aaf00ca /class.c
parent50d39219a9b5f19a536c02ec47b54b79efa015f5 (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.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/class.c b/class.c
index f730009709..5e9dbca3a3 100644
--- a/class.c
+++ b/class.c
@@ -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);