MBlock.h 3.08 KB
Newer Older
1
/* -----------------------------------------------------------------------------
2 3
 *
 * (c) The GHC Team, 1998-1999
4 5 6 7
 *
 * MegaBlock Allocator interface.
 *
 * ---------------------------------------------------------------------------*/
8

sof's avatar
sof committed
9 10
#ifndef __MBLOCK_H__
#define __MBLOCK_H__
11 12

extern lnat RTS_VAR(mblocks_allocated);
13

14 15
extern void * getMBlock(void);
extern void * getMBlocks(nat n);
16

17
#if osf3_TARGET_OS
ken's avatar
ken committed
18 19 20 21 22 23 24
/* 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
#define HEAP_BASE 0x180000000L
#else
#error I have no idea where to begin the heap on a non-64-bit osf3 machine.
#endif
25

26
#else
27

28 29
// we're using the generic method
#define HEAP_BASE 0
30

31 32 33 34
#endif

/* -----------------------------------------------------------------------------
   The HEAP_ALLOCED() test.
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC.
   It needs to be FAST.

   Implementation of HEAP_ALLOCED
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   Since heap is allocated in chunks of megablocks (MBLOCK_SIZE), we
   can just use a table to record which megablocks in the address
   space belong to the heap.  On a 32-bit machine, with 1Mb
   megablocks, using 8 bits for each entry in the table, the table
   requires 4k.  Lookups during GC will be fast, because the table
   will be quickly cached (indeed, performance measurements showed no
   measurable difference between doing the table lookup and using a
   constant comparison).
   -------------------------------------------------------------------------- */

extern StgWord8 mblock_map[];

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#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))

73
#elif SIZEOF_VOID_P == 8
74 75 76 77 78 79 80 81 82 83
/* 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)


84
#else
85
# error HEAP_ALLOCED not defined
86
#endif
sof's avatar
sof committed
87

88
#endif // __MBLOCK_H__