From: simonmar@microsoft.com Date: Wed, 30 Jan 2008 15:09:21 +0000 (+0000) Subject: memInventory: optionally dump the memory inventory X-Git-Tag: Before_cabalised-GHC~251 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=06f9b7c365fb9e9b53723f892b4d63b4f7a56e9a memInventory: optionally dump the memory inventory in addition to checking for leaks --- diff --git a/includes/Storage.h b/includes/Storage.h index 3b3bc1f..d545054 100644 --- a/includes/Storage.h +++ b/includes/Storage.h @@ -542,7 +542,7 @@ extern lnat countOccupied ( bdescr *bd ); extern lnat calcNeeded ( void ); #if defined(DEBUG) -extern void memInventory(void); +extern void memInventory(rtsBool show); extern void checkSanity(void); extern nat countBlocks(bdescr *); extern void checkNurserySanity( step *stp ); diff --git a/rts/sm/GC.c b/rts/sm/GC.c index fe26cf9..0d2ba85 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -214,11 +214,6 @@ GarbageCollect ( rtsBool force_major_gc ) stmPreGCHook(); #ifdef DEBUG - // check for memory leaks if DEBUG is on - memInventory(); -#endif - -#ifdef DEBUG mutlist_MUTVARS = 0; mutlist_MUTARRS = 0; mutlist_OTHERS = 0; @@ -266,6 +261,11 @@ GarbageCollect ( rtsBool force_major_gc ) } #endif +#ifdef DEBUG + // check for memory leaks if DEBUG is on + memInventory(traceClass(DEBUG_gc)); +#endif + // check stack sanity *before* GC (ToDo: check all threads) IF_DEBUG(sanity, checkFreeListSanity()); @@ -667,7 +667,7 @@ GarbageCollect ( rtsBool force_major_gc ) #ifdef DEBUG // check for memory leaks if DEBUG is on - memInventory(); + memInventory(traceClass(DEBUG_gc)); #endif #ifdef RTS_GTK_FRONTPANEL diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 8b3839f..a07685b 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -1173,7 +1173,7 @@ stepBlocks (step *stp) } void -memInventory(void) +memInventory (rtsBool show) { nat g, s, i; step *stp; @@ -1181,6 +1181,7 @@ memInventory(void) lnat nursery_blocks, retainer_blocks, arena_blocks, exec_blocks; lnat live_blocks = 0, free_blocks = 0; + rtsBool leak; // count the blocks we current have @@ -1224,20 +1225,36 @@ memInventory(void) live_blocks += nursery_blocks + + retainer_blocks + arena_blocks + exec_blocks; - if (live_blocks + free_blocks != mblocks_allocated * BLOCKS_PER_MBLOCK) +#define MB(n) (((n) * BLOCK_SIZE_W) / ((1024*1024)/sizeof(W_))) + + leak = live_blocks + free_blocks != mblocks_allocated * BLOCKS_PER_MBLOCK; + if (show || leak) { - debugBelch("Memory leak detected\n"); + if (leak) { + debugBelch("Memory leak detected:\n"); + } else { + debugBelch("Memory inventory:\n"); + } for (g = 0; g < RtsFlags.GcFlags.generations; g++) { - debugBelch(" gen %d blocks : %4lu\n", g, gen_blocks[g]); + debugBelch(" gen %d blocks : %5lu blocks (%lu MB)\n", g, + gen_blocks[g], MB(gen_blocks[g])); + } + debugBelch(" nursery : %5lu blocks (%lu MB)\n", + nursery_blocks, MB(nursery_blocks)); + debugBelch(" retainer : %5lu blocks (%lu MB)\n", + retainer_blocks, MB(retainer_blocks)); + debugBelch(" arena blocks : %5lu blocks (%lu MB)\n", + arena_blocks, MB(arena_blocks)); + debugBelch(" exec : %5lu blocks (%lu MB)\n", + exec_blocks, MB(exec_blocks)); + debugBelch(" free : %5lu blocks (%lu MB)\n", + free_blocks, MB(free_blocks)); + debugBelch(" total : %5lu blocks (%lu MB)\n", + live_blocks + free_blocks, MB(live_blocks+free_blocks)); + if (leak) { + debugBelch("\n in system : %5lu blocks (%lu MB)\n", + mblocks_allocated * BLOCKS_PER_MBLOCK, mblocks_allocated); } - debugBelch(" nursery : %4lu\n", nursery_blocks); - debugBelch(" retainer : %4lu\n", retainer_blocks); - debugBelch(" arena blocks : %4lu\n", arena_blocks); - debugBelch(" exec : %4lu\n", exec_blocks); - debugBelch(" free : %4lu\n", free_blocks); - debugBelch(" total : %4lu\n\n", live_blocks + free_blocks); - debugBelch(" in system : %4lu\n", mblocks_allocated * BLOCKS_PER_MBLOCK); - ASSERT(0); } }