Skip to content

Commit a371d1e

Browse files
Fix MMTK GC by moving object metadata to side table
1 parent d260a63 commit a371d1e

1 file changed

Lines changed: 66 additions & 12 deletions

File tree

gc/mmtk/mmtk.c

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

345364
bool
346365
rb_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

351378
static 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+
373402
static int
374403
rb_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

394424
static 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+
478533
void
479534
rb_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

Comments
 (0)