fix some shutdown memory leaks
[ghc-hetmet.git] / rts / sm / MBlock.c
index b3fa13b..b9d71f6 100644 (file)
@@ -9,16 +9,16 @@
  * ---------------------------------------------------------------------------*/
 
 #include "PosixSource.h"
-
 #include "Rts.h"
+
 #include "RtsUtils.h"
-#include "MBlock.h"
 #include "BlockAlloc.h"
 #include "Trace.h"
 #include "OSMem.h"
 
 #include <string.h>
 
+lnat peak_mblocks_allocated = 0;
 lnat mblocks_allocated = 0;
 lnat mpc_misses = 0;
 
@@ -30,9 +30,9 @@ lnat mpc_misses = 0;
 StgWord8 mblock_map[MBLOCK_MAP_SIZE]; // initially all zeros
 
 static void
-markHeapAlloced(void *p)
+setHeapAlloced(void *p, StgWord8 i)
 {
-    mblock_map[MBLOCK_MAP_ENTRY(p)] = 1;
+    mblock_map[MBLOCK_MAP_ENTRY(p)] = i;
 }
 
 #elif SIZEOF_VOID_P == 8
@@ -82,21 +82,22 @@ StgBool HEAP_ALLOCED_miss(StgWord mblock, void *p)
 }
 
 static void
-markHeapAlloced(void *p)
+setHeapAlloced(void *p, StgWord8 i)
 {
     MBlockMap *map = findMBlockMap(p);
     if(map == NULL)
     {
        mblock_map_count++;
-       mblock_maps = realloc(mblock_maps,
-                             sizeof(MBlockMap*) * mblock_map_count);
+       mblock_maps = stgReallocBytes(mblock_maps,
+                                      sizeof(MBlockMap*) * mblock_map_count,
+                                      "markHeapAlloced(1)");
        map = mblock_maps[mblock_map_count-1] = 
-            stgMallocBytes(sizeof(MBlockMap),"markHeapAlloced");
+            stgMallocBytes(sizeof(MBlockMap),"markHeapAlloced(2)");
         memset(map,0,sizeof(MBlockMap));
        map->addrHigh32 = (StgWord32) (((StgWord)p) >> 32);
     }
 
-    map->lines[MBLOCK_MAP_LINE(p)] = 1;
+    map->lines[MBLOCK_MAP_LINE(p)] = i;
 
     {
         StgWord mblock;
@@ -104,19 +105,22 @@ markHeapAlloced(void *p)
         
         mblock   = (StgWord)p >> MBLOCK_SHIFT;
         entry_no = mblock & (MBC_ENTRIES-1);
-        mblock_cache[entry_no] = (mblock << 1) + 1;
+        mblock_cache[entry_no] = (mblock << 1) + i;
     }
 }
 #endif
 
-/* ----------------------------------------------------------------------------
-   Debugging code for traversing the allocated MBlocks
-   
-   This is used for searching for lost blocks when a memory leak is
-   detected; see Blocks.c:findUnmarkedBlock().
-   ------------------------------------------------------------------------ */
+static void
+markHeapAlloced(void *p)
+{
+    setHeapAlloced(p, 1);
+}
 
-#ifdef DEBUG
+static void
+markHeapUnalloced(void *p)
+{
+    setHeapAlloced(p, 0);
+}
 
 #if SIZEOF_VOID_P == 4
 
@@ -208,8 +212,6 @@ void * getFirstMBlock(void)
 
 #endif // SIZEOF_VOID_P
 
-#endif // DEBUG
-
 /* -----------------------------------------------------------------------------
    Allocate new mblock(s)
    -------------------------------------------------------------------------- */
@@ -235,18 +237,44 @@ getMBlocks(nat n)
     
     // fill in the table
     for (i = 0; i < n; i++) {
-        markHeapAlloced( ret + i * MBLOCK_SIZE );
+        markHeapAlloced( (StgWord8*)ret + i * MBLOCK_SIZE );
     }
     
     mblocks_allocated += n;
+    peak_mblocks_allocated = stg_max(peak_mblocks_allocated, mblocks_allocated);
 
     return ret;
 }
 
 void
+freeMBlocks(void *addr, nat n)
+{
+    nat i;
+
+    debugTrace(DEBUG_gc, "freeing %d megablock(s) at %p",n,addr);
+
+    mblocks_allocated -= n;
+
+    for (i = 0; i < n; i++) {
+        markHeapUnalloced( (StgWord8*)addr + i * MBLOCK_SIZE );
+    }
+
+    osFreeMBlocks(addr, n);
+}
+
+void
 freeAllMBlocks(void)
 {
+    nat n;
+
+    debugTrace(DEBUG_gc, "freeing all megablocks");
+
     osFreeAllMBlocks();
+
+    for (n = 0; n < mblock_map_count; n++) {
+        stgFree(mblock_maps[n]);
+    }
+    stgFree(mblock_maps);
 }
 
 void