зеркало из https://github.com/github/ruby.git
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 <tenderlove@ruby-lang.org>
This commit is contained in:
Родитель
50d39219a9
Коммит
28a6e4ea9d
9
class.c
9
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);
|
||||
|
|
|
@ -150,6 +150,13 @@ RCLASS_IV_COUNT(VALUE obj)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
|
||||
{
|
||||
RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
|
||||
RCLASS_M_TBL(klass) = table;
|
||||
}
|
||||
|
||||
/* class.c */
|
||||
void rb_class_subclass_add(VALUE super, VALUE klass);
|
||||
void rb_class_remove_from_super_subclasses(VALUE);
|
||||
|
|
Загрузка…
Ссылка в новой задаче