From 1a4b4cd7f8b53fc52191c1ddcf3f624a5e687c24 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 15 Feb 2023 15:18:01 +0100 Subject: Move `attached_object` into `rb_classext_struct` Given that signleton classes don't have an allocator, we can re-use these bytes to store the attached object in `rb_classext_struct` without making it larger. --- internal/class.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'internal') diff --git a/internal/class.h b/internal/class.h index b777548174..9905e4e388 100644 --- a/internal/class.h +++ b/internal/class.h @@ -53,7 +53,14 @@ struct rb_classext_struct { struct rb_subclass_entry *module_subclass_entry; const VALUE origin_; const VALUE refined_class; - rb_alloc_func_t allocator; + union { + struct { + rb_alloc_func_t allocator; + } class; + struct { + VALUE attached_object; + } singleton_class; + } as; const VALUE includer; #if !SHAPE_IN_BASIC_FLAGS shape_id_t shape_id; @@ -97,11 +104,10 @@ STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t #define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer) #define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry) #define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry) -#define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator) #define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses) #define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth) #define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses) -#define RCLASS_ATTACHED_OBJECT(c) (rb_attr_get(c, id__attached__)) +#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object) #define RICLASS_IS_ORIGIN FL_USER0 #define RCLASS_CLONED FL_USER1 @@ -147,6 +153,22 @@ VALUE rb_class_inherited(VALUE, VALUE); VALUE rb_keyword_error_new(const char *, VALUE); MJIT_SYMBOL_EXPORT_END +static inline rb_alloc_func_t +RCLASS_ALLOCATOR(VALUE klass) +{ + if (FL_TEST_RAW(klass, FL_SINGLETON)) { + return NULL; + } + return RCLASS_EXT(klass)->as.class.allocator; +} + +static inline void +RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator) +{ + assert(!FL_TEST(klass, FL_SINGLETON)); + RCLASS_EXT(klass)->as.class.allocator = allocator; +} + static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin) { @@ -204,9 +226,9 @@ static inline VALUE RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object) { assert(BUILTIN_TYPE(klass) == T_CLASS); - assert(FL_TEST(klass, FL_SINGLETON)); + assert(FL_TEST_RAW(klass, FL_SINGLETON)); - rb_class_ivar_set(klass, id__attached__, attached_object); + RB_OBJ_WRITE(klass, &RCLASS_EXT(klass)->as.singleton_class.attached_object, attached_object); return attached_object; } -- cgit v1.2.1