Skip to content

Commit ba52af6

Browse files
committed
Always set parent_object in GC
When we mark a T_NONE, we crash with the object and parent object information in the bug report. However, if the parent object is young then it is Qfalse. For example, a bug report looks like: [BUG] try to mark T_NONE object (obj: 0x00003990e42d7c70 T_NONE/, parent: (none)) This commit changes it to always set the parent object and also adds a new field parent_object_old_p to quickly determine if the parent object is old or not.
1 parent 88dc3c4 commit ba52af6

File tree

1 file changed

+12
-29
lines changed

1 file changed

+12
-29
lines changed

gc/default/default.c

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,9 @@ typedef struct rb_objspace {
577577
VALUE gc_stress_mode;
578578

579579
struct {
580+
bool parent_object_old_p;
580581
VALUE parent_object;
582+
581583
int need_major_gc;
582584
size_t last_major_gc;
583585
size_t uncollectible_wb_unprotected_objects;
@@ -4309,15 +4311,11 @@ init_mark_stack(mark_stack_t *stack)
43094311
static void
43104312
rgengc_check_relation(rb_objspace_t *objspace, VALUE obj)
43114313
{
4312-
const VALUE old_parent = objspace->rgengc.parent_object;
4313-
4314-
if (old_parent) { /* parent object is old */
4314+
if (objspace->rgengc.parent_object_old_p) {
43154315
if (RVALUE_WB_UNPROTECTED(objspace, obj) || !RVALUE_OLD_P(objspace, obj)) {
4316-
rgengc_remember(objspace, old_parent);
4316+
rgengc_remember(objspace, objspace->rgengc.parent_object);
43174317
}
43184318
}
4319-
4320-
GC_ASSERT(old_parent == objspace->rgengc.parent_object);
43214319
}
43224320

43234321
static inline int
@@ -4385,12 +4383,7 @@ gc_mark_check_t_none(rb_objspace_t *objspace, VALUE obj)
43854383
rb_raw_obj_info(obj_info_buf, info_size, obj);
43864384

43874385
char parent_obj_info_buf[info_size];
4388-
if (objspace->rgengc.parent_object == Qfalse) {
4389-
strlcpy(parent_obj_info_buf, "(none)", info_size);
4390-
}
4391-
else {
4392-
rb_raw_obj_info(parent_obj_info_buf, info_size, objspace->rgengc.parent_object);
4393-
}
4386+
rb_raw_obj_info(parent_obj_info_buf, info_size, objspace->rgengc.parent_object);
43944387

43954388
rb_bug("try to mark T_NONE object (obj: %s, parent: %s)", obj_info_buf, parent_obj_info_buf);
43964389
}
@@ -4405,14 +4398,9 @@ gc_mark(rb_objspace_t *objspace, VALUE obj)
44054398
if (!gc_mark_set(objspace, obj)) return; /* already marked */
44064399

44074400
if (0) { // for debug GC marking miss
4408-
if (objspace->rgengc.parent_object) {
4409-
RUBY_DEBUG_LOG("%p (%s) parent:%p (%s)",
4410-
(void *)obj, obj_type_name(obj),
4411-
(void *)objspace->rgengc.parent_object, obj_type_name(objspace->rgengc.parent_object));
4412-
}
4413-
else {
4414-
RUBY_DEBUG_LOG("%p (%s)", (void *)obj, obj_type_name(obj));
4415-
}
4401+
RUBY_DEBUG_LOG("%p (%s) parent:%p (%s)",
4402+
(void *)obj, obj_type_name(obj),
4403+
(void *)objspace->rgengc.parent_object, obj_type_name(objspace->rgengc.parent_object));
44164404
}
44174405

44184406
gc_mark_check_t_none(objspace, obj);
@@ -4505,8 +4493,6 @@ rb_gc_impl_mark_weak(void *objspace_ptr, VALUE *ptr)
45054493
{
45064494
rb_objspace_t *objspace = objspace_ptr;
45074495

4508-
GC_ASSERT(objspace->rgengc.parent_object == 0 || !RVALUE_WB_UNPROTECTED(objspace, objspace->rgengc.parent_object));
4509-
45104496
VALUE obj = *ptr;
45114497

45124498
gc_mark_check_t_none(objspace, obj);
@@ -4565,7 +4551,8 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)
45654551
} while (0)
45664552

45674553
MARK_CHECKPOINT("objspace");
4568-
objspace->rgengc.parent_object = Qfalse;
4554+
objspace->rgengc.parent_object = Qundef;
4555+
objspace->rgengc.parent_object_old_p = false;
45694556

45704557
if (finalizer_table != NULL) {
45714558
st_foreach(finalizer_table, pin_value, (st_data_t)objspace);
@@ -4580,12 +4567,8 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)
45804567
static inline void
45814568
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
45824569
{
4583-
if (RVALUE_OLD_P(objspace, obj)) {
4584-
objspace->rgengc.parent_object = obj;
4585-
}
4586-
else {
4587-
objspace->rgengc.parent_object = Qfalse;
4588-
}
4570+
objspace->rgengc.parent_object = obj;
4571+
objspace->rgengc.parent_object_old_p = RVALUE_OLD_P(objspace, obj);
45894572
}
45904573

45914574
static void

0 commit comments

Comments
 (0)