+ 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[];
+
+/* 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
+
+# define MBLOCK_MAP_SIZE 4096
+# 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) )