From 9ff64fc6ed67938e6ec7d37bee612e71f91ba7fa Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Apr 2016 10:29:07 -0600 Subject: [PATCH] GC: guard against excessive fragmentation in incremental mode Although excessive fragmentation is already detected at the end of a major GC, it can get out of hand already during a long incremental phase. So, check for excessive fragmentation and bail out to a major GC when it happens. Related to PR 15287 --- racket/src/racket/gc2/newgc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 6270d4f529..22080fe2f4 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -5349,7 +5349,13 @@ static void garbage_collect(NewGC *gc, int force_full, int no_full, && !gc->started_incremental) /* In incremental mode, GC earlier if we've done everything that we can do incrementally. */ - || gc->accounted_incremental); + || gc->accounted_incremental + /* Give up on incremental mode if fragmentation is + getting out of hand: */ + || (gc->started_incremental + && (gc->memory_in_use > GEN0_MAX_SIZE) + && (mmu_memory_allocated_and_used(gc->mmu) + > (HIGH_FRAGMENTATION_RATIO * gc->memory_in_use)))); if (gc->gc_full && no_full) return;