[project @ 2005-01-28 12:55:17 by simonmar]
[ghc-hetmet.git] / ghc / rts / MBlock.h
index c369416..07c40a0 100644 (file)
@@ -1,5 +1,4 @@
 /* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.16 2002/11/22 06:54:05 matthewc Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -9,12 +8,13 @@
 
 #ifndef __MBLOCK_H__
 #define __MBLOCK_H__
-extern lnat mblocks_allocated;
+
+extern lnat RTS_VAR(mblocks_allocated);
 
 extern void * getMBlock(void);
 extern void * getMBlocks(nat n);
 
-#if osf3_TARGET_OS
+#if osf3_HOST_OS
 /* ToDo: Perhaps by adjusting this value we can make linking without
  * -static work (i.e., not generate a core-dumping executable)? */
 #if SIZEOF_VOID_P == 8
@@ -47,33 +47,40 @@ extern void * getMBlocks(nat n);
    will be quickly cached (indeed, performance measurements showed no
    measurable difference between doing the table lookup and using a
    constant comparison).
+
+   On 64-bit machines, we cache one 12-bit block map that describes
+   4096 megablocks or 4GB of memory. If HEAP_ALLOCED is called for
+   an address that is not in the cache, it calls slowIsHeapAlloced
+   (see MBlock.c) which will find the block map for the 4GB block in
+   question.
    -------------------------------------------------------------------------- */
 
+#if SIZEOF_VOID_P == 4
 extern StgWord8 mblock_map[];
 
-#if SIZEOF_VOID_P == 4
 /* On a 32-bit machine a 4KB table is always sufficient */
 # define MBLOCK_MAP_SIZE       4096
 # define MBLOCK_MAP_ENTRY(p)   ((StgWord)(p) >> MBLOCK_SHIFT)
 # define HEAP_ALLOCED(p)       mblock_map[MBLOCK_MAP_ENTRY(p)]
-# define MARK_HEAP_ALLOCED(p)  (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1)
 
-#elif defined(ia64_TARGET_ARCH)
-/* Instead of trying to cover the whole 64-bit address space (which would
- * require a better data structure), we assume that mmap allocates mappings
- * from the bottom of region 1, and track some portion of address space from
- * there upwards (currently 4GB). */
+#elif SIZEOF_VOID_P == 8
+
 # define MBLOCK_MAP_SIZE       4096
-# define MBLOCK_MAP_ENTRY(p)   (((StgWord)(p) - (1UL << 61)) >> MBLOCK_SHIFT)
-# define HEAP_ALLOCED(p)       ((MBLOCK_MAP_ENTRY(p) < MBLOCK_MAP_SIZE) \
-                                       && mblock_map[MBLOCK_MAP_ENTRY(p)])
-# define MARK_HEAP_ALLOCED(p)  ((MBLOCK_MAP_ENTRY(p) < MBLOCK_MAP_SIZE) \
-                                       && (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1))
-
-#elif defined(TEXT_BEFORE_HEAP)
-/* Fall back to old method - assume heap above HEAP_BASE */
-# define HEAP_ALLOCED(p)       ((StgPtr)(p) >= (StgPtr)(HEAP_BASE))
-# define MARK_HEAP_ALLOCED(p)  do {} while(0)
+# define MBLOCK_MAP_ENTRY(p)   (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT)
+
+typedef struct {
+    StgWord32  addrHigh32;
+    StgWord8   mblocks[MBLOCK_MAP_SIZE];
+} MBlockMap;
+
+extern MBlockMap *mblock_cache;
+
+StgBool slowIsHeapAlloced(void *p);
+
+# define HEAP_ALLOCED(p)                                       \
+       ( ((((StgWord)(p)) >> 32) == mblock_cache->addrHigh32)  \
+       ? mblock_cache->mblocks[MBLOCK_MAP_ENTRY(p)]            \
+       : slowIsHeapAlloced(p) )
 
 #else
 # error HEAP_ALLOCED not defined