[project @ 2002-11-21 14:59:51 by simonpj]
[ghc-hetmet.git] / ghc / rts / MBlock.h
index 18fe052..3845ca4 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.8 2001/01/16 11:53:32 simonmar Exp $
+ * $Id: MBlock.h,v 1.15 2002/10/21 11:38:54 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -7,54 +7,68 @@
  *
  * ---------------------------------------------------------------------------*/
 
+#ifndef __MBLOCK_H__
+#define __MBLOCK_H__
 extern lnat mblocks_allocated;
 
-#ifdef ENABLE_WIN32_DLL_SUPPORT
-extern int is_heap_alloced(const void* p);
-#endif
-
 extern void * getMBlock(void);
 extern void * getMBlocks(nat n);
 
-#if freebsd2_TARGET_OS || freebsd_TARGET_OS
-/* Executable is loaded from      0x0
- * Shared libraries are loaded at 0x2000000
- * Stack is at the top of the address space.  The kernel probably owns
- * 0x8000000 onwards, so we'll pick 0x5000000.
- */
-#define HEAP_BASE 0x50000000
-
-#elif netbsd_TARGET_OS
-/* NetBSD i386 shared libs are at 0x40000000
- */
-#define HEAP_BASE 0x50000000
-#elif openbsd_TARGET_OS
-#define HEAP_BASE 0x50000000
-#elif linux_TARGET_OS
-/* Any ideas?
- */
-#define HEAP_BASE 0x50000000
-
-#elif solaris2_TARGET_OS
-/* guess */
-#define HEAP_BASE 0x50000000
-
-#elif osf3_TARGET_OS
-/* guess */
-#define HEAP_BASE 0x50000000
-
-#elif hpux_TARGET_OS
-/* guess */
-#define HEAP_BASE 0x50000000
-
-#elif macosx_TARGET_OS
-/* guess */
-#define HEAP_BASE 0x50000000
-
-#elif _WIN32
-/* doesn't matter, we use a reserve/commit algorithm */
+#if osf3_TARGET_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
+#define HEAP_BASE 0x180000000L
+#else
+#error I have no idea where to begin the heap on a non-64-bit osf3 machine.
+#endif
 
 #else
-#error Dont know where to get memory from on this architecture
-/* ToDo: memory locations on other architectures */
+
+// we're using the generic method
+#define HEAP_BASE 0
+
 #endif
+
+/* -----------------------------------------------------------------------------
+   The HEAP_ALLOCED() test.
+
+   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).
+   -------------------------------------------------------------------------- */
+
+#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]))
+
+#else // SIZEOF_VOID_P != 4
+
+// on a 64-bit machine, we need to extend the above scheme to use a
+// 2-level mapping.  (ToDo)
+
+#ifdef TEXT_BEFORE_HEAP
+# define HEAP_ALLOCED(x)  ((StgPtr)(x) >= (StgPtr)(HEAP_BASE))
+#else
+#error HEAP_ALLOCED not defined
+#endif
+
+#endif // SIZEOF_VOID_P != 4
+
+#endif // __MBLOCK_H__