static
alloc_rec*
allocNew(nat n) {
- alloc_rec* rec = (alloc_rec*)malloc(sizeof(alloc_rec));
+ alloc_rec* rec;
+ rec = (alloc_rec*)stgMallocBytes(sizeof(alloc_rec),"getMBlocks: allocNew");
rec->size = (n+1)*MBLOCK_SIZE;
rec->base =
VirtualAlloc(NULL, rec->size, MEM_RESERVE, PAGE_READWRITE);
if(rec->base==0) {
- free((void*)rec);
+ stgFree((void*)rec);
rec=0;
- errorBelch(
- "getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed with: %ld\n"
- , n, GetLastError());
+ sysErrorBelch(
+ "getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed", n);
} else {
- if(allocs==0) {
- allocs=rec;
- rec->next=0;
- } else {
- alloc_rec* it=allocs;
- for(; it->next!=0 && it->next->base<rec->base; it=it->next) ;
- rec->next=it->next;
- it->next=rec;
- }
+ alloc_rec temp;
+ temp.base=0; temp.size=0; temp.next=allocs;
+
+ alloc_rec* it;
+ it=&temp;
+ for(; it->next!=0 && it->next->base<rec->base; it=it->next) ;
+ rec->next=it->next;
+ it->next=rec;
+
+ allocs=temp.next;
debugTrace(DEBUG_gc, "allocated %d megablock(s) at 0x%x",n,(nat)rec->base);
}
return rec;
void
insertFree(char* alloc_base, int alloc_size) {
block_rec temp;
- temp.base=0; temp.size=0; temp.next=free_blocks;
+ block_rec* it;
+ block_rec* prev;
- block_rec* it = free_blocks;
- block_rec* prev = &temp;
- for( ; it!=0 && it->base<alloc_base; prev=it, it=it->next) ;
+ temp.base=0; temp.size=0; temp.next=free_blocks;
+ it = free_blocks;
+ prev = &temp;
+ for( ; it!=0 && it->base<alloc_base; prev=it, it=it->next) {}
if(it!=0 && alloc_base+alloc_size == it->base) {
if(prev->base + prev->size == alloc_base) { /* Merge it, alloc, prev */
prev->size += alloc_size + it->size;
prev->next = it->next;
- free(it);
+ stgFree(it);
} else { /* Merge it, alloc */
it->base = alloc_base;
it->size += alloc_size;
} else if(prev->base + prev->size == alloc_base) { /* Merge alloc, prev */
prev->size += alloc_size;
} else { /* Merge none */
- block_rec* rec = (block_rec*)malloc(sizeof(block_rec));
- /* TODO: Check malloc failure */
+ block_rec* rec;
+ rec = (block_rec*)stgMallocBytes(sizeof(block_rec),"getMBlocks: insertFree");
rec->base=alloc_base;
rec->size=alloc_size;
rec->next = it;
void*
findFreeBlocks(nat n) {
void* ret=0;
- block_rec* it=free_blocks;
- int required_size = n*MBLOCK_SIZE;
- /* TODO: Don't just take first block, find smallest sufficient block */
+ block_rec* it;
block_rec temp;
+ block_rec* prev;
+
+ int required_size;
+ it=free_blocks;
+ required_size = n*MBLOCK_SIZE;
temp.next=free_blocks; temp.base=0; temp.size=0;
- block_rec* prev=&temp;
- for( ; it!=0 && it->size<required_size; prev=it, it=it->next ) ;
+ prev=&temp;
+ /* TODO: Don't just take first block, find smallest sufficient block */
+ for( ; it!=0 && it->size<required_size; prev=it, it=it->next ) {}
if(it!=0) {
if( (((unsigned long)it->base) & MBLOCK_MASK) == 0) { /* MBlock aligned */
ret = (void*)it->base;
if(it->size==required_size) {
- prev->next=0;
- free(it);
+ prev->next=it->next;
+ stgFree(it);
} else {
it->base += required_size;
it->size -=required_size;
}
} else {
- char* need_base = (char*)(((unsigned long)it->base) & ((unsigned long)~MBLOCK_MASK)) + MBLOCK_SIZE;
- block_rec* next = (block_rec*)malloc(sizeof(block_rec));
- /* TODO: Check malloc failure */
- int new_size = need_base - it->base;
+ char* need_base;
+ block_rec* next;
+ int new_size;
+ need_base = (char*)(((unsigned long)it->base) & ((unsigned long)~MBLOCK_MASK)) + MBLOCK_SIZE;
+ next = (block_rec*)stgMallocBytes(
+ sizeof(block_rec)
+ , "getMBlocks: findFreeBlocks: splitting");
+ new_size = need_base - it->base;
next->base = need_base +required_size;
next->size = it->size - (new_size+required_size);
it->size = new_size;
(ordered) allocated blocks. */
static void
commitBlocks(char* base, int size) {
- alloc_rec* it=allocs;
- for( ; it!=0 && (it->base+it->size)<base; it=it->next ) ;
+ alloc_rec* it;
+ it=allocs;
+ for( ; it!=0 && (it->base+it->size)<=base; it=it->next ) {}
for( ; it!=0 && size>0; it=it->next ) {
- int size_delta = it->size - (base-it->base);
+ int size_delta;
+ void* temp;
+ size_delta = it->size - (base-it->base);
if(size_delta>size) size_delta=size;
- void* temp = VirtualAlloc(base, size_delta, MEM_COMMIT, PAGE_READWRITE);
- if(temp==0)
- debugBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed: %ld", GetLastError());
+ temp = VirtualAlloc(base, size_delta, MEM_COMMIT, PAGE_READWRITE);
+ if(temp==0) {
+ sysErrorBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed");
+ stg_exit(EXIT_FAILURE);
+ }
size-=size_delta;
base+=size_delta;
}
void *
getMBlocks(nat n) {
- void* ret=0;
+ void* ret;
ret = findFreeBlocks(n);
if(ret==0) {
- alloc_rec* alloc = allocNew(n);
+ alloc_rec* alloc;
+ alloc = allocNew(n);
/* We already belch in allocNew if it fails */
- if(alloc) {
+ if (alloc == 0) {
+ stg_exit(EXIT_FAILURE);
+ } else {
insertFree(alloc->base, alloc->size);
ret = findFreeBlocks(n);
- }
+ }
}
if(ret!=0) {
/* (In)sanity tests */
- if (((W_)ret & MBLOCK_MASK) != 0) barf("getMBlocks: misaligned block returned");
+ if (((W_)ret & MBLOCK_MASK) != 0) {
+ barf("getMBlocks: misaligned block returned");
+ }
commitBlocks(ret, MBLOCK_SIZE*n);
/* Global bookkeeping */
mblocks_allocated += n;
- int i=0;
- for(; i<(int)n; ++i)
+ int i;
+ for(i=0; i<(int)n; ++i) {
markHeapAlloced( ret + i * MBLOCK_SIZE );
+ }
}
return ret;
freeAllMBlocks(void)
{
{
- block_rec* next = 0;
- block_rec* it = free_blocks;
+ block_rec* next;
+ block_rec* it;
+ next=0;
+ it = free_blocks;
for(; it!=0; ) {
- if(!VirtualFree((void*)it->base, it->size, MEM_DECOMMIT))
- debugBelch("freeAllMBlocks: VirtualFree MEM_DECOMMIT failed with %ld", GetLastError());
next = it->next;
- free(it);
+ stgFree(it);
it=next;
}
}
{
- alloc_rec* next = 0;
- alloc_rec* it = allocs;
+ alloc_rec* next;
+ alloc_rec* it;
+ next=0;
+ it=allocs;
for(; it!=0; ) {
- if(!VirtualFree((void*)it->base, 0, MEM_RELEASE))
- debugBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed with %ld", GetLastError());
+ if(!VirtualFree((void*)it->base, 0, MEM_RELEASE)) {
+ sysErrorBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed");
+ stg_exit(EXIT_FAILURE);
+ }
next = it->next;
- free(it);
+ stgFree(it);
it=next;
}
}