GC: use generation 1/2 consistently within a collection

The rule for using generation 1/2is based on the current
memory use versus the maximum size of generation 0. Recent
changes to the GC have caused that size to vary during
a collection, which means that the choice to use generation
1/2 or not can change within a collection.

Partial use of generation 1/2 doesn't inherently cause problems, but
it can cause a generation-1 object to point to a generation-1/2 object
even though the former was allocated after the latter. That's a
problem on if getting generations out of order relative to allocation
order can create problems. As it happens, reset_finalizer_tree()
checks the generation of the finalization record and not the finalized
pointer, because the record is always allocated after the pointer.

Merge to v6.3
This commit is contained in:
Matthew Flatt 2015-10-15 15:57:44 -06:00
parent 03bf7d3def
commit 6199f9a596
2 changed files with 4 additions and 1 deletions

View File

@ -3580,7 +3580,7 @@ void GC_mark2(void *pp, struct NewGC *gc)
size = gcWORDS_TO_BYTES(ohead->size);
if (AGE_GEN_0_TO_GEN_HALF(gc) && (page->generation == AGE_GEN_0) && !gc->gc_full) {
if (gc->use_gen_half && (page->generation == AGE_GEN_0)) {
/* move to generation 1/2 */
work = gc->gen_half.curr_alloc_page;
if (!work || (work->size + size > GEN0_PAGE_SIZE)) {
@ -5023,6 +5023,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin
gc->in_unsafe_allocation_mode = 1;
gc->unsafe_allocation_abort = out_of_memory_gc;
gc->use_gen_half = !gc->gc_full && AGE_GEN_0_TO_GEN_HALF(gc);
if (gc->gc_full)
gc->phantom_count = 0;
else if (gc->memory_in_use > gc->phantom_count) {

View File

@ -193,6 +193,7 @@ typedef struct NewGC {
unsigned char full_needed_for_finalization :1;
unsigned char no_further_modifications :1;
unsigned char gc_full :1; /* a flag saying if this is a full/major collection */
unsigned char use_gen_half :1;
unsigned char running_finalizers :1;
unsigned char back_pointers :1;
unsigned char need_fixup :1;