Skip to content

Commit bbbe07a

Browse files
committed
Speed up finalizers for objects without object ID
If the object being finalized does not have an object ID, then we don't need to insert into the object ID table, we can simply just allocate a new object ID by bumping the next_object_id counter. This speeds up finalization for objects that don't have an object ID. For example, the following script now runs faster: 1_000_000.times do o = Object.new ObjectSpace.define_finalizer(o) {} end Before: Time (mean ± σ): 1.462 s ± 0.019 s [User: 1.360 s, System: 0.094 s] Range (min … max): 1.441 s … 1.503 s 10 runs After: Time (mean ± σ): 1.199 s ± 0.015 s [User: 1.103 s, System: 0.086 s] Range (min … max): 1.181 s … 1.229 s 10 runs
1 parent 703305b commit bbbe07a

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

gc/default.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,6 +3045,19 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
30453045
}
30463046
}
30473047

3048+
static VALUE
3049+
get_object_id_in_finalizer(rb_objspace_t *objspace, VALUE obj)
3050+
{
3051+
if (FL_TEST(obj, FL_SEEN_OBJ_ID)) {
3052+
return rb_gc_impl_object_id(objspace, obj);
3053+
}
3054+
else {
3055+
VALUE id = ULL2NUM(objspace->next_object_id);
3056+
objspace->next_object_id += OBJ_ID_INCREMENT;
3057+
return id;
3058+
}
3059+
}
3060+
30483061
static VALUE
30493062
get_final(long i, void *data)
30503063
{
@@ -3065,7 +3078,7 @@ run_final(rb_objspace_t *objspace, VALUE zombie)
30653078
FL_UNSET(zombie, FL_FINALIZE);
30663079
st_data_t table;
30673080
if (st_delete(finalizer_table, &key, &table)) {
3068-
rb_gc_run_obj_finalizer(rb_gc_impl_object_id(objspace, zombie), RARRAY_LEN(table), get_final, (void *)table);
3081+
rb_gc_run_obj_finalizer(get_object_id_in_finalizer(objspace, zombie), RARRAY_LEN(table), get_final, (void *)table);
30693082
}
30703083
else {
30713084
rb_bug("FL_FINALIZE flag is set, but finalizers are not found");
@@ -3248,7 +3261,7 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)
32483261
while (list) {
32493262
struct force_finalize_list *curr = list;
32503263

3251-
rb_gc_run_obj_finalizer(rb_gc_impl_object_id(objspace, curr->obj), RARRAY_LEN(curr->table), get_final, (void *)curr->table);
3264+
rb_gc_run_obj_finalizer(get_object_id_in_finalizer(objspace, curr->obj), RARRAY_LEN(curr->table), get_final, (void *)curr->table);
32523265

32533266
st_data_t obj = (st_data_t)curr->obj;
32543267
st_delete(finalizer_table, &obj, 0);

0 commit comments

Comments
 (0)