/* -----------------------------------------------------------------------------
- * $Id: MBlock.c,v 1.7 1999/01/25 11:55:06 sof Exp $
+ * $Id: MBlock.c,v 1.23 2001/08/14 13:40:09 sewardj Exp $
+ *
+ * (c) The GHC Team 1998-1999
*
* MegaBlock Allocator Interface. This file contains all the dirty
* architecture-dependent hackery required to get a chunk of aligned
*
* ---------------------------------------------------------------------------*/
-#define NON_POSIX_SOURCE
+/* This is non-posix compliant. */
+/* #include "PosixSource.h" */
#include "Rts.h"
#include "RtsUtils.h"
#include <sys/types.h>
#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
+#ifndef mingw32_TARGET_OS
+# ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+# endif
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#if cygwin32_TARGET_OS
+#if HAVE_WINDOWS_H
#include <windows.h>
#endif
-#if freebsd2_TARGET_OS || freebsd3_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 ASK_FOR_MEM_AT 0x50000000
-
-#elif linux_TARGET_OS
-/* Any ideas?
- */
-#define ASK_FOR_MEM_AT 0x50000000
-
-#elif solaris2_TARGET_OS
-/* guess */
-#define ASK_FOR_MEM_AT 0x50000000
-
-#elif osf3_TARGET_OS
-/* guess */
-#define ASK_FOR_MEM_AT 0x50000000
-
-#elif _WIN32
-/* doesn't matter, we use a reserve/commit algorithm */
-
-#else
-#error Dont know where to get memory from on this architecture
-/* ToDo: memory locations on other architectures */
-#endif
-
lnat mblocks_allocated = 0;
void *
}
#ifndef _WIN32
-
void *
getMBlocks(nat n)
{
- static caddr_t next_request = (caddr_t)ASK_FOR_MEM_AT;
+ static caddr_t next_request = (caddr_t)HEAP_BASE;
caddr_t ret;
lnat size = MBLOCK_SIZE * n;
MAP_FIXED | MAP_PRIVATE, fd, 0);
close(fd);
}
+#elif hpux_TARGET_OS
+ ret = mmap(next_request, size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+#elif macosx_TARGET_OS
+ ret = mmap(next_request, size, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
#else
ret = mmap(next_request, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
}
if (((W_)ret & MBLOCK_MASK) != 0) {
- barf("GetMBlock: misaligned block returned");
+ barf("GetMBlock: misaligned block %p returned when allocating %d megablock(s) at %p", ret, n, next_request);
}
- IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %x\n",n,(nat)ret));
+ IF_DEBUG(gc,fprintf(stderr,"Allocated %d megablock(s) at %p\n",n,ret));
next_request += size;
*/
+char* base_non_committed = (char*)0;
+
+/* Reserve VM 128M at the time to try to minimise the slop cost. */
+#define SIZE_RESERVED_POOL ( 128 * 1024 * 1024 )
+
+/* This predicate should be inlined, really. */
+/* TODO: this only works for a single chunk */
+int
+is_heap_alloced(const void* x)
+{
+ return (((char*)(x) >= base_non_committed) &&
+ ((char*)(x) <= (base_non_committed + SIZE_RESERVED_POOL)));
+}
+
void *
getMBlocks(nat n)
{
- static char* base_non_committed = (char*)0;
static char* base_mblocks = (char*)0;
static char* next_request = (char*)0;
void* ret = (void*)0;
lnat size = MBLOCK_SIZE * n;
- /* Reserve VM 128M at the time to try to minimise the slop cost. */
-#define SIZE_RESERVED_POOL ( 128 * 1024 * 1024 )
-
if ( (base_non_committed == 0) ||
(next_request + size > base_non_committed + SIZE_RESERVED_POOL) ) {
+#ifdef ENABLE_WIN32_DLL_SUPPORT
+ if (base_non_committed)
+ barf("Windows programs can only use 128Mb of heap; sorry!");
+#endif
base_non_committed = VirtualAlloc ( NULL
, SIZE_RESERVED_POOL
, MEM_RESERVE
, PAGE_READWRITE
);
if ( base_non_committed == 0 ) {
-# ifdef DEBUG
+# if 1 /*def DEBUG*/
fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError());
# endif
ret=(void*)-1;
} else {
/* The returned pointer is not aligned on a mega-block boundary. Make it. */
- base_mblocks = (char*)((unsigned)base_non_committed & (unsigned)0xfff00000) + 0x100000;
+ base_mblocks = (char*)((unsigned long)base_non_committed & (unsigned long)0xfff00000) + MBLOCK_SIZE;
# if 0
fprintf(stderr, "Dropping %d bytes off of 128M chunk\n",
(unsigned)base_mblocks - (unsigned)base_non_committed);
# endif
if ( ((char*)base_mblocks + size) > ((char*)base_non_committed + SIZE_RESERVED_POOL) ) {
-# ifdef DEBUG
+# if 1 /*def DEBUG*/
fprintf(stderr, "oops, committed too small a region to start with.");
# endif
ret=(void*)-1;
if ( ret != (void*)-1 ) {
ret = VirtualAlloc(next_request, size, MEM_COMMIT, PAGE_READWRITE);
if (ret == NULL) {
-# ifdef DEBUG
+# if 1 /*def DEBUG*/
fprintf(stderr, "getMBlocks: VirtualAlloc failed with: %d\n", GetLastError());
# endif
ret=(void*)-1;