diff options
Diffstat (limited to 'rts/sm/Storage.c')
| -rw-r--r-- | rts/sm/Storage.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 541da5df1c..e5258c2517 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -78,6 +78,7 @@ initGeneration (generation *gen, int g) gen->n_old_blocks = 0; gen->large_objects = NULL; gen->n_large_blocks = 0; + gen->n_large_words = 0; gen->n_new_large_words = 0; gen->scavenged_large_objects = NULL; gen->n_scavenged_large_blocks = 0; @@ -437,16 +438,12 @@ allocNursery (bdescr *tail, W_ blocks) // tiny optimisation (~0.5%), but it's free. while (blocks > 0) { - if (blocks >= BLOCKS_PER_MBLOCK / 4) { - n = stg_min(BLOCKS_PER_MBLOCK, blocks); - bd = allocLargeChunk(16, n); // see comment with allocLargeChunk() - // NB. we want a nice power of 2 for the minimum here - n = bd->blocks; - } else { - bd = allocGroup(blocks); - n = blocks; - } - + n = stg_min(BLOCKS_PER_MBLOCK, blocks); + // allocLargeChunk will prefer large chunks, but will pick up + // small chunks if there are any available. We must allow + // single blocks here to avoid fragmentation (#7257) + bd = allocLargeChunk(1, n); + n = bd->blocks; blocks -= n; for (i = 0; i < n; i++) { @@ -767,6 +764,7 @@ allocatePinned (Capability *cap, W_ n) // g0->large_objects. if (bd != NULL) { dbl_link_onto(bd, &cap->pinned_object_blocks); + cap->total_allocated += bd->free - bd->start; } // We need to find another block. We could just allocate one, @@ -955,7 +953,7 @@ W_ countOccupied (bdescr *bd) W_ genLiveWords (generation *gen) { - return gen->n_words + countOccupied(gen->large_objects); + return gen->n_words + gen->n_large_words; } W_ genLiveBlocks (generation *gen) |
