[project @ 2004-11-10 03:20:31 by wolfgang]
[ghc-hetmet.git] / ghc / rts / MBlock.h
index 3845ca4..8d2a979 100644 (file)
@@ -1,5 +1,4 @@
 /* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.15 2002/10/21 11:38:54 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -9,7 +8,8 @@
 
 #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);
@@ -47,28 +47,43 @@ 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
-
-// This is the table.  Each byte is non-zero if the appropriate MBlock
-// in the address space contains heap.
 extern StgWord8 mblock_map[];
 
-#define HEAP_ALLOCED(p) \
-  ((int)(mblock_map[((StgWord)(p) & ~MBLOCK_MASK) >> MBLOCK_SHIFT]))
+/* 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)]
+
+#elif SIZEOF_VOID_P == 8
 
-#else // SIZEOF_VOID_P != 4
+# define MBLOCK_MAP_SIZE       4096
+# define MBLOCK_MAP_ENTRY(p)   (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT)
 
-// on a 64-bit machine, we need to extend the above scheme to use a
-// 2-level mapping.  (ToDo)
+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) )
 
-#ifdef TEXT_BEFORE_HEAP
-# define HEAP_ALLOCED(x)  ((StgPtr)(x) >= (StgPtr)(HEAP_BASE))
 #else
-#error HEAP_ALLOCED not defined
+# error HEAP_ALLOCED not defined
 #endif
 
-#endif // SIZEOF_VOID_P != 4
-
 #endif // __MBLOCK_H__