Skip to content

Commit 057d7c1

Browse files
committed
object_id_to_ref: complete incremental GC before iterating
Otherwise dealing with garbage objects is tricky.
1 parent e4b386e commit 057d7c1

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

gc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,6 @@ rb_gc_pointer_to_heap_p(VALUE obj)
17551755
#define LAST_OBJECT_ID() (object_id_counter * OBJ_ID_INCREMENT)
17561756
static VALUE id2ref_value = 0;
17571757
static st_table *id2ref_tbl = NULL;
1758-
static bool id2ref_tbl_built = false;
17591758

17601759
#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
17611760
static size_t object_id_counter = 1;
@@ -1947,6 +1946,7 @@ build_id2ref_i(VALUE obj, void *data)
19471946
case T_CLASS:
19481947
case T_MODULE:
19491948
if (RCLASS(obj)->object_id) {
1949+
RUBY_ASSERT(!rb_objspace_garbage_object_p(obj));
19501950
st_insert(id2ref_tbl, RCLASS(obj)->object_id, obj);
19511951
}
19521952
break;
@@ -1955,6 +1955,7 @@ build_id2ref_i(VALUE obj, void *data)
19551955
break;
19561956
default:
19571957
if (rb_shape_obj_has_id(obj)) {
1958+
RUBY_ASSERT(!rb_objspace_garbage_object_p(obj));
19581959
st_insert(id2ref_tbl, rb_obj_id(obj), obj);
19591960
}
19601961
break;
@@ -1979,12 +1980,12 @@ object_id_to_ref(void *objspace_ptr, VALUE object_id)
19791980

19801981
// build_id2ref_i will most certainly malloc, which could trigger GC and sweep
19811982
// objects we just added to the table.
1982-
bool gc_disabled = RTEST(rb_gc_disable_no_rest());
1983+
// By calling rb_gc_disable() we also save having to handle potentially garbage objects.
1984+
bool gc_disabled = RTEST(rb_gc_disable());
19831985
{
19841986
rb_gc_impl_each_object(objspace, build_id2ref_i, (void *)id2ref_tbl);
19851987
}
19861988
if (!gc_disabled) rb_gc_enable();
1987-
id2ref_tbl_built = true;
19881989
}
19891990

19901991
VALUE obj;
@@ -2036,10 +2037,9 @@ obj_free_object_id(VALUE obj)
20362037
RUBY_ASSERT(FIXNUM_P(obj_id) || RB_TYPE_P(obj_id, T_BIGNUM));
20372038

20382039
if (!st_delete(id2ref_tbl, (st_data_t *)&obj_id, NULL)) {
2039-
// If we're currently building the table then it's not a bug.
20402040
// The the object is a T_IMEMO/fields, then it's possible the actual object
20412041
// has been garbage collected already.
2042-
if (id2ref_tbl_built && !RB_TYPE_P(obj, T_IMEMO)) {
2042+
if (!RB_TYPE_P(obj, T_IMEMO)) {
20432043
rb_bug("Object ID seen, but not in _id2ref table: object_id=%llu object=%s", NUM2ULL(obj_id), rb_obj_info(obj));
20442044
}
20452045
}

0 commit comments

Comments
 (0)