summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--class.c9
-rw-r--r--eval.c3
-rw-r--r--gc.c9
-rw-r--r--internal/class.h6
-rw-r--r--method.h4
-rw-r--r--vm_method.c25
6 files changed, 35 insertions, 21 deletions
diff --git a/class.c b/class.c
index 0d97603821..9876e996c8 100644
--- a/class.c
+++ b/class.c
@@ -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);
diff --git a/eval.c b/eval.c
index 237d9acaa7..e4fec3d6e1 100644
--- a/eval.c
+++ b/eval.c
@@ -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) {
diff --git a/gc.c b/gc.c
index 788f06f158..11a79e69fe 100644
--- a/gc.c
+++ b/gc.c
@@ -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)
{
diff --git a/method.h b/method.h
index 6bc494f4b0..dae0a4f43f 100644
--- a/method.h
+++ b/method.h
@@ -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 {