From fa3cabd6814866cacd00218cf132b33f21d51e6f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Nov 2015 10:21:37 -0700 Subject: [PATCH] incremental GC: avoid allocating immobile on old-generation page The allocation strategy for immobile objects avoids some fragmentation in non-incremental mode, but it interferes with finishing up an incremental major collection, so trade some fragmentation for an earlier finish (which is far more likely to use less memory instead of more, despite extra fragmentation). --- racket/src/racket/gc2/newgc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 8fa4ac7f22..c78bb6020f 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -2692,6 +2692,7 @@ static void push_ptr(NewGC *gc, void *ptr, int inc_gen1) #endif GC_ASSERT(inc_gen1 || !gc->inc_gen1); + GC_ASSERT(!inc_gen1 || !gc->finishing_incremental); push_ptr_at(ptr, inc_gen1 ? &gc->inc_mark_stack : &gc->mark_stack); } @@ -5501,7 +5502,11 @@ static void clean_up_heap(NewGC *gc) next = NULL; } } - gc->med_freelist_pages[ty][i] = prev; + if (gc->finishing_incremental) { + /* no more allocation on old pages */ + gc->med_freelist_pages[ty][i] = NULL; + } else + gc->med_freelist_pages[ty][i] = prev; } } @@ -5832,6 +5837,8 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin if (gc->full_needed_for_finalization && gc->gc_full) gc->full_needed_for_finalization= 0; + if (gc->gc_full) + gc->finishing_incremental = 0; #ifdef GC_DEBUG_PAGES if (gc->gc_full == 1) { @@ -5984,7 +5991,9 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, int switchin TIME_STEP("repaired"); if (check_inc_repair) { if (!gc->inc_repair_next) { - /* Didn't fire a full GC? Go back to incremental marking: */ + /* Didn't fire a full GC? This shouldn't happend, but if it + does, go back to incremental marking: */ + GC_ASSERT(gc->gc_full); gc->finishing_incremental = 0; } else { int fuel = (no_full