diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-09-21 13:11:22 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-09-21 13:46:47 +0100 |
commit | 1f5d83648dfda39d999eb8a9e8192339b3eea540 (patch) | |
tree | 257b9a2b5f4d38706bce47dc017128ebea35b431 /rts/sm/Storage.c | |
parent | a17da16f08ae24e24ebe671d0731c43b240008f5 (diff) | |
download | haskell-1f5d83648dfda39d999eb8a9e8192339b3eea540.tar.gz |
Allow allocNursery() to allocate single blocks (#7257)
Forcing large allocations here can creates serious fragmentation in
some cases, and since the large allocations are only a small
optimisation we should allow the nursery to hoover up small blocks
before allocating large chunks.
Diffstat (limited to 'rts/sm/Storage.c')
-rw-r--r-- | rts/sm/Storage.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 541da5df1c..755c65427c 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -437,16 +437,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++) { |