[ruby/mmtk] Fix object ID for finalizers

We should get the object ID for finalizers in rb_gc_impl_define_finalizer
instead of when we create the finalizer job in make_final_job because
when we are in multi-Ractor mode, object ID needs to walk the references
which allocates an identity hash table. We cannot allocate in make_final_job
because it is in a MMTk worker thread.

https://github.com/ruby/mmtk/commit/922f22a690
This commit is contained in:
Peter Zhu 2025-05-20 13:03:09 -04:00 committed by git
parent 1c66124273
commit 27b0638386

View File

@ -59,7 +59,7 @@ struct MMTk_final_job {
void *data; void *data;
} dfree; } dfree;
struct { struct {
VALUE object_id; /* HACK: we store the object ID on the 0th element of this array. */
VALUE finalizer_array; VALUE finalizer_array;
} finalize; } finalize;
} as; } as;
@ -229,7 +229,6 @@ rb_mmtk_scan_objspace(void)
case MMTK_FINAL_JOB_DFREE: case MMTK_FINAL_JOB_DFREE:
break; break;
case MMTK_FINAL_JOB_FINALIZE: case MMTK_FINAL_JOB_FINALIZE:
rb_gc_impl_mark(objspace, job->as.finalize.object_id);
rb_gc_impl_mark(objspace, job->as.finalize.finalizer_array); rb_gc_impl_mark(objspace, job->as.finalize.finalizer_array);
break; break;
default: default:
@ -285,7 +284,6 @@ make_final_job(struct objspace *objspace, VALUE obj, VALUE table)
struct MMTk_final_job *job = xmalloc(sizeof(struct MMTk_final_job)); struct MMTk_final_job *job = xmalloc(sizeof(struct MMTk_final_job));
job->next = objspace->finalizer_jobs; job->next = objspace->finalizer_jobs;
job->kind = MMTK_FINAL_JOB_FINALIZE; job->kind = MMTK_FINAL_JOB_FINALIZE;
job->as.finalize.object_id = rb_obj_id((VALUE)obj);
job->as.finalize.finalizer_array = table; job->as.finalize.finalizer_array = table;
objspace->finalizer_jobs = job; objspace->finalizer_jobs = job;
@ -855,7 +853,7 @@ gc_run_finalizers_get_final(long i, void *data)
{ {
VALUE table = (VALUE)data; VALUE table = (VALUE)data;
return RARRAY_AREF(table, i); return RARRAY_AREF(table, i + 1);
} }
static void static void
@ -874,17 +872,15 @@ gc_run_finalizers(void *data)
job->as.dfree.func(job->as.dfree.data); job->as.dfree.func(job->as.dfree.data);
break; break;
case MMTK_FINAL_JOB_FINALIZE: { case MMTK_FINAL_JOB_FINALIZE: {
VALUE object_id = job->as.finalize.object_id;
VALUE finalizer_array = job->as.finalize.finalizer_array; VALUE finalizer_array = job->as.finalize.finalizer_array;
rb_gc_run_obj_finalizer( rb_gc_run_obj_finalizer(
job->as.finalize.object_id, RARRAY_AREF(finalizer_array, 0),
RARRAY_LEN(finalizer_array), RARRAY_LEN(finalizer_array) - 1,
gc_run_finalizers_get_final, gc_run_finalizers_get_final,
(void *)finalizer_array (void *)finalizer_array
); );
RB_GC_GUARD(object_id);
RB_GC_GUARD(finalizer_array); RB_GC_GUARD(finalizer_array);
break; break;
} }
@ -950,7 +946,7 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
rb_ary_push(table, block); rb_ary_push(table, block);
} }
else { else {
table = rb_ary_new3(1, block); table = rb_ary_new3(2, block);
rb_obj_hide(table); rb_obj_hide(table);
st_add_direct(objspace->finalizer_table, obj, table); st_add_direct(objspace->finalizer_table, obj, table);
} }