summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-02-15 15:18:01 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-02-16 08:14:44 +0100
commit1a4b4cd7f8b53fc52191c1ddcf3f624a5e687c24 (patch)
tree2143cb0a59d5f680d0c2c245b4698f51f75b952d /internal
parent1df75d658674d511780e578d3a394e1a9bcee5be (diff)
downloadruby-1a4b4cd7f8b53fc52191c1ddcf3f624a5e687c24.tar.gz
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.
Diffstat (limited to 'internal')
-rw-r--r--internal/class.h32
1 files changed, 27 insertions, 5 deletions
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;
}