/* -----------------------------------------------------------------------------
- * $Id: MBlock.c,v 1.51 2004/09/03 15:28:33 simonmar Exp $
*
* (c) The GHC Team 1998-1999
*
The MBlock Map: provides our implementation of HEAP_ALLOCED()
-------------------------------------------------------------------------- */
-#ifdef MBLOCK_MAP_SIZE
+#if SIZEOF_VOID_P == 4
StgWord8 mblock_map[MBLOCK_MAP_SIZE]; // initially all zeros
+#elif SIZEOF_VOID_P == 8
+static MBlockMap dummy_mblock_map;
+MBlockMap *mblock_cache = &dummy_mblock_map;
+int mblock_map_count = 0;
+MBlockMap **mblock_maps = NULL;
+
+static MBlockMap *
+findMBlockMap(void *p)
+{
+ int i;
+ StgWord32 hi = (StgWord32) (((StgWord)p) >> 32);
+ for( i = 0; i < mblock_map_count; i++ )
+ {
+ if(mblock_maps[i]->addrHigh32 == hi)
+ {
+ return mblock_maps[i];
+ }
+ }
+ return NULL;
+}
+
+StgBool
+slowIsHeapAlloced(void *p)
+{
+ MBlockMap *map = findMBlockMap(p);
+ if(map)
+ {
+ mblock_cache = map;
+ return map->mblocks[MBLOCK_MAP_ENTRY(p)];
+ }
+ else
+ return 0;
+}
#endif
+static void
+markHeapAlloced(void *p)
+{
+#if SIZEOF_VOID_P == 4
+ mblock_map[MBLOCK_MAP_ENTRY(p)] = 1;
+#elif SIZEOF_VOID_P == 8
+ MBlockMap *map = findMBlockMap(p);
+ if(map == NULL)
+ {
+ mblock_map_count++;
+ mblock_maps = realloc(mblock_maps,
+ sizeof(MBlockMap*) * mblock_map_count);
+ map = mblock_maps[mblock_map_count-1] = calloc(1,sizeof(MBlockMap));
+ map->addrHigh32 = (StgWord32) (((StgWord)p) >> 32);
+ }
+ map->mblocks[MBLOCK_MAP_ENTRY(p)] = 1;
+ mblock_cache = map;
+#endif
+}
+
/* -----------------------------------------------------------------------------
Allocate new mblock(s)
-------------------------------------------------------------------------- */
err = vm_allocate(mach_task_self(),(vm_address_t*) &ret, size, TRUE);
if(err) // don't know what the error codes mean exactly
- barf("memory allocation failed (requested %d bytes)", size);
+ barf("memory allocation failed (requested %lu bytes)", size);
else
vm_protect(mach_task_self(),ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE);
#else
(errno == EINVAL && sizeof(void*)==4 && size >= 0xc0000000)) {
// If we request more than 3Gig, then we get EINVAL
// instead of ENOMEM (at least on Linux).
- errorBelch("out of memory (requested %d bytes)", size);
+ errorBelch("out of memory (requested %lu bytes)", size);
stg_exit(EXIT_FAILURE);
} else {
barf("getMBlock: mmap: %s", strerror(errno));
// fill in the table
for (i = 0; i < n; i++) {
- MARK_HEAP_ALLOCED( ret + i * MBLOCK_SIZE );
+ markHeapAlloced( ret + i * MBLOCK_SIZE );
}
mblocks_allocated += n;
// fill in the table
for (i = 0; i < n; i++) {
- MARK_HEAP_ALLOCED ( ret + i * MBLOCK_SIZE );
+ markHeapAlloced( ret + i * MBLOCK_SIZE );
}
return ret;