/* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.15 2002/10/21 11:38:54 simonmar Exp $
*
- * (c) The GHC Team, 1998-1999
+ * (c) The GHC Team, 1998-2005
*
* MegaBlock Allocator interface.
*
* ---------------------------------------------------------------------------*/
-#ifndef __MBLOCK_H__
-#define __MBLOCK_H__
-extern lnat mblocks_allocated;
+#ifndef MBLOCK_H
+#define MBLOCK_H
+
+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
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__
+#endif /* MBLOCK_H */