diff options
-rw-r--r-- | class.c | 9 | ||||
-rw-r--r-- | eval.c | 3 | ||||
-rw-r--r-- | gc.c | 9 | ||||
-rw-r--r-- | internal/class.h | 6 | ||||
-rw-r--r-- | method.h | 4 | ||||
-rw-r--r-- | vm_method.c | 25 |
6 files changed, 35 insertions, 21 deletions
@@ -911,8 +911,7 @@ rb_include_class_new(VALUE module, VALUE super) { VALUE klass = class_alloc(T_ICLASS, rb_cClass); - RCLASS_M_TBL(OBJ_WB_UNPROTECT(klass)) = - RCLASS_M_TBL(OBJ_WB_UNPROTECT(module)); /* TODO: unprotected? */ + RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); RCLASS_SET_ORIGIN(klass, klass); if (BUILTIN_TYPE(module) == T_ICLASS) { @@ -1098,13 +1097,12 @@ move_refined_method(ID key, VALUE value, void *data) const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me; RB_OBJ_WRITE(me, &me->def->body.refined.orig_me, NULL); new_me = rb_method_entry_clone(me); - rb_id_table_insert(tbl, key, (VALUE)new_me); - RB_OBJ_WRITTEN(klass, Qundef, new_me); + rb_method_table_insert(klass, tbl, key, new_me); rb_method_entry_copy(me, orig_me); return ID_TABLE_CONTINUE; } else { - rb_id_table_insert(tbl, key, (VALUE)me); + rb_method_table_insert(klass, tbl, key, me); return ID_TABLE_DELETE; } } @@ -1119,7 +1117,6 @@ ensure_origin(VALUE klass) VALUE origin = RCLASS_ORIGIN(klass); if (origin == klass) { origin = class_alloc(T_ICLASS, klass); - OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */ RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); RCLASS_SET_SUPER(klass, origin); RCLASS_SET_ORIGIN(klass, origin); @@ -1420,8 +1420,7 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module) c = iclass = rb_include_class_new(module, superclass); RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass); - RCLASS_M_TBL(OBJ_WB_UNPROTECT(c)) = - RCLASS_M_TBL(OBJ_WB_UNPROTECT(module)); /* TODO: check unprotecting */ + RCLASS_M_TBL(c) = RCLASS_M_TBL(module); module = RCLASS_SUPER(module); while (module && module != klass) { @@ -2854,8 +2854,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj) break; case T_ICLASS: /* Basically , T_ICLASS shares table with the module */ - if (FL_TEST(obj, RICLASS_IS_ORIGIN) && - !FL_TEST(obj, RICLASS_ORIGIN_SHARED_MTBL)) { + if (RICLASS_OWNS_M_TBL_P(obj)) { /* Method table is not shared for origin iclasses of classes */ rb_id_table_free(RCLASS_M_TBL(obj)); } @@ -3974,8 +3973,7 @@ obj_memsize_of(VALUE obj, int use_all_types) } break; case T_ICLASS: - if (FL_TEST(obj, RICLASS_IS_ORIGIN) && - !FL_TEST(obj, RICLASS_ORIGIN_SHARED_MTBL)) { + if (RICLASS_OWNS_M_TBL_P(obj)) { if (RCLASS_M_TBL(obj)) { size += rb_id_table_memsize(RCLASS_M_TBL(obj)); } @@ -5504,8 +5502,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) break; case T_ICLASS: - if (FL_TEST(obj, RICLASS_IS_ORIGIN) && - !FL_TEST(obj, RICLASS_ORIGIN_SHARED_MTBL)) { + if (RICLASS_OWNS_M_TBL_P(obj)) { mark_m_tbl(objspace, RCLASS_M_TBL(obj)); } if (RCLASS_SUPER(obj)) { diff --git a/internal/class.h b/internal/class.h index 40938255af..663a1e8dbf 100644 --- a/internal/class.h +++ b/internal/class.h @@ -144,6 +144,12 @@ RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass) FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL); } +static inline bool +RICLASS_OWNS_M_TBL_P(VALUE iclass) +{ + return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN; +} + static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass) { @@ -188,6 +188,8 @@ struct rb_method_definition_struct { uintptr_t method_serial; }; +struct rb_id_table; + typedef struct rb_method_definition_struct rb_method_definition_t; STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8); @@ -230,6 +232,8 @@ const rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me); const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class); void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src); +void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me); + void rb_scope_visibility_set(rb_method_visibility_t); VALUE rb_unnamed_parameters(int arity); diff --git a/vm_method.c b/vm_method.c index 037ac2a655..58516b9ddd 100644 --- a/vm_method.c +++ b/vm_method.c @@ -174,11 +174,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // invalidate cc by invalidating cc->cme VALUE owner = cme->owner; VM_ASSERT(BUILTIN_TYPE(owner) == T_CLASS); - rb_callable_method_entry_t *new_cme = - (rb_callable_method_entry_t *)rb_method_entry_clone((const rb_method_entry_t *)cme); - struct rb_id_table *mtbl = RCLASS_M_TBL(RCLASS_ORIGIN(owner)); - rb_id_table_insert(mtbl, mid, (VALUE)new_cme); - RB_OBJ_WRITTEN(owner, cme, new_cme); + const rb_method_entry_t *new_cme = rb_method_entry_clone((const rb_method_entry_t *)cme); + VALUE origin = RCLASS_ORIGIN(owner); + rb_method_table_insert(origin, RCLASS_M_TBL(origin), mid, new_cme); } vm_me_invalidate_cache((rb_callable_method_entry_t *)cme); RB_DEBUG_COUNTER_INC(cc_invalidate_tree_cme); @@ -261,6 +259,19 @@ rb_clear_method_cache_all(void) rb_objspace_each_objects(invalidate_all_cc, NULL); } +void +rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me) +{ + VALUE table_owner = klass; + if (RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass)) { + table_owner = RBASIC(table_owner)->klass; + } + VM_ASSERT(RB_TYPE_P(table_owner, T_CLASS) || RB_TYPE_P(table_owner, T_ICLASS) || RB_TYPE_P(table_owner, T_MODULE)); + VM_ASSERT(table == RCLASS_M_TBL(table_owner)); + rb_id_table_insert(table, method_id, (VALUE)me); + RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me); +} + VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker) { @@ -802,8 +813,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil make_method_entry_refined(klass, me); } - rb_id_table_insert(mtbl, mid, (VALUE)me); - RB_OBJ_WRITTEN(klass, Qundef, (VALUE)me); + rb_method_table_insert(klass, mtbl, mid, me); VM_ASSERT(me->def != NULL); @@ -973,6 +983,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ } cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class); rb_id_table_insert(mtbl, id, (VALUE)cme); + RB_OBJ_WRITTEN(defined_class, Qundef, (VALUE)cme); VM_ASSERT(callable_method_entry_p(cme)); } else { |