Commit 06f9b7c3 authored by simonmar@microsoft.com's avatar simonmar@microsoft.com
Browse files

memInventory: optionally dump the memory inventory

in addition to checking for leaks
parent faafd34d
......@@ -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 );
......
......@@ -213,11 +213,6 @@ GarbageCollect ( rtsBool force_major_gc )
// tell the STM to discard any cached closures it's hoping to re-use
stmPreGCHook();
#ifdef DEBUG
// check for memory leaks if DEBUG is on
memInventory();
#endif
#ifdef DEBUG
mutlist_MUTVARS = 0;
mutlist_MUTARRS = 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
......
......@@ -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);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment