Skip to content

Commit 2ca8769

Browse files
committed
Reclaim one VALUE from rb_classext_t
The `includer` field is only used for `T_ICLASS`, so by moving it into the existing union we can save one `VALUE` per class and module.
1 parent c941fce commit 2ca8769

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

gc.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,12 +3718,14 @@ update_superclasses(rb_objspace_t *objspace, rb_classext_t *ext)
37183718
}
37193719

37203720
static void
3721-
update_classext_values(rb_objspace_t *objspace, rb_classext_t *ext)
3721+
update_classext_values(rb_objspace_t *objspace, rb_classext_t *ext, bool is_iclass)
37223722
{
37233723
UPDATE_IF_MOVED(objspace, RCLASSEXT_ORIGIN(ext));
37243724
UPDATE_IF_MOVED(objspace, RCLASSEXT_REFINED_CLASS(ext));
3725-
UPDATE_IF_MOVED(objspace, RCLASSEXT_INCLUDER(ext));
37263725
UPDATE_IF_MOVED(objspace, RCLASSEXT_CLASSPATH(ext));
3726+
if (is_iclass) {
3727+
UPDATE_IF_MOVED(objspace, RCLASSEXT_INCLUDER(ext));
3728+
}
37273729
}
37283730

37293731
static void
@@ -3757,7 +3759,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
37573759
update_superclasses(objspace, ext);
37583760
update_subclasses(objspace, ext);
37593761

3760-
update_classext_values(objspace, ext);
3762+
update_classext_values(objspace, ext, false);
37613763
}
37623764

37633765
static void
@@ -3774,7 +3776,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void
37743776
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
37753777
update_subclasses(objspace, ext);
37763778

3777-
update_classext_values(objspace, ext);
3779+
update_classext_values(objspace, ext, true);
37783780
}
37793781

37803782
extern rb_symbols_t ruby_global_symbols;

internal/class.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ struct rb_classext_struct {
116116
struct {
117117
VALUE attached_object;
118118
} singleton_class;
119+
struct {
120+
const VALUE includer;
121+
} iclass;
119122
} as;
120-
const VALUE includer;
121123
attr_index_t max_iv_count;
122124
unsigned char variation_count;
123125
bool permanent_classpath : 1;
@@ -184,7 +186,7 @@ static inline rb_classext_t * RCLASS_EXT_WRITABLE(VALUE obj);
184186
#define RCLASSEXT_ORIGIN(ext) (ext->origin_)
185187
#define RCLASSEXT_REFINED_CLASS(ext) (ext->refined_class)
186188
// class.allocator/singleton_class.attached_object are not accessed directly via RCLASSEXT_*
187-
#define RCLASSEXT_INCLUDER(ext) (ext->includer)
189+
#define RCLASSEXT_INCLUDER(ext) (ext->as.iclass.includer)
188190
#define RCLASSEXT_MAX_IV_COUNT(ext) (ext->max_iv_count)
189191
#define RCLASSEXT_VARIATION_COUNT(ext) (ext->variation_count)
190192
#define RCLASSEXT_PERMANENT_CLASSPATH(ext) (ext->permanent_classpath)
@@ -237,7 +239,7 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE
237239
// namespaces don't make changes on these refined_class/attached_object/includer
238240
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT_PRIME(c)->refined_class)
239241
#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT_PRIME(c)->as.singleton_class.attached_object)
240-
#define RCLASS_INCLUDER(c) (RCLASS_EXT_PRIME(c)->includer)
242+
#define RCLASS_INCLUDER(c) (RCLASS_EXT_PRIME(c)->as.iclass.includer)
241243

242244
// Writable classext entries (instead of RCLASS_SET_*) because member data will be operated directly
243245
#define RCLASS_WRITABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->m_tbl)
@@ -459,6 +461,7 @@ RCLASSEXT_SET_ORIGIN(rb_classext_t *ext, VALUE klass, VALUE origin)
459461
static inline void
460462
RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE includer)
461463
{
464+
RUBY_ASSERT(RB_TYPE_P(klass, T_ICLASS));
462465
RB_OBJ_WRITE(klass, &(RCLASSEXT_INCLUDER(ext)), includer);
463466
}
464467

@@ -651,7 +654,7 @@ RCLASS_SET_REFINED_CLASS(VALUE klass, VALUE refined)
651654
static inline rb_alloc_func_t
652655
RCLASS_ALLOCATOR(VALUE klass)
653656
{
654-
if (RCLASS_SINGLETON_P(klass)) {
657+
if (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS)) {
655658
return 0;
656659
}
657660
return RCLASS_EXT_PRIME(klass)->as.class.allocator;
@@ -702,6 +705,7 @@ RICLASS_OWNS_M_TBL_P(VALUE iclass)
702705
static inline void
703706
RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
704707
{
708+
RUBY_ASSERT(RB_TYPE_P(iclass, T_ICLASS));
705709
RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
706710
}
707711

0 commit comments

Comments
 (0)