summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-06-18 11:31:11 +0100
committerJean Boussier <jean.boussier@gmail.com>2025-06-23 10:04:58 +0100
commit32ee3fab0a98ab7f520da0feb56b29c937d0cf6c (patch)
tree4354c76fdc905b86dca03dac486603ed74855613 /internal
parentea4a53c59561985df8b56e00890c75333b641788 (diff)
Shink RClass when it is known they can't be namespaced
Even when namespaces are enabled, only a few core classes created during init will eventually be namespaced. For these it's OK to allocate a 320B slot to hold the extra namespace stuff. But for any class created post init, we know we'll never need the namespace and we can fit in a 160B slot.
Diffstat (limited to 'internal')
-rw-r--r--internal/class.h23
1 files changed, 15 insertions, 8 deletions
diff --git a/internal/class.h b/internal/class.h
index 68cd813cb1..f71583d61a 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -136,7 +136,6 @@ STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_cl
struct RClass {
struct RBasic basic;
- st_table *ns_classext_tbl; // ns_object -> (rb_classext_t *)
VALUE object_id;
/*
* If ns_classext_tbl is NULL, then the prime classext is readable (because no other classext exists).
@@ -144,16 +143,22 @@ struct RClass {
*/
};
-// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
-// On 32bit platforms there is no variable width allocation so it doesn't matter.
-// TODO: restore this assertion after shrinking rb_classext_t
-// STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE || SIZEOF_VALUE < SIZEOF_LONG_LONG);
-
struct RClass_and_rb_classext_t {
struct RClass rclass;
rb_classext_t classext;
};
+#if SIZEOF_VALUE >= SIZEOF_LONG_LONG
+// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
+// On 32bit platforms there is no variable width allocation so it doesn't matter.
+STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass_and_rb_classext_t) <= 4 * RVALUE_SIZE);
+#endif
+
+struct RClass_namespaceable {
+ struct RClass_and_rb_classext_t base;
+ st_table *ns_classext_tbl; // ns_object -> (rb_classext_t *)
+};
+
static const uint16_t RCLASS_MAX_SUPERCLASS_DEPTH = ((uint16_t)-1);
static inline bool RCLASS_SINGLETON_P(VALUE klass);
@@ -297,7 +302,8 @@ static inline st_table *
RCLASS_CLASSEXT_TBL(VALUE klass)
{
if (FL_TEST_RAW(klass, RCLASS_NAMESPACEABLE)) {
- return RCLASS(klass)->ns_classext_tbl;
+ struct RClass_namespaceable *ns_klass = (struct RClass_namespaceable *)klass;
+ return ns_klass->ns_classext_tbl;
}
return NULL;
}
@@ -306,7 +312,8 @@ static inline void
RCLASS_SET_CLASSEXT_TBL(VALUE klass, st_table *tbl)
{
RUBY_ASSERT(FL_TEST_RAW(klass, RCLASS_NAMESPACEABLE));
- RCLASS(klass)->ns_classext_tbl = tbl;
+ struct RClass_namespaceable *ns_klass = (struct RClass_namespaceable *)klass;
+ ns_klass->ns_classext_tbl = tbl;
}
/* class.c */