head->Magic = MAGIC_USED;
head->File = File;
head->Line = Line;
+ head->ValidSize = __Bytes;
+ head->AllocateTime = now();
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", head->Data, head->Size, __builtin_return_address(0));
+ Debug("[Heap ] Malloc'd %p (%i bytes), returning to %p", head->Data, head->Size, __builtin_return_address(0));
#endif
return head->Data;
}
best->Magic = MAGIC_USED; // Mark block as used
best->File = File;
best->Line = Line;
+ best->ValidSize = __Bytes;
+ best->AllocateTime = now();
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0));
+ Debug("[Heap ] Malloc'd %p (%i bytes), returning to %s:%i", best->Data, best->Size, File, Line);
#endif
return best->Data;
}
best->Magic = MAGIC_USED; // Mark block as used
best->File = File;
best->Line = Line;
+ best->AllocateTime = now();
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Log_Debug("Heap", "newhead(%p)->Size = 0x%x", newhead, newhead->Size);
- Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i",
+ Debug("[Heap ] Malloc'd %p (0x%x bytes), returning to %s:%i",
best->Data, best->Size, File, Line);
#endif
return best->Data;
*/
void Heap_Deallocate(void *Ptr)
{
- tHeapHead *head;
+ tHeapHead *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
tHeapFoot *foot;
- #if DEBUG_TRACE
- Log_Log("Heap", "free: Ptr = %p", Ptr);
- Log_Log("Heap", "free: Returns to %p", __builtin_return_address(0));
- #endif
-
// 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) ) {
Log_Warning("Heap", "free - Passed a non-aligned address (%p)", Ptr);
return ;
#if !VERBOSE_DUMP
- Log_Log("Heap", "%p (0x%llx): 0x%08lx %i %4C",
+ Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
- Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
+ if(foot)
+ Log_Log("Heap", "Backlink = %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);
head = foot->Head;
while( (tVAddr)head >= (tVAddr)badHead )
{
- Log_Log("Heap", "%p (0x%llx): 0x%08lx %i %4C",
+ Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
if(head->File)
// Print the block info?
#if 1
- Log_Debug("Heap", "%p (0x%x) - 0x%x (%i) Owned by %s:%i",
- head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line);
+ if( head->Magic == MAGIC_FREE )
+ Log_Debug("Heap", "%p (%P) - 0x%x free",
+ head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size);
+ else
+ Log_Debug("Heap", "%p (%P) - 0x%x (%i) Owned by %s:%i (%lli ms old)",
+ head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line,
+ now() - head->AllocateTime
+ );
#endif
}
Log_Log("Heap", "%i blocks (0x%x bytes)", nBlocks, totalBytes);
Log_Log("Heap", "%i free blocks (0x%x bytes)", nFree, freeBytes);
- frag = (nFree-1)*10000/nBlocks;
+ if(nBlocks != 0)
+ frag = (nFree-1)*10000/nBlocks;
+ else
+ frag = 0;
Log_Log("Heap", "%i.%02i%% Heap Fragmentation", frag/100, frag%100);
avgAlloc = (totalBytes-freeBytes)/(nBlocks-nFree);
- overhead = (sizeof(tHeapFoot)+sizeof(tHeapHead))*10000/avgAlloc;
+ if(avgAlloc != 0)
+ overhead = (sizeof(tHeapFoot)+sizeof(tHeapHead))*10000/avgAlloc;
+ else
+ overhead = 0;
Log_Log("Heap", "Average allocation: %i bytes, Average Overhead: %i.%02i%%",
avgAlloc, overhead/100, overhead%100
);