summaryrefslogtreecommitdiff
path: root/gc/mmtk
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2025-04-21 16:16:07 +0900
committerJean Boussier <[email protected]>2025-05-08 07:58:05 +0200
commitf48e45d1e9c4412d5f3ee49241d0b9359651ce7c (patch)
tree88e53f6ef5e926b87f6ab620ca6ff23bf15380f3 /gc/mmtk
parentd34c15054708c84e9d3305ede0752820b42ac498 (diff)
Move `object_id` in object fields.
And get rid of the `obj_to_id_tbl` It's no longer needed, the `object_id` is now stored inline in the object alongside instance variables. We still need the inverse table in case `_id2ref` is invoked, but we lazily build it by walking the heap if that happens. The `object_id` concern is also no longer a GC implementation concern, but a generic implementation. Co-Authored-By: Matt Valentine-House <[email protected]>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13159
Diffstat (limited to 'gc/mmtk')
-rw-r--r--gc/mmtk/mmtk.c152
-rw-r--r--gc/mmtk/mmtk.h1
-rw-r--r--gc/mmtk/src/abi.rs1
-rw-r--r--gc/mmtk/src/weak_proc.rs1
4 files changed, 1 insertions, 154 deletions
diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c
index d74bce79e8..59bef826bf 100644
--- a/gc/mmtk/mmtk.c
+++ b/gc/mmtk/mmtk.c
@@ -24,10 +24,6 @@ struct objspace {
size_t total_gc_time;
size_t total_allocated_objects;
- st_table *id_to_obj_tbl;
- st_table *obj_to_id_tbl;
- unsigned long long next_object_id;
-
st_table *finalizer_table;
struct MMTk_final_job *finalizer_jobs;
rb_postponed_job_handle_t finalizer_postponed_job;
@@ -227,8 +223,6 @@ rb_mmtk_scan_objspace(void)
st_foreach(objspace->finalizer_table, pin_value, (st_data_t)objspace);
}
- st_foreach(objspace->obj_to_id_tbl, gc_mark_tbl_no_pin_i, (st_data_t)objspace);
-
struct MMTk_final_job *job = objspace->finalizer_jobs;
while (job != NULL) {
switch (job->kind) {
@@ -337,41 +331,6 @@ rb_mmtk_update_table_i(VALUE val, void *data)
}
static int
-rb_mmtk_update_obj_id_tables_obj_to_id_i(st_data_t key, st_data_t val, st_data_t data)
-{
- RUBY_ASSERT(RB_FL_TEST(key, FL_SEEN_OBJ_ID));
-
- if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
- return ST_DELETE;
- }
-
- return ST_CONTINUE;
-}
-
-static int
-rb_mmtk_update_obj_id_tables_id_to_obj_i(st_data_t key, st_data_t val, st_data_t data)
-{
- RUBY_ASSERT(RB_FL_TEST(val, FL_SEEN_OBJ_ID));
-
- if (!mmtk_is_reachable((MMTk_ObjectReference)val)) {
- return ST_DELETE;
- }
-
- return ST_CONTINUE;
-}
-
-static void
-rb_mmtk_update_obj_id_tables(void)
-{
- struct objspace *objspace = rb_gc_get_objspace();
-
- st_foreach(objspace->obj_to_id_tbl, rb_mmtk_update_obj_id_tables_obj_to_id_i, 0);
- if (objspace->id_to_obj_tbl) {
- st_foreach(objspace->id_to_obj_tbl, rb_mmtk_update_obj_id_tables_id_to_obj_i, 0);
- }
-}
-
-static int
rb_mmtk_global_tables_count(void)
{
return RB_GC_VM_WEAK_TABLE_COUNT;
@@ -403,7 +362,6 @@ MMTk_RubyUpcalls ruby_upcalls = {
rb_mmtk_update_global_tables,
rb_mmtk_global_tables_count,
rb_mmtk_update_finalizer_table,
- rb_mmtk_update_obj_id_tables,
};
// Use max 80% of the available memory by default for MMTk
@@ -432,7 +390,6 @@ rb_gc_impl_objspace_alloc(void)
return calloc(1, sizeof(struct objspace));
}
-static void objspace_obj_id_init(struct objspace *objspace);
static void gc_run_finalizers(void *data);
void
@@ -442,8 +399,6 @@ rb_gc_impl_objspace_init(void *objspace_ptr)
objspace->measure_gc_time = true;
- objspace_obj_id_init(objspace);
-
objspace->finalizer_table = st_init_numtable();
objspace->finalizer_postponed_job = rb_postponed_job_preregister(0, gc_run_finalizers, objspace);
@@ -1069,111 +1024,6 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)
gc_run_finalizers(objspace);
}
-// Object ID
-static int
-object_id_cmp(st_data_t x, st_data_t y)
-{
- if (RB_TYPE_P(x, T_BIGNUM)) {
- return !rb_big_eql(x, y);
- }
- else {
- return x != y;
- }
-}
-
-static st_index_t
-object_id_hash(st_data_t n)
-{
- return FIX2LONG(rb_hash((VALUE)n));
-}
-
-#define OBJ_ID_INCREMENT (RUBY_IMMEDIATE_MASK + 1)
-#define OBJ_ID_INITIAL (OBJ_ID_INCREMENT)
-
-static const struct st_hash_type object_id_hash_type = {
- object_id_cmp,
- object_id_hash,
-};
-
-static void
-objspace_obj_id_init(struct objspace *objspace)
-{
- objspace->id_to_obj_tbl = NULL;
- objspace->obj_to_id_tbl = st_init_numtable();
- objspace->next_object_id = OBJ_ID_INITIAL;
-}
-
-VALUE
-rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
-{
- VALUE id;
- struct objspace *objspace = objspace_ptr;
-
- unsigned int lev = rb_gc_vm_lock();
- if (FL_TEST(obj, FL_SEEN_OBJ_ID)) {
- st_data_t val;
- if (st_lookup(objspace->obj_to_id_tbl, (st_data_t)obj, &val)) {
- id = (VALUE)val;
- }
- else {
- rb_bug("rb_gc_impl_object_id: FL_SEEN_OBJ_ID flag set but not found in table");
- }
- }
- else {
- RUBY_ASSERT(!st_lookup(objspace->obj_to_id_tbl, (st_data_t)obj, NULL));
-
- id = ULL2NUM(objspace->next_object_id);
- objspace->next_object_id += OBJ_ID_INCREMENT;
-
- st_insert(objspace->obj_to_id_tbl, (st_data_t)obj, (st_data_t)id);
- if (RB_UNLIKELY(objspace->id_to_obj_tbl)) {
- st_insert(objspace->id_to_obj_tbl, (st_data_t)id, (st_data_t)obj);
- }
- FL_SET(obj, FL_SEEN_OBJ_ID);
- }
- rb_gc_vm_unlock(lev);
-
- return id;
-}
-
-static int
-build_id_to_obj_i(st_data_t key, st_data_t value, st_data_t data)
-{
- st_table *id_to_obj_tbl = (st_table *)data;
- st_insert(id_to_obj_tbl, value, key);
- return ST_CONTINUE;
-}
-
-VALUE
-rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
-{
- struct objspace *objspace = objspace_ptr;
-
-
- unsigned int lev = rb_gc_vm_lock();
-
- if (!objspace->id_to_obj_tbl) {
- objspace->id_to_obj_tbl = st_init_table_with_size(&object_id_hash_type, st_table_size(objspace->obj_to_id_tbl));
- st_foreach(objspace->obj_to_id_tbl, build_id_to_obj_i, (st_data_t)objspace->id_to_obj_tbl);
- }
-
- VALUE obj;
- bool found = st_lookup(objspace->id_to_obj_tbl, object_id, &obj) && !rb_gc_impl_garbage_object_p(objspace, obj);
-
- rb_gc_vm_unlock(lev);
-
- if (found) {
- return obj;
- }
-
- if (rb_funcall(object_id, rb_intern(">="), 1, ULL2NUM(objspace->next_object_id))) {
- rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not an id value", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
- }
- else {
- rb_raise(rb_eRangeError, "%+"PRIsVALUE" is a recycled object", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
- }
-}
-
// Forking
void
@@ -1364,7 +1214,7 @@ rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj)
n++; \
} while (0)
- if (FL_TEST(obj, FL_SEEN_OBJ_ID)) SET_ENTRY(object_id, rb_obj_id(obj));
+ if (rb_obj_id_p(obj)) SET_ENTRY(object_id, rb_obj_id(obj));
object_metadata_entries[n].name = 0;
object_metadata_entries[n].val = 0;
diff --git a/gc/mmtk/mmtk.h b/gc/mmtk/mmtk.h
index 238781b1b9..72b4d9df03 100644
--- a/gc/mmtk/mmtk.h
+++ b/gc/mmtk/mmtk.h
@@ -68,7 +68,6 @@ typedef struct MMTk_RubyUpcalls {
void (*update_global_tables)(int tbl_idx);
int (*global_tables_count)(void);
void (*update_finalizer_table)(void);
- void (*update_obj_id_tables)(void);
} MMTk_RubyUpcalls;
typedef struct MMTk_RawVecOfObjRef {
diff --git a/gc/mmtk/src/abi.rs b/gc/mmtk/src/abi.rs
index 5414d87d68..c7a337ef35 100644
--- a/gc/mmtk/src/abi.rs
+++ b/gc/mmtk/src/abi.rs
@@ -322,7 +322,6 @@ pub struct RubyUpcalls {
pub update_global_tables: extern "C" fn(tbl_idx: c_int),
pub global_tables_count: extern "C" fn() -> c_int,
pub update_finalizer_table: extern "C" fn(),
- pub update_obj_id_tables: extern "C" fn(),
}
unsafe impl Sync for RubyUpcalls {}
diff --git a/gc/mmtk/src/weak_proc.rs b/gc/mmtk/src/weak_proc.rs
index 11f7f5abbf..77af5e2b85 100644
--- a/gc/mmtk/src/weak_proc.rs
+++ b/gc/mmtk/src/weak_proc.rs
@@ -185,7 +185,6 @@ struct UpdateFinalizerObjIdTables;
impl GlobalTableProcessingWork for UpdateFinalizerObjIdTables {
fn process_table(&mut self) {
(crate::upcalls().update_finalizer_table)();
- (crate::upcalls().update_obj_id_tables)();
}
}
impl GCWork<Ruby> for UpdateFinalizerObjIdTables {