+ Log_Debug("PMem", "maxAddr = %P", maxAddr);
+ Log_Log("PMem", "Physical memory set up (%lli pages of ~%lli MiB used)",
+ giPhysAlloc, (giTotalMemorySize*PAGE_SIZE)/(1024*1024)
+ );
+}
+
+void MM_DumpStatistics(void)
+{
+ for( int i = 1; i < numAddrClasses; i ++ )
+ {
+ const int first = (i == 1 ? 0 : (1UL << (addrClasses[i-1] - 12)));
+ const int last = MIN( (1UL << (addrClasses[i] - 12)) - 1, giPageCount );
+ const int total = last - first + 1;
+
+ int nFree = 0;
+ int nMultiRef = 0;
+ int totalRefs = 0;
+ bool refpage_valid = !!MM_GetPhysAddr(&gaPageReferences[first]);
+
+ for( Uint pg = first; pg < last; pg ++ )
+ {
+ // Free chunk
+ if( gaPageBitmap[pg/32] == 0 )
+ {
+ int count = 32 - pg%32;
+ nFree += count;
+ pg += count - 1;
+ continue ;
+ }
+
+ // Single free
+ if( !(gaPageBitmap[pg/32] & (1 << pg%32)) )
+ {
+ nFree ++;
+ continue ;
+ }
+
+ // Check if reference page is valid
+ if( pg % (PAGE_SIZE/sizeof(gaPageReferences[0])) == 0 ) {
+ refpage_valid = !!MM_GetPhysAddr(&gaPageReferences[pg]);
+ }
+
+ //
+ if( refpage_valid && gaPageReferences[pg] > 1 ) {
+ totalRefs += gaPageReferences[pg];
+ nMultiRef ++;
+ }
+ else
+ totalRefs ++;
+ }
+
+ int nUsed = (total - nFree);
+ Log_Log("MMPhys", "%ipbit - %i/%i used, %i reused, %i average reference count",
+ addrClasses[i], nUsed, total, nMultiRef,
+ nMultiRef ? (totalRefs-(nUsed - nMultiRef)) / nMultiRef : 0
+ );
+ // TODO: Calculate fragentation of physical memory.
+ // > Somehow support defragmenting?
+
+ if( last == giPageCount )
+ break;
+ }
+ Log_Log("MMPhys", "%lli/%lli total pages used, 0 - %i possible free range",
+ giPhysAlloc, giTotalMemorySize, giLastPossibleFree);
+
+ int startpage = 0;
+ int last_refcnt = 0;
+ void *last_node = NULL;
+ for( int pg = 0; pg < giPageCount; pg ++ )
+ {
+ bool output = 0;
+ int refcount = 0;
+ void *node = NULL;
+ if( !(gaPageBitmap[pg/32] & (1 << pg%32)) )
+ {
+ // free
+ output = 1;
+ }
+ else
+ {
+ refcount = MM_GetPhysAddr(&gaPageReferences[pg]) ? gaPageReferences[pg] : 1;
+ node = MM_GetPhysAddr(&gaPageNodes[pg]) ? gaPageNodes[pg] : NULL;
+
+ if( last_refcnt != refcount || last_node != node )
+ output = 1;
+ }
+ if( output || pg == giPageCount-1 )
+ {
+ if( last_refcnt > 0 )
+ Debug("0x%4x+%i: node=%p refcount=%i", pg-startpage, last_node, last_refcnt);
+ startpage = pg;
+ }
+ last_refcnt = refcount;
+ last_node = node;
+ }