From 6bd49b33c859e3893318b8ceb1f3e0dd0988144f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 3 Jul 2019 13:52:51 +0100 Subject: [PATCH] Ensure that GC is disabled during compaction Various things can cause GC to occur when compaction is running, for example resizing the object identity map: ``` frame #24: 0x000000010c784a10 ruby`gc_grey [inlined] push_mark_stack(stack=, data=) at gc.c:4311:42 frame #25: 0x000000010c7849ff ruby`gc_grey(objspace=0x00007fc56c804400, obj=140485906037400) at gc.c:4907 frame #26: 0x000000010c78f881 ruby`gc_start at gc.c:6464:8 frame #27: 0x000000010c78f5d1 ruby`gc_start [inlined] gc_marks_start(objspace=0x00007fc56c804400, full_mark=) at gc.c:6009 frame #28: 0x000000010c78f3c0 ruby`gc_start at gc.c:6291 frame #29: 0x000000010c78f399 ruby`gc_start(objspace=0x00007fc56c804400, reason=) at gc.c:7104 frame #30: 0x000000010c78930c ruby`objspace_xmalloc0 [inlined] objspace_malloc_fixup(objspace=, mem=0x000000011372a000, size=) at gc.c:9665:5 frame #31: 0x000000010c7892f5 ruby`objspace_xmalloc0(objspace=0x00007fc56c804400, size=12582912) at gc.c:9707 frame #32: 0x000000010c89bc13 ruby`st_init_table_with_size(type=, size=) at st.c:605:39 frame #33: 0x000000010c89c5e2 ruby`rebuild_table_if_necessary [inlined] rebuild_table(tab=0x00007fc56c40b250) at st.c:780:19 frame #34: 0x000000010c89c5ac ruby`rebuild_table_if_necessary(tab=0x00007fc56c40b250) at st.c:1142 frame #35: 0x000000010c89c379 ruby`st_insert(tab=0x00007fc56c40b250, key=140486132605040, value=140485922918920) at st.c:1161:5 frame #36: 0x000000010c794a16 ruby`gc_compact_heap [inlined] gc_move(objspace=0x00007fc56c804400, scan=, free=, moved_list=140485922918960) at gc.c:7441:9 frame #37: 0x000000010c794917 ruby`gc_compact_heap(objspace=0x00007fc56c804400, comparator=) at gc.c:7695 frame #38: 0x000000010c79410d ruby`gc_compact [inlined] gc_compact_after_gc(objspace=0x00007fc56c804400, use_toward_empty=1, use_double_pages=, use_verifier=1) at gc.c:0:22 ``` We *definitely* need the heap to be in a consistent state during compaction, so this commit sets the current state to "during_gc" so that nothing will trigger a GC until the heap finishes compacting. This fixes the bug we saw when running the tests for https://github.com/ruby/ruby/pull/2264 --- gc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gc.c b/gc.c index 7c652aaa1d..a12a3fa70f 100644 --- a/gc.c +++ b/gc.c @@ -8260,7 +8260,9 @@ gc_compact(rb_objspace_t *objspace, int use_toward_empty, int use_double_pages, /* pin objects referenced by maybe pointers */ rb_gc(); /* compact */ + during_gc = TRUE; gc_compact_after_gc(objspace, use_toward_empty, use_double_pages, TRUE); + during_gc = FALSE; } objspace->flags.during_compacting = FALSE; return gc_compact_stats(objspace);