@@ -336,16 +336,43 @@ struct object_metadata {
336336 unsigned char seen_obj_id : 1 ;
337337};
338338
339- static inline struct object_metadata *
340- RVALUE_METADATA (VALUE obj )
339+ static st_table * object_metadata_table ;
340+
341+ static void
342+ init_object_metadata_table (void )
341343{
342- return (struct object_metadata * )(obj - 2 );
344+ object_metadata_table = st_init_numtable ();
345+ }
346+
347+ static void
348+ set_object_seen_obj_id (VALUE obj , bool seen )
349+ {
350+ st_data_t key = (st_data_t )obj ;
351+ st_data_t value ;
352+
353+ if (st_lookup (object_metadata_table , key , & value )) {
354+ struct object_metadata * metadata = (struct object_metadata * )value ;
355+ metadata -> seen_obj_id = seen ? 1 : 0 ;
356+ }
357+ else {
358+ struct object_metadata * metadata = xmalloc (sizeof (struct object_metadata ));
359+ metadata -> seen_obj_id = seen ? 1 : 0 ;
360+ st_insert (object_metadata_table , key , (st_data_t )metadata );
361+ }
343362}
344363
345364bool
346365rb_gc_impl_object_id_seen_p (VALUE obj )
347366{
348- return RVALUE_METADATA (obj )-> seen_obj_id ;
367+ st_data_t key = (st_data_t )obj ;
368+ st_data_t value ;
369+
370+ if (st_lookup (object_metadata_table , key , & value )) {
371+ struct object_metadata * metadata = (struct object_metadata * )value ;
372+ return metadata -> seen_obj_id != 0 ;
373+ }
374+
375+ return false;
349376}
350377
351378static int
@@ -370,6 +397,8 @@ rb_mmtk_update_obj_id_tables_obj_to_id_i(st_data_t key, st_data_t val, st_data_t
370397 return ST_CONTINUE ;
371398}
372399
400+ static void rb_mmtk_cleanup_metadata (void );
401+
373402static int
374403rb_mmtk_update_obj_id_tables_id_to_obj_i (st_data_t key , st_data_t val , st_data_t data )
375404{
@@ -389,6 +418,7 @@ rb_mmtk_update_obj_id_tables(void)
389418
390419 st_foreach (objspace -> obj_to_id_tbl , rb_mmtk_update_obj_id_tables_obj_to_id_i , 0 );
391420 st_foreach (objspace -> id_to_obj_tbl , rb_mmtk_update_obj_id_tables_id_to_obj_i , 0 );
421+ rb_mmtk_cleanup_metadata ();
392422}
393423
394424static int
@@ -464,6 +494,7 @@ rb_gc_impl_objspace_init(void *objspace_ptr)
464494 objspace -> measure_gc_time = true;
465495
466496 objspace_obj_id_init (objspace );
497+ init_object_metadata_table ();
467498
468499 objspace -> finalizer_table = st_init_numtable ();
469500 objspace -> finalizer_postponed_job = rb_postponed_job_preregister (0 , gc_run_finalizers , objspace );
@@ -475,9 +506,36 @@ rb_gc_impl_objspace_init(void *objspace_ptr)
475506 objspace -> cond_world_started = (pthread_cond_t )PTHREAD_COND_INITIALIZER ;
476507}
477508
509+ static int
510+ cleanup_object_metadata (st_data_t key , st_data_t val , st_data_t arg )
511+ {
512+ VALUE obj = (VALUE )key ;
513+ if (!mmtk_is_reachable ((MMTk_ObjectReference )obj )) {
514+ xfree ((void * )val );
515+ return ST_DELETE ;
516+ }
517+ return ST_CONTINUE ;
518+ }
519+
520+ static int
521+ free_metadata_entry (st_data_t key , st_data_t val , st_data_t arg )
522+ {
523+ xfree ((void * )val );
524+ return ST_CONTINUE ;
525+ }
526+
527+ static void
528+ rb_mmtk_cleanup_metadata (void )
529+ {
530+ st_foreach (object_metadata_table , cleanup_object_metadata , 0 );
531+ }
532+
478533void
479534rb_gc_impl_objspace_free (void * objspace_ptr )
480535{
536+ st_foreach (object_metadata_table , free_metadata_entry , 0 );
537+ st_free_table (object_metadata_table );
538+
481539 free (objspace_ptr );
482540}
483541
@@ -675,18 +733,14 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
675733 mmtk_handle_user_collection_request (ractor_cache , false, false);
676734 }
677735
678- size_t header_size = sizeof (struct object_metadata ) + 7 + sizeof ( VALUE ); // Should be 1 + 7 + 8 = 16
736+ size_t header_size = sizeof (VALUE );
679737 size_t allocation_size_with_header = alloc_size + header_size ;
680738 uintptr_t raw_ptr = (uintptr_t )mmtk_alloc (ractor_cache -> mutator , allocation_size_with_header , MMTk_MIN_OBJ_ALIGN , 0 , MMTK_ALLOCATION_SEMANTICS_DEFAULT );
681739
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 );
740+ VALUE * size_ptr = (VALUE * )(raw_ptr );
687741 * size_ptr = alloc_size ;
688742
689- VALUE * obj_ptr = size_ptr + 1 ; // Points right after the size field (raw_ptr + 16)
743+ VALUE * obj_ptr = size_ptr + 1 ;
690744
691745 obj_ptr [0 ] = flags ;
692746 obj_ptr [1 ] = klass ;
@@ -1153,7 +1207,7 @@ rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
11531207
11541208 st_insert (objspace -> obj_to_id_tbl , (st_data_t )obj , (st_data_t )id );
11551209 st_insert (objspace -> id_to_obj_tbl , (st_data_t )id , (st_data_t )obj );
1156- RVALUE_METADATA (obj ) -> seen_obj_id = true;
1210+ set_object_seen_obj_id (obj , true) ;
11571211 }
11581212 rb_gc_vm_unlock (lev );
11591213
0 commit comments