[project @ 2005-01-28 12:55:17 by simonmar]
[ghc-hetmet.git] / ghc / rts / MBlock.h
index 64fd459..07c40a0 100644 (file)
@@ -1,5 +1,4 @@
 /* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.20 2004/08/13 13:10:10 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -15,7 +14,7 @@ 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
@@ -48,39 +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). */
-# 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 SIZEOF_VOID_P == 8
-/* XXX: This is a HACK, and will not work in general!  We just use the
- * lower 32 bits of the address, and do the same as for the 32-bit
- * version.  As long as the OS gives us memory in a roughly linear
- * fashion, it won't go wrong until we've allocated 4G.  */
+
 # define MBLOCK_MAP_SIZE       4096
 # define MBLOCK_MAP_ENTRY(p)   (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT)
-# define HEAP_ALLOCED(p)       (mblock_map[MBLOCK_MAP_ENTRY(p)])
-# define MARK_HEAP_ALLOCED(p)  (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1)
 
+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