1 /* -----------------------------------------------------------------------------
2 * $Id: MBlock.h,v 1.20 2004/08/13 13:10:10 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * MegaBlock Allocator interface.
8 * ---------------------------------------------------------------------------*/
13 extern lnat RTS_VAR(mblocks_allocated);
15 extern void * getMBlock(void);
16 extern void * getMBlocks(nat n);
19 /* ToDo: Perhaps by adjusting this value we can make linking without
20 * -static work (i.e., not generate a core-dumping executable)? */
21 #if SIZEOF_VOID_P == 8
22 #define HEAP_BASE 0x180000000L
24 #error I have no idea where to begin the heap on a non-64-bit osf3 machine.
29 // we're using the generic method
34 /* -----------------------------------------------------------------------------
35 The HEAP_ALLOCED() test.
37 HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC.
40 Implementation of HEAP_ALLOCED
41 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43 Since heap is allocated in chunks of megablocks (MBLOCK_SIZE), we
44 can just use a table to record which megablocks in the address
45 space belong to the heap. On a 32-bit machine, with 1Mb
46 megablocks, using 8 bits for each entry in the table, the table
47 requires 4k. Lookups during GC will be fast, because the table
48 will be quickly cached (indeed, performance measurements showed no
49 measurable difference between doing the table lookup and using a
51 -------------------------------------------------------------------------- */
53 extern StgWord8 mblock_map[];
55 #if SIZEOF_VOID_P == 4
56 /* On a 32-bit machine a 4KB table is always sufficient */
57 # define MBLOCK_MAP_SIZE 4096
58 # define MBLOCK_MAP_ENTRY(p) ((StgWord)(p) >> MBLOCK_SHIFT)
59 # define HEAP_ALLOCED(p) mblock_map[MBLOCK_MAP_ENTRY(p)]
60 # define MARK_HEAP_ALLOCED(p) (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1)
62 #elif defined(ia64_TARGET_ARCH)
63 /* Instead of trying to cover the whole 64-bit address space (which would
64 * require a better data structure), we assume that mmap allocates mappings
65 * from the bottom of region 1, and track some portion of address space from
66 * there upwards (currently 4GB). */
67 # define MBLOCK_MAP_SIZE 4096
68 # define MBLOCK_MAP_ENTRY(p) (((StgWord)(p) - (1UL << 61)) >> MBLOCK_SHIFT)
69 # define HEAP_ALLOCED(p) ((MBLOCK_MAP_ENTRY(p) < MBLOCK_MAP_SIZE) \
70 && mblock_map[MBLOCK_MAP_ENTRY(p)])
71 # define MARK_HEAP_ALLOCED(p) ((MBLOCK_MAP_ENTRY(p) < MBLOCK_MAP_SIZE) \
72 && (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1))
74 #elif SIZEOF_VOID_P == 8
75 /* XXX: This is a HACK, and will not work in general! We just use the
76 * lower 32 bits of the address, and do the same as for the 32-bit
77 * version. As long as the OS gives us memory in a roughly linear
78 * fashion, it won't go wrong until we've allocated 4G. */
79 # define MBLOCK_MAP_SIZE 4096
80 # define MBLOCK_MAP_ENTRY(p) (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT)
81 # define HEAP_ALLOCED(p) (mblock_map[MBLOCK_MAP_ENTRY(p)])
82 # define MARK_HEAP_ALLOCED(p) (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1)
86 # error HEAP_ALLOCED not defined
89 #endif // __MBLOCK_H__