diff options
author | John Hawthorn <[email protected]> | 2025-05-20 13:10:41 -0700 |
---|---|---|
committer | John Hawthorn <[email protected]> | 2025-05-23 10:22:24 -0700 |
commit | 11ad7f5f47b4e4919bcf7a03338a62ef5b5396cc (patch) | |
tree | 24b162eff4ed9bdf6c846cb85319e0f99b5c5125 | |
parent | 1435ea7f44f3d781a03054b4055a1ad2f90dd392 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13420
-rw-r--r-- | class.c | 17 | ||||
-rw-r--r-- | gc.c | 16 | ||||
-rw-r--r-- | internal/class.h | 17 |
3 files changed, 17 insertions, 33 deletions
@@ -183,16 +183,6 @@ duplicate_classext_const_tbl(struct rb_id_table *src, VALUE klass) return dst; } -static void -duplicate_classext_superclasses(rb_classext_t *orig, rb_classext_t *copy) -{ - RCLASSEXT_SUPERCLASSES(copy) = RCLASSEXT_SUPERCLASSES(orig); - RCLASSEXT_SUPERCLASS_DEPTH(copy) = RCLASSEXT_SUPERCLASS_DEPTH(orig); - // the copy is always not the owner and the orig (or its parent class) will maintain the superclasses array - RCLASSEXT_SUPERCLASSES_OWNER(copy) = false; - RCLASSEXT_SUPERCLASSES_WITH_SELF(copy) = RCLASSEXT_SUPERCLASSES_WITH_SELF(orig); -} - static VALUE namespace_subclasses_tbl_key(const rb_namespace_t *ns) { @@ -349,9 +339,6 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace RCLASSEXT_CVC_TBL(ext) = duplicate_classext_id_table(RCLASSEXT_CVC_TBL(orig), dup_iclass); - // superclass_depth, superclasses - duplicate_classext_superclasses(orig, ext); - // subclasses, subclasses_index duplicate_classext_subclasses(orig, ext); @@ -832,11 +819,11 @@ rb_class_update_superclasses(VALUE klass) } else { superclasses = class_superclasses_including_self(super); - RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true, true); + RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true); } size_t depth = super_depth == RCLASS_MAX_SUPERCLASS_DEPTH ? super_depth : super_depth + 1; - RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false, false); + RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false); } void @@ -1238,7 +1238,8 @@ classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg) rb_id_table_free(tbl); } rb_class_classext_free_subclasses(ext, args->klass); - if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) { + if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) { + RUBY_ASSERT(is_prime); // superclasses should only be used on prime xfree(RCLASSEXT_SUPERCLASSES(ext)); } 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 { size_t *size = (size_t *)arg; size_t array_size; - if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) { - array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext); - if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) - array_size += 1; + if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) { + RUBY_ASSERT(prime); + array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1; *size += array_size * sizeof(VALUE); } } @@ -3802,10 +3802,8 @@ update_subclasses(void *objspace, rb_classext_t *ext) static void update_superclasses(rb_objspace_t *objspace, rb_classext_t *ext) { - size_t array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext); - if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) { - if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) - array_size += 1; + if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) { + size_t array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1; for (size_t i = 0; i < array_size; i++) { UPDATE_IF_MOVED(objspace, RCLASSEXT_SUPERCLASSES(ext)[i]); } diff --git a/internal/class.h b/internal/class.h index 82f8f0e9dc..15530b8842 100644 --- a/internal/class.h +++ b/internal/class.h @@ -127,7 +127,6 @@ struct rb_classext_struct { bool shared_const_tbl : 1; bool iclass_is_origin : 1; bool iclass_origin_shared_mtbl : 1; - bool superclasses_owner : 1; bool superclasses_with_self : 1; VALUE classpath; }; @@ -198,7 +197,6 @@ static inline rb_classext_t * RCLASS_EXT_WRITABLE(VALUE obj); #define RCLASSEXT_SHARED_CONST_TBL(ext) (ext->shared_const_tbl) #define RCLASSEXT_ICLASS_IS_ORIGIN(ext) (ext->iclass_is_origin) #define RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) (ext->iclass_origin_shared_mtbl) -#define RCLASSEXT_SUPERCLASSES_OWNER(ext) (ext->superclasses_owner) #define RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) (ext->superclasses_with_self) #define RCLASSEXT_CLASSPATH(ext) (ext->classpath) @@ -227,9 +225,6 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE * so always those should be writable. */ #define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl) -#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_READABLE(c)->superclass_depth) -#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_READABLE(c)->superclasses) -#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_READABLE(c)->superclasses_with_self) #define RCLASS_SUBCLASSES_X(c) (RCLASS_EXT_READABLE(c)->subclasses) #define RCLASS_SUBCLASSES_FIRST(c) (RCLASS_EXT_READABLE(c)->subclasses->head->next) #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 #define RCLASS_CLONED_P(c) (RCLASS_EXT_READABLE(c)->cloned) #define RCLASS_CLASSPATH(c) (RCLASS_EXT_READABLE(c)->classpath) +// Superclasses can't be changed after initialization +#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_PRIME(c)->superclass_depth) +#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_PRIME(c)->superclasses) +#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_PRIME(c)->superclasses_with_self) + // namespaces don't make changes on these refined_class/attached_object/includer #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT_PRIME(c)->refined_class) #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); static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table); static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table); -static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self); +static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool with_self); static inline void RCLASS_SET_SUBCLASSES(VALUE klass, rb_subclass_anchor_t *anchor); static inline void RCLASS_WRITE_NS_SUPER_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses); 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) } static inline void -RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self) +RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool with_self) { RUBY_ASSERT(depth <= RCLASS_MAX_SUPERCLASS_DEPTH); - rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass); + rb_classext_t *ext = RCLASS_EXT_PRIME(klass); RCLASSEXT_SUPERCLASS_DEPTH(ext) = depth; RCLASSEXT_SUPERCLASSES(ext) = superclasses; - RCLASSEXT_SUPERCLASSES_OWNER(ext) = owns_it; RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) = with_self; } |