Detailed FixedMalloc allocator output for verbose (bug=486099,r=lhansen)
authorTommy Reilly <treilly@adobe.com>
Fri, 20 Nov 2009 10:11:05 -0500
changeset 3181 38e90e12dcdb14bdddb87c4c326f1b8e3c8902f5
parent 3180 931a7aea969391f89b9ace529bfb6889296e5b1f
child 3182 d7d9ba597cbe8311b6a821bfd3c472c166b6bc4f
push id1744
push usertreilly@adobe.com
push dateFri, 20 Nov 2009 15:11:10 +0000
reviewerslhansen
bugs486099
Detailed FixedMalloc allocator output for verbose (bug=486099,r=lhansen)
MMgc/FixedMalloc.cpp
MMgc/FixedMalloc.h
MMgc/GC.cpp
MMgc/GCHeap.cpp
shell/avmshell-features.h
--- a/MMgc/FixedMalloc.cpp
+++ b/MMgc/FixedMalloc.cpp
@@ -191,17 +191,17 @@ namespace MMgc
 			totalAskSize += ask;
 			totalAllocated += allocated;
 		}
 
 #ifdef MMGC_MEMORY_PROFILER
 		totalAskSize += totalAskSizeLargeAllocs;
 #endif
 
-		// not entirely accurate
+		// not entirely accurate, assumes large allocations using all of last page (large ask size not stored)
 		totalAllocated += numLargeChunks * GCHeap::kBlockSize;
 	}
 
 	void *FixedMalloc::LargeAlloc(size_t size, FixedMallocOpts flags)
 	{
 		GCHeap::CheckForAllocSizeOverflow(size, GCHeap::kBlockSize+DebugSize());
 		
 		size += DebugSize();
@@ -269,10 +269,25 @@ namespace MMgc
 	size_t FixedMalloc::GetTotalSize()
 	{
 		size_t total = numLargeChunks;
 		for (int i=0; i<kNumSizeClasses; i++) {
 			total += m_allocs[i].GetNumChunks();
 		}	
 		return total;
 	}
+
+#ifdef MMGC_MEMORY_PROFILER
+	void FixedMalloc::DumpMemoryInfo()
+	{
+		size_t inUse, ask;
+		GetUsageInfo(ask, inUse);
+		GCLog("[mem] FixedMalloc total %d pages inuse %d bytes ask %d bytes\n", GetTotalSize(), inUse, ask);
+		for (int i=0; i<kNumSizeClasses; i++) {
+			m_allocs[i].GetUsageInfo(ask, inUse);
+			if( m_allocs[i].GetNumChunks() > 0)
+				GCLog("[mem] FixedMalloc[%d] total %d pages inuse %d bytes ask %d bytes\n", kSizeClasses[i], m_allocs[i].GetNumChunks(), inUse, ask);
+		}
+		GCLog("[mem] FixedMalloc[large] total %d pages\n", numLargeChunks);
+	}
+#endif
 }
 
--- a/MMgc/FixedMalloc.h
+++ b/MMgc/FixedMalloc.h
@@ -126,16 +126,20 @@ namespace MMgc
 		 */
 		void GetUsageInfo(size_t& totalAskSize, size_t& totalAllocated);
 		
 		/**
 		 * @return the number bytes currently allocated by FixedMalloc
 		 */
 		size_t GetBytesInUse();
 
+#ifdef MMGC_MEMORY_PROFILER
+		void DumpMemoryInfo();
+#endif
+
 	private:
 		// Initialize FixedMalloc.  Must be called from GCHeap during GCHeap setup.
 		void InitInstance(GCHeap *heap);
 		
 		// Destroy FixedMalloc and free all resources.
 		void DestroyInstance();
 		
 #ifdef MMGC_64BIT
