X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fheap.c;h=396fa238904c6e14b2f2e714818634b7d99a1a75;hb=5ee801f4fb22bba3298f10273027e67f53692e4c;hp=be8eeaf6e3b4dc06945d84a499e4c4f4bcc63000;hpb=e7809e57b0692cf65ee1a7d2060c52fc53da49f2;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/heap.c b/KernelLand/Kernel/heap.c old mode 100644 new mode 100755 index be8eeaf6..396fa238 --- a/KernelLand/Kernel/heap.c +++ b/KernelLand/Kernel/heap.c @@ -1,14 +1,20 @@ /* - * AcessOS Microkernel Version + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * * heap.c + * - Dynamic memory allocation */ #include #include #include +#include +#include -#define WARNINGS 1 -#define DEBUG_TRACE 0 -#define VERBOSE_DUMP 0 +#define WARNINGS 1 // Warn and dump on heap errors +#define DEBUG_TRACE 0 // Enable tracing of allocations +#define VERBOSE_DUMP 0 // Set to 1 to enable a verbose dump when heap errors are encountered +#define VALIDATE_ON_ALLOC 1 // Set to 1 to enable validation of the heap on all malloc() calls // === CONSTANTS === #define HEAP_INIT_SIZE 0x8000 // 32 KiB @@ -26,69 +32,87 @@ // === PROTOTYPES === void Heap_Install(void); -void *Heap_Extend(int Bytes); +void *Heap_Extend(size_t Bytes); void *Heap_Merge(tHeapHead *Head); //void *Heap_Allocate(const char *File, int Line, size_t Bytes); //void *Heap_AllocateZero(const char *File, int Line, size_t Bytes); //void *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes); -//void Heap_Deallocate(void *Ptr); -void Heap_Dump(void); -void Heap_Stats(void); +//void Heap_Deallocate(const char *File, int Line, void *Ptr); +//void Heap_Dump(void); +void Heap_ValidateDump(int bVerbose); +//void Heap_Stats(void); // === GLOBALS === tMutex glHeap; -void *gHeapStart; -void *gHeapEnd; +tHeapHead *gHeapStart; +tHeapHead *gHeapEnd; // === CODE === void Heap_Install(void) { - gHeapStart = (void*)MM_KHEAP_BASE; - gHeapEnd = (void*)MM_KHEAP_BASE; + gHeapStart = (void*)MM_KHEAP_BASE; + gHeapEnd = gHeapStart; Heap_Extend(HEAP_INIT_SIZE); } +static inline tHeapHead *Heap_NextHead(tHeapHead *Head) { + return (void*)( (char*)Head + Head->Size ); +} +static inline tHeapFoot *Heap_ThisFoot(tHeapHead *Head) { + return (void*)( (char*)Head + Head->Size - sizeof(tHeapFoot) ); +} +static inline tHeapFoot *Heap_PrevFoot(tHeapHead *Head) { + //ASSERT(Head != gHeapStart); + return (void*)( (char*)Head - sizeof(tHeapFoot) ); +} + /** * \brief Extend the size of the heap */ -void *Heap_Extend(int Bytes) +void *Heap_Extend(size_t Bytes) { - Uint i; - tHeapHead *head = gHeapEnd; - tHeapFoot *foot; + //Debug("Heap_Extend(0x%x)", Bytes); // Bounds Check - if( (tVAddr)gHeapEnd == MM_KHEAP_MAX ) + if( gHeapEnd == (tHeapHead*)MM_KHEAP_MAX ) { + Log_Error("Heap", "Heap limit reached (%p)", (void*)MM_KHEAP_MAX); return NULL; + } if( Bytes == 0 ) { Log_Warning("Heap", "Heap_Extend called with Bytes=%i", Bytes); return NULL; } + const Uint pages = (Bytes + 0xFFF) >> 12; + tHeapHead *new_end = (void*)( (tVAddr)gHeapEnd + (pages << 12) ); // Bounds Check - if( (tVAddr)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) { -// Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd; + if( new_end > (tHeapHead*)MM_KHEAP_MAX ) + { + Log_Error("Heap", "Heap limit exceeded (%p)", (void*)new_end); + // TODO: Clip allocation to available space, and have caller check returned block return NULL; } // Heap expands in pages - for( i = 0; i < (Bytes+0xFFF) >> 12; i ++ ) + for( Uint i = 0; i < pages; i ++ ) { - if( !MM_Allocate( (tVAddr)gHeapEnd+(i<<12) ) ) + if( !MM_Allocate( (tPage*)gHeapEnd + i ) ) { - Warning("OOM - Heap_Extend"); + Warning("OOM - Heap_Extend (%i bytes)"); + Heap_Dump(); return NULL; } } - // Increas heap end - gHeapEnd = (Uint8*)gHeapEnd + (i << 12); + // Increase heap end + tHeapHead *head = gHeapEnd; + gHeapEnd = new_end; // Create Block head->Size = (Bytes+0xFFF)&~0xFFF; head->Magic = MAGIC_FREE; - foot = (void*)( (Uint)gHeapEnd - sizeof(tHeapFoot) ); + tHeapFoot *foot = Heap_ThisFoot(head); foot->Head = head; foot->Magic = MAGIC_FOOT; @@ -96,7 +120,7 @@ void *Heap_Extend(int Bytes) } /** - * \brief Merges two ajacent heap blocks + * \brief Merges two adjacent heap blocks */ void *Heap_Merge(tHeapHead *Head) { @@ -106,11 +130,12 @@ void *Heap_Merge(tHeapHead *Head) //Log("Heap_Merge: (Head=%p)", Head); - thisFoot = (void*)( (Uint)Head + Head->Size - sizeof(tHeapFoot) ); - if((Uint)thisFoot > (Uint)gHeapEnd) return NULL; + thisFoot = Heap_ThisFoot(Head); + if( (void*)thisFoot > (void*)gHeapEnd ) + return NULL; // Merge Left (Down) - foot = (void*)( (Uint)Head - sizeof(tHeapFoot) ); + foot = Heap_PrevFoot(Head); if( ((Uint)foot < (Uint)gHeapEnd && (Uint)foot > (Uint)gHeapStart) && foot->Head->Magic == MAGIC_FREE) { foot->Head->Size += Head->Size; // Increase size @@ -123,11 +148,11 @@ void *Heap_Merge(tHeapHead *Head) } // Merge Right (Upwards) - head = (void*)( (Uint)Head + Head->Size ); + head = Heap_NextHead(Head); if((Uint)head < (Uint)gHeapEnd && head->Magic == MAGIC_FREE) { Head->Size += head->Size; - foot = (void*)( (Uint)Head + Head->Size - sizeof(tHeapFoot) ); + foot = Heap_ThisFoot(Head); foot->Head = Head; // Update Backlink thisFoot->Head = NULL; // Clear old footer thisFoot->Magic = 0; @@ -146,16 +171,20 @@ void *Heap_Merge(tHeapHead *Head) */ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) { - tHeapHead *head, *newhead; + tHeapHead *newhead; tHeapFoot *foot, *newfoot; tHeapHead *best = NULL; - Uint bestSize = 0; // Speed hack + Uint bestSize = UINT_MAX; // Speed hack size_t Bytes; if( __Bytes == 0 ) { return NULL; // TODO: Return a known un-mapped range. // return INVLPTR; } + + #if VALIDATE_ON_ALLOC + Heap_Validate(); + #endif // Get required size #if POW2_SIZES @@ -169,10 +198,7 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) Mutex_Acquire(&glHeap); // Traverse Heap - for( head = gHeapStart; - (Uint)head < (Uint)gHeapEnd; - head = (void*)((Uint)head + head->Size) - ) + for( tHeapHead *head = gHeapStart; head < gHeapEnd; head = Heap_NextHead(head) ) { // Alignment Check #if POW2_SIZES @@ -182,12 +208,29 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) #endif Mutex_Release(&glHeap); // Release spinlock #if WARNINGS - Log_Warning("Heap", "Size of heap address %p is invalid - not aligned (0x%x) [at paddr 0x%x]", + Log_Warning("Heap", "Size of heap address %p is invalid" + " - not aligned (0x%x) [at paddr 0x%x]", head, head->Size, MM_GetPhysAddr(&head->Size)); - Heap_Dump(); + Heap_ValidateDump(VERBOSE_DUMP); #endif return NULL; } + if( head->Size < MIN_SIZE ) { + Mutex_Release(&glHeap); + Log_Warning("Heap", "Size of heap address %p is invalid" + " - Too small (0x%x) [at paddr 0x%x]", + head, head->Size, MM_GetPhysAddr(&head->Size)); + Heap_ValidateDump(VERBOSE_DUMP); + return NULL; + } + if( head->Size > (2<<30) ) { + Mutex_Release(&glHeap); + Log_Warning("Heap", "Size of heap address %p is invalid" + " - Over 2GiB (0x%x) [at paddr 0x%x]", + head, head->Size, MM_GetPhysAddr(&head->Size)); + Heap_ValidateDump(VERBOSE_DUMP); + return NULL; + } // Check if allocated if(head->Magic == MAGIC_USED) continue; @@ -197,7 +240,7 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) #if WARNINGS Log_Warning("Heap", "Magic of heap address %p is invalid (%p = 0x%x)", head, &head->Magic, head->Magic); - Heap_Dump(); + Heap_ValidateDump(VERBOSE_DUMP); #endif return NULL; } @@ -214,8 +257,8 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) head->AllocateTime = now(); Mutex_Release(&glHeap); // Release spinlock #if DEBUG_TRACE - Debug("[Heap ] Malloc'd %p (%i bytes), returning to %p", - head->Data, head->Size, __builtin_return_address(0)); + Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i", + head->Data, head->Size, File, Line); #endif return head->Data; } @@ -240,6 +283,7 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) best = Heap_Extend( Bytes ); // Check for errors if(!best) { + Warning("OOM when allocating 0x%x bytes", Bytes); Mutex_Release(&glHeap); // Release spinlock return NULL; } @@ -252,32 +296,41 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) best->AllocateTime = now(); Mutex_Release(&glHeap); // Release spinlock #if DEBUG_TRACE - Debug("[Heap ] Malloc'd %p (%i bytes), returning to %s:%i", best->Data, best->Size, File, Line); + Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i", + best->Data, best->Size, File, Line); #endif return best->Data; } } // Split Block - newhead = (void*)( (Uint)best + Bytes ); - newfoot = (void*)( (Uint)best + Bytes - sizeof(tHeapFoot) ); - foot = (void*)( (Uint)best + best->Size - sizeof(tHeapFoot) ); - - newfoot->Head = best; // Create new footer - newfoot->Magic = MAGIC_FOOT; - newhead->Size = best->Size - Bytes; // Create new header - newhead->Magic = MAGIC_FREE; - foot->Head = newhead; // Update backlink in old footer + // - Save size for new block + size_t newsize = best->Size - Bytes; + // - Allocate beginning of old block best->Size = Bytes; // Update size in old header best->ValidSize = __Bytes; best->Magic = MAGIC_USED; // Mark block as used best->File = File; best->Line = Line; best->AllocateTime = now(); + // - Create a new foot on old block + newfoot = Heap_ThisFoot(best); + newfoot->Head = best; // Create new footer + newfoot->Magic = MAGIC_FOOT; + // - Create a new header after resized old + newhead = Heap_NextHead(best); + newhead->Size = newsize; + newhead->Magic = MAGIC_FREE; + newhead->ValidSize = 0; + newhead->File = NULL; + newhead->Line = 0; + // - Update footer + foot = Heap_ThisFoot(newhead); + foot->Head = newhead; Mutex_Release(&glHeap); // Release spinlock #if DEBUG_TRACE - Debug("[Heap ] Malloc'd %p (0x%x bytes), returning to %s:%i", + Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i", best->Data, best->Size, File, Line); #endif return best->Data; @@ -286,21 +339,14 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes) /** * \brief Free an allocated memory block */ -void Heap_Deallocate(void *Ptr) +void Heap_Deallocate(const char *File, int Line, void *Ptr) { - tHeapHead *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); - tHeapFoot *foot; - // INVLPTR is returned from Heap_Allocate when the allocation // size is zero. if( Ptr == INVLPTR ) return; - #if DEBUG_TRACE - Debug("[Heap ] free: %p freed by %p (%i old)", Ptr, __builtin_return_address(0), now()-head->AllocateTime); - #endif - // Alignment Check - if( (Uint)Ptr & (sizeof(Uint)-1) ) { + if( (tVAddr)Ptr % sizeof(void*) != 0 ) { Log_Warning("Heap", "free - Passed a non-aligned address (%p)", Ptr); return; } @@ -314,9 +360,12 @@ void Heap_Deallocate(void *Ptr) } // Check memory block - Header - head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); + tHeapHead *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); if(head->Magic == MAGIC_FREE) { - Log_Warning("Heap", "free - Passed a freed block (%p) by %p", head, __builtin_return_address(0)); + Log_Warning("Heap", "free - Passed a freed block (%p) by %s:%i (was freed by %s:%i)", + head, File, Line, + head->File, head->Line); + Proc_PrintBacktrace(); return; } if(head->Magic != MAGIC_USED) { @@ -326,25 +375,31 @@ void Heap_Deallocate(void *Ptr) } // Check memory block - Footer - foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); + tHeapFoot *foot = Heap_ThisFoot(head); if(foot->Head != head) { Log_Warning("Heap", "free - Footer backlink is incorrect (%p, 0x%x)", head, foot->Head); Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line); return; } if(foot->Magic != MAGIC_FOOT) { - Log_Warning("Heap", "free - Footer magic is invalid (%p, %p = 0x%x)", head, &foot->Magic, foot->Magic); + Log_Warning("Heap", "free - Footer magic is invalid (%p, %p = 0x%x)", + head, &foot->Magic, foot->Magic); Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line); return; } + #if DEBUG_TRACE + Log_Debug("Heap", "free: %p freed by %s:%i (%i old)", + Ptr, File, Line, now()-head->AllocateTime); + #endif + // Lock Mutex_Acquire( &glHeap ); // Mark as free head->Magic = MAGIC_FREE; - //head->File = NULL; - //head->Line = 0; + head->File = File; + head->Line = Line; head->ValidSize = 0; // Merge blocks Heap_Merge( head ); @@ -374,13 +429,13 @@ void *Heap_Reallocate(const char *File, int Line, void *__ptr, size_t __size) if(newSize <= head->Size) return __ptr; // Check if next block is free - nextHead = (void*)( (Uint)head + head->Size ); + nextHead = Heap_NextHead(head); // Extend into next block if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize) { Uint size = nextHead->Size + head->Size; - foot = (void*)( (Uint)nextHead + nextHead->Size - sizeof(tHeapFoot) ); + foot = Heap_ThisFoot(nextHead); // Exact Fit if(size == newSize) { head->Size = newSize; @@ -393,23 +448,26 @@ void *Heap_Reallocate(const char *File, int Line, void *__ptr, size_t __size) return __ptr; } // Create a new heap block - nextHead = (void*)( (Uint)head + newSize ); - nextHead->Size = size - newSize; - nextHead->Magic = MAGIC_FREE; - foot->Head = nextHead; // Edit 2nd footer - head->Size = newSize; // Edit first header - head->File = File; + // - Update old with new information + head->Size = newSize; + head->File = File; // Kinda counts as a new allocation head->Line = Line; head->ValidSize = __size; - // Create new footer - foot = (void*)( (Uint)head + newSize - sizeof(tHeapFoot) ); + // - Create new footer + foot = Heap_ThisFoot(head); foot->Head = head; foot->Magic = MAGIC_FOOT; + // - Create new header + nextHead = Heap_NextHead(head); + nextHead->Size = size - newSize; + nextHead->Magic = MAGIC_FREE; + // - Update old footer + foot->Head = nextHead; return __ptr; } // Extend downwards? - foot = (void*)( (Uint)head - sizeof(tHeapFoot) ); + foot = Heap_PrevFoot(head); nextHead = foot->Head; if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize) { @@ -417,38 +475,35 @@ void *Heap_Reallocate(const char *File, int Line, void *__ptr, size_t __size) // Inexact fit, split things up if(size > newSize) { - // TODO + // TODO: Handle splitting of downwards blocks Warning("[Heap ] TODO: Space efficient realloc when new size is smaller"); } // Exact fit - if(size >= newSize) - { - Uint oldDataSize; - // Set 1st (new/lower) header - nextHead->Magic = MAGIC_USED; - nextHead->Size = newSize; - nextHead->File = File; - nextHead->Line = Line; - nextHead->ValidSize = __size; - // Get 2nd (old) footer - foot = (void*)( (Uint)nextHead + newSize ); - foot->Head = nextHead; - // Save old data size - oldDataSize = head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead); - // Clear old header - head->Size = 0; - head->Magic = 0; - // Copy data - memcpy(nextHead->Data, __ptr, oldDataSize); - // Return - return nextHead->Data; - } - // On to the expensive then + Uint oldDataSize; + // Set 1st (new/lower) header + nextHead->Magic = MAGIC_USED; + nextHead->Size = newSize; + nextHead->File = File; + nextHead->Line = Line; + nextHead->ValidSize = __size; + // Get 2nd (old) footer + foot = Heap_ThisFoot(nextHead); + foot->Head = nextHead; + // Save old data size + oldDataSize = head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead); + // Clear old header + head->Size = 0; + head->Magic = 0; + // Copy data + memmove(nextHead->Data, __ptr, oldDataSize); + // Return + return nextHead->Data; } // Well, darn nextHead = Heap_Allocate( File, Line, __size ); + if(!nextHead) return NULL; nextHead -= 1; nextHead->File = File; nextHead->Line = Line; @@ -504,11 +559,17 @@ int Heap_IsHeapAddr(void *Ptr) */ void Heap_Validate(void) { - Heap_Dump(); + // Call dump non-verbosely. + // - If a heap error is detected, it'll print + Heap_ValidateDump(0); } -#if WARNINGS void Heap_Dump(void) +{ + Heap_ValidateDump(1); +} + +void Heap_ValidateDump(int bVerbose) { tHeapHead *head, *badHead; tHeapFoot *foot = NULL; @@ -521,16 +582,18 @@ void Heap_Dump(void) head = gHeapStart; while( (Uint)head < (Uint)gHeapEnd ) { - foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); - #if VERBOSE_DUMP - Log_Log("Heap", "%p (0x%P): 0x%08x (%i) %4C", - head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic); - Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic); - if(head->File) { - Log_Log("Heap", "%sowned by %s:%i", - (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line); + foot = Heap_ThisFoot(head); + + if( bVerbose ) + { + Log_Log("Heap", "%p (%P): 0x%08x (%i) %4C", + head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic); + Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic); + if(head->File) { + Log_Log("Heap", "%sowned by %s:%i", + (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line); + } } - #endif // Sanity Check Header if(head->Size == 0) { @@ -556,9 +619,10 @@ void Heap_Dump(void) break; } - #if VERBOSE_DUMP - Log_Log("Heap", ""); - #endif + if( bVerbose ) + { + Log_Log("Heap", ""); + } // All OK? Go to next head = foot->NextHead; @@ -575,24 +639,25 @@ void Heap_Dump(void) in_heap_dump = 0; return ; } - - #if !VERBOSE_DUMP - Log_Log("Heap", "%p (%P): 0x%08lx %i %4C", - head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic); - if(foot) - Log_Log("Heap", "Foot %p = {Head:%p,Magic:%4C}", foot, foot->Head, &foot->Magic); - if(head->File) { - Log_Log("Heap", "%sowned by %s:%i", - (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line); - } - Log_Log("Heap", ""); - #endif - + // If not verbose, we need to dump the failing block + if( !bVerbose ) + { + Log_Log("Heap", "%p (%P): 0x%08lx %i %4C", + head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic); + if(foot) + Log_Log("Heap", "Foot %p = {Head:%p,Magic:%4C}", foot, foot->Head, &foot->Magic); + if(head->File) { + Log_Log("Heap", "%sowned by %s:%i", + (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line); + } + Log_Log("Heap", ""); + } + badHead = head; // Work backwards - foot = (void*)( (tVAddr)gHeapEnd - sizeof(tHeapFoot) ); + foot = Heap_PrevFoot(gHeapEnd); Log_Log("Heap", "==== Going Backwards ==== (from %p)", foot); head = foot->Head; while( (tVAddr)head >= (tVAddr)badHead ) @@ -632,19 +697,16 @@ void Heap_Dump(void) if(head == badHead) break; - foot = (void*)( (tVAddr)head - sizeof(tHeapFoot) ); + foot = Heap_PrevFoot(head); head = foot->Head; Log_Debug("Heap", "head=%p", head); } - Panic("Heap_Dump - Heap is corrupted, kernel panic!"); + Panic("Heap_Dump - Heap is corrupted, kernel panic! (%p)", badHead); } -#endif -#if 1 void Heap_Stats(void) { - tHeapHead *head; int nBlocks = 0; int nFree = 0; int totalBytes = 0; @@ -652,10 +714,7 @@ void Heap_Stats(void) int maxAlloc=0, minAlloc=-1; int avgAlloc, frag, overhead; - for(head = gHeapStart; - (Uint)head < (Uint)gHeapEnd; - head = (void*)( (Uint)head + head->Size ) - ) + for( tHeapHead *head = gHeapStart; head < gHeapEnd; head = Heap_NextHead(head) ) { nBlocks ++; totalBytes += head->Size; @@ -681,7 +740,8 @@ void Heap_Stats(void) head->Data, MM_GetPhysAddr(&head->Data), head->Size); else Log_Debug("Heap", "%p (%P) - 0x%x (%i) Owned by %s:%i (%lli ms old)", - head->Data, MM_GetPhysAddr(&head->Data), head->Size, head->ValidSize, head->File, head->Line, + head->Data, MM_GetPhysAddr(&head->Data), head->Size, + head->ValidSize, head->File, head->Line, now() - head->AllocateTime ); #endif @@ -720,10 +780,7 @@ void Heap_Stats(void) memset(sizeCounts, 0, nBlocks*sizeof(sizeCounts[0])); - for(head = gHeapStart; - (Uint)head < (Uint)gHeapEnd; - head = (void*)( (Uint)head + head->Size ) - ) + for(tHeapHead *head = gHeapStart; head < gHeapEnd; head = (void*)( (tVAddr)head + head->Size ) ) { for( i = 0; i < nBlocks; i ++ ) { if( sizeCounts[i].Size == 0 ) @@ -735,12 +792,12 @@ void Heap_Stats(void) if( i == nBlocks ) continue; sizeCounts[i].Size = head->Size; sizeCounts[i].Count ++; - #if 1 - //Log("Heap_Stats: %i %p - 0x%x bytes (%s) (%i)", nBlocks, head, - // head->Size, (head->Magic==MAGIC_FREE?"FREE":"used"), i - // ); - //Log("Heap_Stats: sizeCounts[%i] = {Size:0x%x, Count: %i}", i, - // sizeCounts[i].Size, sizeCounts[i].Count); + #if 0 + Log("Heap_Stats: %i %p - 0x%x bytes (%s) (%i)", nBlocks, head, + head->Size, (head->Magic==MAGIC_FREE?"FREE":"used"), i + ); + Log("Heap_Stats: sizeCounts[%i] = {Size:0x%x, Count: %i}", i, + sizeCounts[i].Size, sizeCounts[i].Count); #endif } @@ -753,7 +810,6 @@ void Heap_Stats(void) } #endif } -#endif // === EXPORTS === EXPORT(Heap_Allocate);