@@ -332,6 +332,22 @@ rb_mmtk_update_finalizer_table(void)
332332 st_foreach (objspace -> finalizer_table , rb_mmtk_update_finalizer_table_i , (st_data_t )objspace );
333333}
334334
335+ struct object_metadata {
336+ unsigned char seen_obj_id : 1 ;
337+ };
338+
339+ static inline struct object_metadata *
340+ RVALUE_METADATA (VALUE obj )
341+ {
342+ return (struct object_metadata * )(obj - 2 );
343+ }
344+
345+ bool
346+ rb_gc_impl_object_id_seen_p (VALUE obj )
347+ {
348+ return RVALUE_METADATA (obj )-> seen_obj_id ;
349+ }
350+
335351static int
336352rb_mmtk_update_table_i (VALUE val , void * data )
337353{
@@ -345,7 +361,7 @@ rb_mmtk_update_table_i(VALUE val, void *data)
345361static int
346362rb_mmtk_update_obj_id_tables_obj_to_id_i (st_data_t key , st_data_t val , st_data_t data )
347363{
348- RUBY_ASSERT (RB_FL_TEST (key , FL_SEEN_OBJ_ID ));
364+ RUBY_ASSERT (rb_gc_impl_object_id_seen_p (key ));
349365
350366 if (!mmtk_is_reachable ((MMTk_ObjectReference )key )) {
351367 return ST_DELETE ;
@@ -357,7 +373,7 @@ rb_mmtk_update_obj_id_tables_obj_to_id_i(st_data_t key, st_data_t val, st_data_t
357373static int
358374rb_mmtk_update_obj_id_tables_id_to_obj_i (st_data_t key , st_data_t val , st_data_t data )
359375{
360- RUBY_ASSERT (RB_FL_TEST (val , FL_SEEN_OBJ_ID ));
376+ RUBY_ASSERT (rb_gc_impl_object_id_seen_p (val ));
361377
362378 if (!mmtk_is_reachable ((MMTk_ObjectReference )val )) {
363379 return ST_DELETE ;
@@ -659,23 +675,33 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
659675 mmtk_handle_user_collection_request (ractor_cache , false, false);
660676 }
661677
662- VALUE * alloc_obj = mmtk_alloc (ractor_cache -> mutator , alloc_size + 8 , MMTk_MIN_OBJ_ALIGN , 0 , MMTK_ALLOCATION_SEMANTICS_DEFAULT );
663- alloc_obj ++ ;
664- alloc_obj [-1 ] = alloc_size ;
665- alloc_obj [0 ] = flags ;
666- alloc_obj [1 ] = klass ;
667- if (alloc_size > 16 ) alloc_obj [2 ] = v1 ;
668- if (alloc_size > 24 ) alloc_obj [3 ] = v2 ;
669- if (alloc_size > 32 ) alloc_obj [4 ] = v3 ;
678+ size_t header_size = sizeof (struct object_metadata ) + 7 + sizeof (VALUE ); // Should be 1 + 7 + 8 = 16
679+ size_t allocation_size_with_header = alloc_size + header_size ;
680+ uintptr_t raw_ptr = (uintptr_t )mmtk_alloc (ractor_cache -> mutator , allocation_size_with_header , MMTk_MIN_OBJ_ALIGN , 0 , MMTK_ALLOCATION_SEMANTICS_DEFAULT );
681+
682+ struct object_metadata * metadata_ptr = (struct object_metadata * )raw_ptr ;
683+ * metadata_ptr = (struct object_metadata ){0 }; // Initialize all bitfields to 0
684+
685+
686+ VALUE * size_ptr = (VALUE * )(raw_ptr + 8 );
687+ * size_ptr = alloc_size ;
688+
689+ VALUE * obj_ptr = size_ptr + 1 ; // Points right after the size field (raw_ptr + 16)
690+
691+ obj_ptr [0 ] = flags ;
692+ obj_ptr [1 ] = klass ;
693+ if (alloc_size > (sizeof (VALUE ) * 2 )) obj_ptr [2 ] = v1 ;
694+ if (alloc_size > (sizeof (VALUE ) * 3 )) obj_ptr [3 ] = v2 ;
695+ if (alloc_size > (sizeof (VALUE ) * 4 )) obj_ptr [4 ] = v3 ; // Check if payload holds RBasic + 3 slots + more
670696
671- mmtk_post_alloc (ractor_cache -> mutator , (void * )alloc_obj , alloc_size + 8 , MMTK_ALLOCATION_SEMANTICS_DEFAULT );
697+ mmtk_post_alloc (ractor_cache -> mutator , (void * )obj_ptr , allocation_size_with_header , MMTK_ALLOCATION_SEMANTICS_DEFAULT );
672698
673699 // TODO: only add when object needs obj_free to be called
674- mmtk_add_obj_free_candidate (alloc_obj );
700+ mmtk_add_obj_free_candidate (obj_ptr );
675701
676702 objspace -> total_allocated_objects ++ ;
677703
678- return (VALUE )alloc_obj ;
704+ return (VALUE )obj_ptr ;
679705}
680706
681707size_t
@@ -1110,13 +1136,13 @@ rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
11101136 struct objspace * objspace = objspace_ptr ;
11111137
11121138 unsigned int lev = rb_gc_vm_lock ();
1113- if (FL_TEST (obj , FL_SEEN_OBJ_ID )) {
1139+ if (rb_gc_impl_object_id_seen_p (obj )) {
11141140 st_data_t val ;
11151141 if (st_lookup (objspace -> obj_to_id_tbl , (st_data_t )obj , & val )) {
11161142 id = (VALUE )val ;
11171143 }
11181144 else {
1119- rb_bug ("rb_gc_impl_object_id: FL_SEEN_OBJ_ID flag set but not found in table" );
1145+ rb_bug ("rb_gc_impl_object_id: object id seen already, but not found in table" );
11201146 }
11211147 }
11221148 else {
@@ -1127,7 +1153,7 @@ rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
11271153
11281154 st_insert (objspace -> obj_to_id_tbl , (st_data_t )obj , (st_data_t )id );
11291155 st_insert (objspace -> id_to_obj_tbl , (st_data_t )id , (st_data_t )obj );
1130- FL_SET (obj , FL_SEEN_OBJ_ID ) ;
1156+ RVALUE_METADATA (obj ) -> seen_obj_id = true ;
11311157 }
11321158 rb_gc_vm_unlock (lev );
11331159
@@ -1343,7 +1369,7 @@ rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj)
13431369 n++; \
13441370} while (0)
13451371
1346- if (FL_TEST (obj , FL_SEEN_OBJ_ID )) SET_ENTRY (object_id , rb_obj_id (obj ));
1372+ if (rb_gc_impl_object_id_seen_p (obj )) SET_ENTRY (object_id , rb_obj_id (obj ));
13471373
13481374 object_metadata_entries [n ].name = 0 ;
13491375 object_metadata_entries [n ].val = 0 ;
0 commit comments