--- a/MMgc/GC.cpp
+++ b/MMgc/GC.cpp
@@ -2026,24 +2026,27 @@ bail:
 		int inUse =  a->GetNumAlloc() * a->GetItemSize();
 		int maxAlloc =  a->GetMaxAlloc()* a->GetItemSize();
 
 		overhead = maxAlloc-inUse;
 		internal_waste = 0;
 
 		int efficiency = maxAlloc > 0 ? inUse * 100 / maxAlloc : 100;
 		if(inUse) {
-			GCLog("Allocator(%d):   %d%% efficiency %d bytes (%d kb) in use out of %d bytes (%d kb)\n", a->GetItemSize(), efficiency, inUse, inUse>>10, maxAlloc, maxAlloc>>10);
+			const char *name = a->ContainsPointers() ? a->ContainsRCObjects() ? "rc" : "gc" : "opaque";
+			if(heap->config.verbose)
+				GCLog("[mem] gc[%d] %s allocator:   %d%% efficiency %d bytes (%d kb) in use out of %d bytes (%d kb)\n", a->GetItemSize(), name, efficiency, inUse, inUse>>10, maxAlloc, maxAlloc>>10);
 #ifdef MMGC_MEMORY_PROFILER
 			if(heap->HooksEnabled())
 			{
 				size_t askSize = a->GetTotalAskSize();
 				internal_waste = inUse - askSize;
 				size_t internal_efficiency = askSize * 100 / inUse;
-				GCLog("\t\t\t\t %u%% internal efficiency %u bytes (%u kb) actually requested out of %d bytes(%d kb)\n", internal_efficiency, (uint32_t) askSize, (uint32_t)(askSize>>10), inUse, inUse>>10);
+				if(heap->config.verbose)
+					GCLog("\t\t\t\t %u%% internal efficiency %u bytes (%u kb) actually requested out of %d bytes(%d kb)\n", internal_efficiency, (uint32_t) askSize, (uint32_t)(askSize>>10), inUse, inUse>>10);
 			}
 #endif
 		}
 	}
 
 	void GC::DumpMemoryInfo()
 	{
 		size_t total = GetNumBlocks() * GCHeap::kBlockSize;
--- a/MMgc/GCHeap.cpp
+++ b/MMgc/GCHeap.cpp
@@ -1869,16 +1869,20 @@ namespace MMgc
 			gc->GetUsageInfo(ask, allocated);
 			gc_ask_total += ask;
 			gc_allocated_total += allocated;
 			gc_count += 1;
 			
 			gc_total += gc->GetNumBlocks() * kBlockSize;
 		}
 
+#ifdef MMGC_MEMORY_PROFILER
+		fixedMalloc.DumpMemoryInfo();
+#endif
+
 		// Gross stats are not meaningful if the profiler is running, see bugzilla 490014.
 		// Disabling their printing is just an expedient fix to avoid misleading data being
 		// printed.  There are other, more complicated, fixes we should adopt.
 
 		GCLog("[mem] ------- gross stats -----\n");
 #ifdef MMGC_MEMORY_PROFILER
 		if (GCHeap::GetGCHeap()->GetProfiler() == NULL)
 #endif
--- a/shell/avmshell-features.h
+++ b/shell/avmshell-features.h
@@ -160,27 +160,29 @@
 	#define NJ_VERBOSE_DISABLED 1
 	#define NJ_PROFILE_DISABLED 1
 #endif
 
 #ifndef AVMFEATURE_OVERRIDE_GLOBAL_NEW
   #define AVMFEATURE_OVERRIDE_GLOBAL_NEW 0
 #endif
 
+#ifndef AVMFEATURE_MEMORY_PROFILER
 #if AVMFEATURE_DEBUGGER
 	#if AVMSYSTEM_MAC && !(AVMSYSTEM_PPC && AVMSYSTEM_64BIT)
 		#define AVMFEATURE_MEMORY_PROFILER 1
 	#elif AVMSYSTEM_WIN32 && !AVMSYSTEM_ARM // note, does not require DEBUG
 		#define AVMFEATURE_MEMORY_PROFILER 1
 	#else
 		#define AVMFEATURE_MEMORY_PROFILER 0
 	#endif
 #else
 	#define AVMFEATURE_MEMORY_PROFILER 0
 #endif
+#endif
 
 #ifndef AVMFEATURE_API_VERSIONING
     #define AVMFEATURE_API_VERSIONING 0
 #endif
 
 #ifndef AVMFEATURE_CACHE_GQCN
   #define AVMFEATURE_CACHE_GQCN 1
 #endif