зеркало из https://github.com/github/ruby.git
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:
Родитель
838031170c
Коммит
76e594d515
16
gc.c
16
gc.c
|
@ -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,6 +11230,8 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
|
|||
{
|
||||
rb_objspace_t *objspace = &rb_objspace;
|
||||
|
||||
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)) {
|
||||
|
@ -11240,6 +11246,8 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
|
|||
cr->mfd = prev_mfd;
|
||||
}
|
||||
}
|
||||
RB_VM_LOCK_LEAVE();
|
||||
}
|
||||
|
||||
struct root_objects_data {
|
||||
const char *category;
|
||||
|
|
Загрузка…
Ссылка в новой задаче