Skip to content

Commit 11ad7f5

Browse files
committed
Don't use namespaced classext for superclasses
Superclasses can't be modified by user code, so do not need namespace indirection. For example Object.superclass is always BasicObject, no matter what modules are included onto it.
1 parent 1435ea7 commit 11ad7f5

File tree

3 files changed

+17
-33
lines changed

3 files changed

+17
-33
lines changed

class.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,6 @@ duplicate_classext_const_tbl(struct rb_id_table *src, VALUE klass)
183183
return dst;
184184
}
185185

186-
static void
187-
duplicate_classext_superclasses(rb_classext_t *orig, rb_classext_t *copy)
188-
{
189-
RCLASSEXT_SUPERCLASSES(copy) = RCLASSEXT_SUPERCLASSES(orig);
190-
RCLASSEXT_SUPERCLASS_DEPTH(copy) = RCLASSEXT_SUPERCLASS_DEPTH(orig);
191-
// the copy is always not the owner and the orig (or its parent class) will maintain the superclasses array
192-
RCLASSEXT_SUPERCLASSES_OWNER(copy) = false;
193-
RCLASSEXT_SUPERCLASSES_WITH_SELF(copy) = RCLASSEXT_SUPERCLASSES_WITH_SELF(orig);
194-
}
195-
196186
static VALUE
197187
namespace_subclasses_tbl_key(const rb_namespace_t *ns)
198188
{
@@ -349,9 +339,6 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace
349339

350340
RCLASSEXT_CVC_TBL(ext) = duplicate_classext_id_table(RCLASSEXT_CVC_TBL(orig), dup_iclass);
351341

352-
// superclass_depth, superclasses
353-
duplicate_classext_superclasses(orig, ext);
354-
355342
// subclasses, subclasses_index
356343
duplicate_classext_subclasses(orig, ext);
357344

@@ -832,11 +819,11 @@ rb_class_update_superclasses(VALUE klass)
832819
}
833820
else {
834821
superclasses = class_superclasses_including_self(super);
835-
RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true, true);
822+
RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true);
836823
}
837824

838825
size_t depth = super_depth == RCLASS_MAX_SUPERCLASS_DEPTH ? super_depth : super_depth + 1;
839-
RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false, false);
826+
RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false);
840827
}
841828

842829
void

gc.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,8 @@ classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
12381238
rb_id_table_free(tbl);
12391239
}
12401240
rb_class_classext_free_subclasses(ext, args->klass);
1241-
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
1241+
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
1242+
RUBY_ASSERT(is_prime); // superclasses should only be used on prime
12421243
xfree(RCLASSEXT_SUPERCLASSES(ext));
12431244
}
12441245
if (!is_prime) { // the prime classext will be freed with RClass
@@ -2293,10 +2294,9 @@ classext_superclasses_memsize(rb_classext_t *ext, bool prime, VALUE namespace, v
22932294
{
22942295
size_t *size = (size_t *)arg;
22952296
size_t array_size;
2296-
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
2297-
array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext);
2298-
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext))
2299-
array_size += 1;
2297+
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
2298+
RUBY_ASSERT(prime);
2299+
array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1;
23002300
*size += array_size * sizeof(VALUE);
23012301
}
23022302
}
@@ -3802,10 +3802,8 @@ update_subclasses(void *objspace, rb_classext_t *ext)
38023802
static void
38033803
update_superclasses(rb_objspace_t *objspace, rb_classext_t *ext)
38043804
{
3805-
size_t array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext);
3806-
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
3807-
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext))
3808-
array_size += 1;
3805+
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
3806+
size_t array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1;
38093807
for (size_t i = 0; i < array_size; i++) {
38103808
UPDATE_IF_MOVED(objspace, RCLASSEXT_SUPERCLASSES(ext)[i]);
38113809
}

internal/class.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ struct rb_classext_struct {
127127
bool shared_const_tbl : 1;
128128
bool iclass_is_origin : 1;
129129
bool iclass_origin_shared_mtbl : 1;
130-
bool superclasses_owner : 1;
131130
bool superclasses_with_self : 1;
132131
VALUE classpath;
133132
};
@@ -198,7 +197,6 @@ static inline rb_classext_t * RCLASS_EXT_WRITABLE(VALUE obj);
198197
#define RCLASSEXT_SHARED_CONST_TBL(ext) (ext->shared_const_tbl)
199198
#define RCLASSEXT_ICLASS_IS_ORIGIN(ext) (ext->iclass_is_origin)
200199
#define RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) (ext->iclass_origin_shared_mtbl)
201-
#define RCLASSEXT_SUPERCLASSES_OWNER(ext) (ext->superclasses_owner)
202200
#define RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) (ext->superclasses_with_self)
203201
#define RCLASSEXT_CLASSPATH(ext) (ext->classpath)
204202

@@ -227,9 +225,6 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE
227225
* so always those should be writable.
228226
*/
229227
#define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl)
230-
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_READABLE(c)->superclass_depth)
231-
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_READABLE(c)->superclasses)
232-
#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_READABLE(c)->superclasses_with_self)
233228
#define RCLASS_SUBCLASSES_X(c) (RCLASS_EXT_READABLE(c)->subclasses)
234229
#define RCLASS_SUBCLASSES_FIRST(c) (RCLASS_EXT_READABLE(c)->subclasses->head->next)
235230
#define RCLASS_ORIGIN(c) (RCLASS_EXT_READABLE(c)->origin_)
@@ -240,6 +235,11 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE
240235
#define RCLASS_CLONED_P(c) (RCLASS_EXT_READABLE(c)->cloned)
241236
#define RCLASS_CLASSPATH(c) (RCLASS_EXT_READABLE(c)->classpath)
242237

238+
// Superclasses can't be changed after initialization
239+
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_PRIME(c)->superclass_depth)
240+
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_PRIME(c)->superclasses)
241+
#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_PRIME(c)->superclasses_with_self)
242+
243243
// namespaces don't make changes on these refined_class/attached_object/includer
244244
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT_PRIME(c)->refined_class)
245245
#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT_PRIME(c)->as.singleton_class.attached_object)
@@ -270,7 +270,7 @@ static inline void RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table);
270270
static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table);
271271
static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table);
272272

273-
static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self);
273+
static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool with_self);
274274
static inline void RCLASS_SET_SUBCLASSES(VALUE klass, rb_subclass_anchor_t *anchor);
275275
static inline void RCLASS_WRITE_NS_SUPER_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses);
276276
static inline void RCLASS_WRITE_NS_MODULE_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses);
@@ -714,14 +714,13 @@ RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
714714
}
715715

716716
static inline void
717-
RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self)
717+
RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool with_self)
718718
{
719719
RUBY_ASSERT(depth <= RCLASS_MAX_SUPERCLASS_DEPTH);
720720

721-
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
721+
rb_classext_t *ext = RCLASS_EXT_PRIME(klass);
722722
RCLASSEXT_SUPERCLASS_DEPTH(ext) = depth;
723723
RCLASSEXT_SUPERCLASSES(ext) = superclasses;
724-
RCLASSEXT_SUPERCLASSES_OWNER(ext) = owns_it;
725724
RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) = with_self;
726725
}
727726

0 commit comments

Comments
 (0)