1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

fix GC event synchronization

(1) gc_verify_internal_consistency() use barrier locking
    for consistency while `during_gc == true` at the end
    of the sweep on `RGENGC_CHECK_MODE >= 2`.
(2) `rb_objspace_reachable_objects_from()` is called without
    VM synchronization and it checks `during_gc != true`.

So (1) and (2) causes BUG because of `during_gc == true`.
To prevent this error, wait for VM barrier on `during_gc == false`
and introduce VM locking on `rb_objspace_reachable_objects_from()`.

http://ci.rvm.jp/results/trunk-asserts@phosphorus-docker/3830088
This commit is contained in:
Koichi Sasada 2022-02-14 16:10:18 +09:00
parent 838031170c
commit 76e594d515
Notes: git 2022-02-14 17:18:15 +09:00

36
gc.c
View file

@ -5722,10 +5722,6 @@ gc_sweep_finish(rb_objspace_t *objspace)
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
gc_mode_transition(objspace, gc_mode_none);
#if RGENGC_CHECK_MODE >= 2
gc_verify_internal_consistency(objspace);
#endif
}
static int
@ -9340,6 +9336,14 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l
mjit_gc_exit_hook();
gc_exit_clock(objspace, event);
RB_VM_LOCK_LEAVE_LEV(lock_lev);
#if RGENGC_CHECK_MODE >= 2
if (event == gc_enter_event_sweep_continue && gc_mode(objspace) == gc_mode_none) {
GC_ASSERT(!during_gc);
// sweep finished
gc_verify_internal_consistency(objspace);
}
#endif
}
static void *
@ -11226,19 +11230,23 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
{
rb_objspace_t *objspace = &rb_objspace;
if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
RB_VM_LOCK_ENTER();
{
if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
if (is_markable_object(objspace, obj)) {
rb_ractor_t *cr = GET_RACTOR();
struct gc_mark_func_data_struct mfd = {
.mark_func = func,
.data = data,
}, *prev_mfd = cr->mfd;
if (is_markable_object(objspace, obj)) {
rb_ractor_t *cr = GET_RACTOR();
struct gc_mark_func_data_struct mfd = {
.mark_func = func,
.data = data,
}, *prev_mfd = cr->mfd;
cr->mfd = &mfd;
gc_mark_children(objspace, obj);
cr->mfd = prev_mfd;
cr->mfd = &mfd;
gc_mark_children(objspace, obj);
cr->mfd = prev_mfd;
}
}
RB_VM_LOCK_LEAVE();
}
struct root_objects_data {