X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FBlockAlloc.c;h=280ebfc7dbdfb94bbe3f5757771572916b34fe8d;hb=1c45176f3b9be75b5c4744d9ef074430bf034e3f;hp=81baf6c19694d7ff2b989a1a5e82112b13a81f48;hpb=a57e55b095c48d8ca27b2ec13f4d138655618577;p=ghc-hetmet.git diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c index 81baf6c..280ebfc 100644 --- a/rts/sm/BlockAlloc.c +++ b/rts/sm/BlockAlloc.c @@ -565,6 +565,9 @@ freeChain_lock(bdescr *bd) RELEASE_SM_LOCK; } +// splitBlockGroup(bd,B) splits bd in two. Afterward, bd will have B +// blocks, and a new block descriptor pointing to the remainder is +// returned. bdescr * splitBlockGroup (bdescr *bd, nat blocks) { @@ -575,16 +578,21 @@ splitBlockGroup (bdescr *bd, nat blocks) } if (bd->blocks > BLOCKS_PER_MBLOCK) { - nat mblocks; + nat low_mblocks, high_mblocks; void *new_mblock; if ((blocks - BLOCKS_PER_MBLOCK) % (MBLOCK_SIZE / BLOCK_SIZE) != 0) { barf("splitLargeBlock: not a multiple of a megablock"); } - mblocks = 1 + (blocks - BLOCKS_PER_MBLOCK) / (MBLOCK_SIZE / BLOCK_SIZE); - new_mblock = (void *) ((P_)MBLOCK_ROUND_DOWN(bd) + mblocks * MBLOCK_SIZE_W); + low_mblocks = 1 + (blocks - BLOCKS_PER_MBLOCK) / (MBLOCK_SIZE / BLOCK_SIZE); + high_mblocks = (bd->blocks - blocks) / (MBLOCK_SIZE / BLOCK_SIZE); + + new_mblock = (void *) ((P_)MBLOCK_ROUND_DOWN(bd) + low_mblocks * MBLOCK_SIZE_W); initMBlock(new_mblock); new_bd = FIRST_BDESCR(new_mblock); - new_bd->blocks = MBLOCK_GROUP_BLOCKS(mblocks); + new_bd->blocks = MBLOCK_GROUP_BLOCKS(high_mblocks); + + ASSERT(blocks + new_bd->blocks == + bd->blocks + BLOCKS_PER_MBLOCK - MBLOCK_SIZE/BLOCK_SIZE); } else { @@ -727,4 +735,36 @@ countFreeList(void) } return total_blocks; } + +void +markBlocks (bdescr *bd) +{ + for (; bd != NULL; bd = bd->link) { + bd->flags |= BF_KNOWN; + } +} + +void +reportUnmarkedBlocks (void) +{ + void *mblock; + bdescr *bd; + + debugBelch("Unreachable blocks:\n"); + for (mblock = getFirstMBlock(); mblock != NULL; + mblock = getNextMBlock(mblock)) { + for (bd = FIRST_BDESCR(mblock); bd <= LAST_BDESCR(mblock); ) { + if (!(bd->flags & BF_KNOWN) && bd->free != (P_)-1) { + debugBelch(" %p\n",bd); + } + if (bd->blocks >= BLOCKS_PER_MBLOCK) { + mblock += (BLOCKS_TO_MBLOCKS(bd->blocks) - 1) * MBLOCK_SIZE; + break; + } else { + bd += bd->blocks; + } + } + } +} + #endif