diff options
author | simonmar@microsoft.com <unknown> | 2008-02-28 15:31:29 +0000 |
---|---|---|
committer | simonmar@microsoft.com <unknown> | 2008-02-28 15:31:29 +0000 |
commit | fac738e582dcaca1575f5291c83910db01d25284 (patch) | |
tree | 5c7645efcad551108137593e4cb19df259b4b7d4 /includes/Block.h | |
parent | 75927bb04bccb3ada850641939f0842a4168968a (diff) | |
download | haskell-fac738e582dcaca1575f5291c83910db01d25284.tar.gz |
Release some of the memory allocated to a stack when it shrinks (#2090)
When a stack is occupying less than 1/4 of the memory it owns, and is
larger than a megablock, we release half of it. Shrinking is O(1), it
doesn't need to copy the stack.
Diffstat (limited to 'includes/Block.h')
-rw-r--r-- | includes/Block.h | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/includes/Block.h b/includes/Block.h index 7721765147..112092c5c4 100644 --- a/includes/Block.h +++ b/includes/Block.h @@ -227,21 +227,30 @@ void freeChain(bdescr *p); void freeGroup_lock(bdescr *p); void freeChain_lock(bdescr *p); -/* Round a value to megablocks --------------------------------------------- */ +bdescr * splitBlockGroup (bdescr *bd, nat blocks); -#define WORDS_PER_MBLOCK (BLOCKS_PER_MBLOCK * BLOCK_SIZE_W) +/* Round a value to megablocks --------------------------------------------- */ +// We want to allocate an object around a given size, round it up or +// down to the nearest size that will fit in an mblock group. INLINE_HEADER StgWord round_to_mblocks(StgWord words) { - if (words > WORDS_PER_MBLOCK) { - if ((words % WORDS_PER_MBLOCK) < (WORDS_PER_MBLOCK / 2)) { - words = (words / WORDS_PER_MBLOCK) * WORDS_PER_MBLOCK; - } else { - words = ((words / WORDS_PER_MBLOCK) + 1) * WORDS_PER_MBLOCK; + if (words > BLOCKS_PER_MBLOCK * BLOCK_SIZE_W) { + // first, ignore the gap at the beginning of the first mblock by + // adding it to the total words. Then we can pretend we're + // dealing in a uniform unit of megablocks. + words += FIRST_BLOCK_OFF/sizeof(W_); + + if ((words % MBLOCK_SIZE_W) < (MBLOCK_SIZE_W / 2)) { + words = (words / MBLOCK_SIZE_W) * MBLOCK_SIZE_W; + } else { + words = ((words / MBLOCK_SIZE_W) + 1) * MBLOCK_SIZE_W; + } + + words -= FIRST_BLOCK_OFF/sizeof(W_); } - } - return words; + return words; } #endif /* !CMINUSMINUS */ |