@@ -1183,7 +1183,7 @@ static void
1183
1183
class_initialize_method_table (VALUE c )
1184
1184
{
1185
1185
// initialize the prime classext m_tbl
1186
- RCLASS_SET_M_TBL (c , rb_id_table_create (0 ));
1186
+ RCLASS_SET_M_TBL_EVEN_WHEN_PROMOTED (c , rb_id_table_create (0 ));
1187
1187
}
1188
1188
1189
1189
static void
@@ -1206,9 +1206,12 @@ rb_class_boot(VALUE super)
1206
1206
{
1207
1207
VALUE klass = class_alloc (T_CLASS , rb_cClass );
1208
1208
1209
- class_associate_super (klass , super , true);
1209
+ // initialize method table prior to class_associate_super()
1210
+ // because class_associate_super() may cause GC and promote klass
1210
1211
class_initialize_method_table (klass );
1211
1212
1213
+ class_associate_super (klass , super , true);
1214
+
1212
1215
return (VALUE )klass ;
1213
1216
}
1214
1217
@@ -1492,7 +1495,9 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
1492
1495
struct clone_method_arg arg ;
1493
1496
arg .old_klass = orig ;
1494
1497
arg .new_klass = clone ;
1495
- class_initialize_method_table (clone );
1498
+ // TODO: use class_initialize_method_table() instead of RCLASS_SET_M_TBL_*
1499
+ // after RCLASS_SET_M_TBL is protected by write barrier
1500
+ RCLASS_SET_M_TBL_EVEN_WHEN_PROMOTED (clone , rb_id_table_create (0 ));
1496
1501
rb_id_table_foreach (RCLASS_M_TBL (orig ), clone_method_i , & arg );
1497
1502
}
1498
1503
@@ -1609,6 +1614,9 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
1609
1614
RBASIC_SET_CLASS (clone , klass_metaclass_clone );
1610
1615
}
1611
1616
1617
+ // initialize method table before any GC chance
1618
+ class_initialize_method_table (clone );
1619
+
1612
1620
rb_class_set_super (clone , RCLASS_SUPER (klass ));
1613
1621
rb_iv_tbl_copy (clone , klass );
1614
1622
if (RCLASS_CONST_TBL (klass )) {
@@ -1622,7 +1630,6 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
1622
1630
if (!UNDEF_P (attach )) {
1623
1631
rb_singleton_class_attached (clone , attach );
1624
1632
}
1625
- class_initialize_method_table (clone );
1626
1633
{
1627
1634
struct clone_method_arg arg ;
1628
1635
arg .old_klass = klass ;
0 commit comments