diff --git a/heap.c b/heap.c index d4bedba..1551783 100644 --- a/heap.c +++ b/heap.c @@ -1,4 +1,5 @@ /* stack grows up from the bottom and heap grows down from the top of heap space */ +#include #include #include #include "picoc.h" @@ -96,8 +97,11 @@ void *HeapAlloc(int Size) if (Bucket < FREELIST_BUCKETS && FreeListBucket[Bucket] != NULL) { /* try to allocate from a freelist bucket first */ + printf("allocating %d(%d) from bucket", Size, AllocSize); NewMem = FreeListBucket[Bucket]; + assert((unsigned long)NewMem >= (unsigned long)&HeapMemory && (unsigned char *)NewMem - &HeapMemory[0] < HEAP_SIZE); FreeListBucket[Bucket] = *(struct AllocNode **)NewMem; + assert(FreeListBucket[Bucket] == NULL || ((unsigned long)FreeListBucket[Bucket] >= (unsigned long)&HeapMemory && (unsigned char *)FreeListBucket[Bucket] - &HeapMemory[0] < HEAP_SIZE)); NewMem->Size = AllocSize; } else if (FreeListBig != NULL) @@ -107,14 +111,20 @@ void *HeapAlloc(int Size) if (*FreeNode != NULL) { + assert((unsigned long)*FreeNode >= (unsigned long)&HeapMemory && (unsigned char *)*FreeNode - &HeapMemory[0] < HEAP_SIZE); + assert((*FreeNode)->Size < HEAP_SIZE && (*FreeNode)->Size > 0); if ((*FreeNode)->Size < Size + SPLIT_MEM_THRESHOLD) { /* close in size - reduce fragmentation by not splitting */ + printf("allocating %d(%d) from freelist, no split (%d)", Size, AllocSize, (*FreeNode)->Size); NewMem = *FreeNode; + assert((unsigned long)NewMem >= (unsigned long)&HeapMemory && (unsigned char *)NewMem - &HeapMemory[0] < HEAP_SIZE); *FreeNode = NewMem->NextFree; } else { /* split this big memory chunk */ + printf("allocating %d(%d) from freelist, split chunk (%d)", Size, AllocSize, (*FreeNode)->Size); NewMem = *FreeNode + (*FreeNode)->Size - AllocSize; + assert((unsigned long)NewMem >= (unsigned long)&HeapMemory && (unsigned char *)NewMem - &HeapMemory[0] < HEAP_SIZE); (*FreeNode)->Size -= AllocSize; NewMem->Size = AllocSize; } @@ -123,6 +133,7 @@ void *HeapAlloc(int Size) if (NewMem == NULL) { /* couldn't allocate from a freelist - try to increase the size of the heap area */ + printf("allocating %d(%d) at bottom of heap", Size, AllocSize); if (HeapBottom - AllocSize < StackTop) return NULL; @@ -132,6 +143,7 @@ void *HeapAlloc(int Size) } memset(&NewMem->NextFree, '\0', AllocSize-sizeof(NewMem->Size)); + printf(" = %lx\n", (unsigned long)&NewMem->NextFree); return (void *)&NewMem->NextFree; } @@ -141,20 +153,27 @@ void HeapFree(void *Mem) struct AllocNode *MemNode = (struct AllocNode *)(Mem-sizeof(int)); int Bucket = MemNode->Size >> 2; + assert((unsigned long)Mem >= (unsigned long)&HeapMemory && (unsigned char *)Mem - &HeapMemory[0] < HEAP_SIZE); + assert(MemNode->Size < HEAP_SIZE && MemNode->Size > 0); if (Mem == NULL) return; if ((void *)MemNode == HeapBottom) { /* pop it off the bottom of the heap, reducing the heap size */ + printf("freeing %d from bottom of heap\n", MemNode->Size); HeapBottom += sizeof(int) + MemNode->Size; } else if (Bucket < FREELIST_BUCKETS) { /* we can fit it in a bucket */ + printf("freeing %d to bucket\n", MemNode->Size); + assert(FreeListBucket[Bucket] == NULL || ((unsigned long)FreeListBucket[Bucket] >= (unsigned long)&HeapMemory && (unsigned char *)FreeListBucket[Bucket] - &HeapMemory[0] < HEAP_SIZE)); *(struct AllocNode **)MemNode = FreeListBucket[Bucket]; FreeListBucket[Bucket] = (struct AllocNode *)MemNode; } else { /* put it in the big memory freelist */ + printf("freeing %lx:%d to freelist\n", (unsigned long)Mem, MemNode->Size); + assert(FreeListBig == NULL || ((unsigned long)FreeListBig >= (unsigned long)&HeapMemory && (unsigned char *)FreeListBig - &HeapMemory[0] < HEAP_SIZE)); MemNode->NextFree = FreeListBig; FreeListBig = MemNode; } diff --git a/picoc.h b/picoc.h index ca2cb08..2de5890 100644 --- a/picoc.h +++ b/picoc.h @@ -65,7 +65,7 @@ enum LexToken /* used in dynamic memory allocation */ struct AllocNode { - int Size; + unsigned int Size; struct AllocNode *NextFree; };