summaryrefslogtreecommitdiff
path: root/rts/sm/MBlock.c
diff options
context:
space:
mode:
authorIan Lynagh <igloo@earth.li>2010-08-13 17:04:02 +0000
committerIan Lynagh <igloo@earth.li>2010-08-13 17:04:02 +0000
commit3fb074b5fcfd91fe0d37af83f221450ac4734908 (patch)
treece49021f2f6411643cfc261b79bbb73e4ea1ff1c /rts/sm/MBlock.c
parent429dc9a048f5533143fb5c9908b09d3155496e9b (diff)
downloadhaskell-3fb074b5fcfd91fe0d37af83f221450ac4734908.tar.gz
Return memory to the OS; trac #698
Diffstat (limited to 'rts/sm/MBlock.c')
-rw-r--r--rts/sm/MBlock.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/rts/sm/MBlock.c b/rts/sm/MBlock.c
index 996b2c9ae9..53172753f1 100644
--- a/rts/sm/MBlock.c
+++ b/rts/sm/MBlock.c
@@ -18,6 +18,7 @@
#include <string.h>
+lnat peak_mblocks_allocated = 0;
lnat mblocks_allocated = 0;
lnat mpc_misses = 0;
@@ -29,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
@@ -81,7 +82,7 @@ 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)
@@ -95,7 +96,7 @@ markHeapAlloced(void *p)
map->addrHigh32 = (StgWord32) (((StgWord)p) >> 32);
}
- map->lines[MBLOCK_MAP_LINE(p)] = 1;
+ map->lines[MBLOCK_MAP_LINE(p)] = i;
{
StgWord mblock;
@@ -103,19 +104,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
@@ -207,8 +211,6 @@ void * getFirstMBlock(void)
#endif // SIZEOF_VOID_P
-#endif // DEBUG
-
/* -----------------------------------------------------------------------------
Allocate new mblock(s)
-------------------------------------------------------------------------- */
@@ -238,13 +240,31 @@ getMBlocks(nat n)
}
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)
{
+ debugTrace(DEBUG_gc, "freeing all megablocks");
osFreeAllMBlocks();
}