Skip to content

Commit e09126f

Browse files
committed
initialize method tables before any GC chance
1 parent 1a34680 commit e09126f

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

class.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ static void
11831183
class_initialize_method_table(VALUE c)
11841184
{
11851185
// 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));
11871187
}
11881188

11891189
static void
@@ -1206,9 +1206,12 @@ rb_class_boot(VALUE super)
12061206
{
12071207
VALUE klass = class_alloc(T_CLASS, rb_cClass);
12081208

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
12101211
class_initialize_method_table(klass);
12111212

1213+
class_associate_super(klass, super, true);
1214+
12121215
return (VALUE)klass;
12131216
}
12141217

@@ -1492,7 +1495,9 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
14921495
struct clone_method_arg arg;
14931496
arg.old_klass = orig;
14941497
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));
14961501
rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
14971502
}
14981503

@@ -1609,6 +1614,9 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
16091614
RBASIC_SET_CLASS(clone, klass_metaclass_clone);
16101615
}
16111616

1617+
// initialize method table before any GC chance
1618+
class_initialize_method_table(clone);
1619+
16121620
rb_class_set_super(clone, RCLASS_SUPER(klass));
16131621
rb_iv_tbl_copy(clone, klass);
16141622
if (RCLASS_CONST_TBL(klass)) {
@@ -1622,7 +1630,6 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
16221630
if (!UNDEF_P(attach)) {
16231631
rb_singleton_class_attached(clone, attach);
16241632
}
1625-
class_initialize_method_table(clone);
16261633
{
16271634
struct clone_method_arg arg;
16281635
arg.old_klass = klass;

internal/class.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ static inline st_table * RCLASS_WRITABLE_IV_HASH(VALUE obj);
256256
static inline uint32_t RCLASS_IV_COUNT(VALUE obj);
257257
static inline void RCLASS_SET_IV_HASH(VALUE obj, const st_table *table);
258258
static inline void RCLASS_WRITE_IV_HASH(VALUE obj, const st_table *table);
259-
static inline void RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table);
260-
// TODO: rename RCLASS_WRITE_M_TBL_WORKAROUND to RCLASS_WRITE_M_TBL with write barrier
259+
// TODO: rename RCLASS_SET_M_TBL_WORKAROUND (and _WRITE_) to RCLASS_SET_M_TBL with write barrier
260+
static inline void RCLASS_SET_M_TBL_WORKAROUND(VALUE klass, struct rb_id_table *table, bool check_promoted);
261261
static inline void RCLASS_WRITE_M_TBL_WORKAROUND(VALUE klass, struct rb_id_table *table, bool check_promoted);
262262
static inline void RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
263263
static inline void RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
@@ -562,10 +562,13 @@ RCLASS_IV_COUNT(VALUE obj)
562562
}
563563
}
564564

565+
#define RCLASS_SET_M_TBL_EVEN_WHEN_PROMOTED(klass, table) RCLASS_SET_M_TBL_WORKAROUND(klass, table, false)
566+
#define RCLASS_SET_M_TBL(klass, table) RCLASS_SET_M_TBL_WORKAROUND(klass, table, true)
567+
565568
static inline void
566-
RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
569+
RCLASS_SET_M_TBL_WORKAROUND(VALUE klass, struct rb_id_table *table, bool check_promoted)
567570
{
568-
RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
571+
RUBY_ASSERT(!check_promoted || !RB_OBJ_PROMOTED(klass));
569572
RCLASSEXT_M_TBL(RCLASS_EXT(klass)) = table;
570573
}
571574

0 commit comments

Comments
 (0)