WIP
authorbenjamin@smedbergs.us
Tue, 12 Feb 2008 23:19:24 -0500
changeset 39 6932d8476f00
parent 38 239589f2b220
child 40 432248c58b48
push id1
push userbsmedberg@mozilla.com
push dateMon, 21 Apr 2008 01:54:18 +0000
WIP
export-gcthread
series
valgrind-annotations
new file mode 100644
--- /dev/null
+++ b/export-gcthread
@@ -0,0 +1,12 @@
+diff --git a/MMgc/GCThreads.h b/MMgc/GCThreads.h
+--- a/MMgc/GCThreads.h
++++ b/MMgc/GCThreads.h
+@@ -178,7 +178,7 @@ namespace MMgc
+     };
+ 
+ 	/** A catchall object for per-thread state. */
+-	class GCThread {
++	class MMGC_API GCThread {
+ 	public:
+ 		static void Init();
+ 		static void Destroy();
--- a/series
+++ b/series
@@ -5,8 +5,10 @@ const-workitem.patch
 gcstack-access
 workitems-notgc-noassert
 gc-graph #+graphviz
 alloc-backtrace #+graphviz
 enable-traces
 debug-print-finalizers
 finalizable-merge-fixup
 remove-finalize-method
+export-gcthread
+valgrind-annotations
new file mode 100644
--- /dev/null
+++ b/valgrind-annotations
@@ -0,0 +1,239 @@
+Add valgrind annotations for MMgc allocations. Note that there are some extraneous changes to set the current work queue correctly... I need to split those hunks out :-(
+
+diff --git a/MMgc/FixedMalloc.cpp b/MMgc/FixedMalloc.cpp
+--- a/MMgc/FixedMalloc.cpp
++++ b/MMgc/FixedMalloc.cpp
+@@ -79,6 +79,8 @@ namespace MMgc
+ 
+ 	FixedMalloc::FixedMalloc(GCHeap* heap)
+ 	{
++		VALGRIND_CREATE_MEMPOOL(this, 0, 1);
++
+ 		m_heap = heap;
+ 		// Create all the allocators up front (not lazy)
+ 		// so that we don't have to check the pointers for
+@@ -98,6 +100,7 @@ namespace MMgc
+ 			FixedAllocSafe *a = m_allocs[i];
+ 			delete a;
+ 		}		
++		VALGRIND_DESTROY_MEMPOOL(this);
+ 	}
+ 
+ 	size_t FixedMalloc::Allocated()
+diff --git a/MMgc/FixedMalloc.h b/MMgc/FixedMalloc.h
+--- a/MMgc/FixedMalloc.h
++++ b/MMgc/FixedMalloc.h
+@@ -38,6 +38,8 @@
+ #ifndef __Malloc__
+ #define __Malloc__
+ 
++#include <valgrind/memcheck.h>
++#include <stdio.h>
+ 
+ namespace MMgc
+ {
+@@ -73,6 +75,9 @@ namespace MMgc
+ 			} else {
+ 				item = LargeAlloc(size);
+ 			}
++                        VALGRIND_MEMPOOL_ALLOC(this, item, size);
++			VALGRIND_CHECK_MEM_IS_DEFINED(item, size);
++			fprintf(stderr, "FixedMalloc::Alloc = %p\n", item);
+ 			return item;
+ 		}
+ 
+@@ -80,6 +85,8 @@ namespace MMgc
+ 		{
+ 			if(item == 0)
+ 				return;
++
++			VALGRIND_MEMPOOL_FREE(this, item);
+ 
+ 			// small things are never allocated on the 4K boundary b/c the block
+ 			// header structure is stored there, large things always are		
+diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
+--- a/MMgc/GC.cpp
++++ b/MMgc/GC.cpp
+@@ -110,6 +110,8 @@ extern "C" greg_t _getsp(void);
+ #define SAMPLE_FRAME(_x, _s) 
+ #define SAMPLE_CHECK() 
+ #endif
++
++#include <valgrind/memcheck.h>
+ 
+ namespace MMgc
+ {
+@@ -294,7 +296,9 @@ namespace MMgc
+ 		GCAssert (sizeof(sintptr) == 4);
+ 		GCAssert (sizeof(uintptr) == 4);	
+ 		#endif		
+-	
++
++		VALGRIND_CREATE_MEMPOOL(this, 0, 0);
++
+ #ifdef MMGC_DRC
+ 		zct.gc = this;
+ #endif
+@@ -409,6 +413,8 @@ namespace MMgc
+ 		while(m_callbacks) {
+ 			m_callbacks->Destroy();			
+ 		}
++
++		VALGRIND_DESTROY_MEMPOOL(this);
+ 	}
+ 
+ 	void GC::Collect()
+@@ -746,6 +752,12 @@ namespace MMgc
+ 			memset(item, 0, Size(item));
+ 		}
+ #endif
++
++		VALGRIND_MEMPOOL_ALLOC(this, item, size);
++		if (flags & kZero) {
++			int h = VALGRIND_MAKE_MEM_DEFINED(item, size);
++			VALGRIND_DISCARD(h);
++		}
+ 
+ 		return item;
+ 	}
+@@ -1543,6 +1555,8 @@ bail:
+ 		{
+ 			const void *val = GC::Pointer(*p++);	
+ 			
++			int valhandle = VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
++
+ 			if(val < _memStart || val >= _memEnd)
+ 				continue;
+ 
+@@ -1558,6 +1572,8 @@ bail:
+ 				RCObject *obj = (RCObject*)val;
+ 				obj->Pin();
+ 			}
++
++			VALGRIND_DISCARD(valhandle);
+ 		}
+ 	}
+ 			
+@@ -2340,12 +2356,16 @@ bail:
+ #ifdef GCHEAP_LOCK
+ 			GCAcquireSpinlock lock(m_rootListLock);
+ #endif
++			m_currentQueue = &m_incrementalWork;
++
+ 			GCRoot *r = m_roots;
+ 			while(r) {
+ 				GCWorkItem item = r->GetWorkItem();
+ 				MarkItem(item, m_incrementalWork);
+ 				r = r->next;
+ 			}
++
++			m_currentQueue = NULL;
+ 		}
+ 		markTicks += GetPerformanceCounter() - start;
+ 		IncrementalMark();
+@@ -2482,6 +2502,7 @@ bail:
+ 		{
+ 			int b = SetMark(wi.ptr);
+ 			(void)b;
++#if 0
+ #ifdef _DEBUG
+ 			// def ref validation does a Trace which can 
+ 			// cause things on the work queue to be already marked
+@@ -2490,6 +2511,7 @@ bail:
+ 				GCAssert(!b);
+ 			}
+ #endif			
++#endif
+ 		}
+ 		else
+ 		{
+@@ -2509,6 +2531,8 @@ bail:
+ 		while(p < end) 
+ 		{
+ 			uintptr val = *p++;  
++			
++			int valhandle = VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
+ 
+ 			if(val < _memStart || val >= _memEnd)
+ 				continue;
+@@ -2520,6 +2544,8 @@ bail:
+ 			{
+ 				const void *item;
+ 				GCAlloc::GCBlock *block = (GCAlloc::GCBlock*) (val & ~0xFFF);
++
++				VALGRIND_CHECK_MEM_IS_DEFINED(&block, sizeof(GCAlloc::GCBlock*));
+ 
+ #ifdef MMGC_INTERIOR_PTRS
+ 				item = (void*) val;
+@@ -2660,6 +2686,8 @@ bail:
+ 					#endif
+ 				}
+ 			}
++
++			VALGRIND_DISCARD(valhandle);
+ 		}
+ 	}
+ 
+@@ -2775,6 +2803,8 @@ bail:
+ 		// finished in Sweep
+ 		sweepStart = GetPerformanceCounter();
+ 		
++		m_currentQueue = &m_incrementalWork;
++
+ 		// mark roots again, could have changed (alternative is to put WB's on the roots
+ 		// which we may need to do if we find FinishIncrementalMark taking too long)
+ 		
+@@ -2801,6 +2831,8 @@ bail:
+ 		}
+ 
+ 		MarkQueueAndStack(m_incrementalWork);
++
++		m_currentQueue = NULL;
+ 
+ #ifdef _DEBUG
+ 		// need to traverse all marked objects and make sure they don't contain
+diff --git a/MMgc/GCAlloc.cpp b/MMgc/GCAlloc.cpp
+--- a/MMgc/GCAlloc.cpp
++++ b/MMgc/GCAlloc.cpp
+@@ -711,5 +711,7 @@ start:
+ #endif
+ 		// Add this item to the free list
+ 		*((void**)item) = oldFree;	
++
++                VALGRIND_MEMPOOL_FREE(GC::GetGC(item), GetUserPointer(item));
+ 	}
+ }
+diff --git a/MMgc/GCHeap.cpp b/MMgc/GCHeap.cpp
+--- a/MMgc/GCHeap.cpp
++++ b/MMgc/GCHeap.cpp
+@@ -43,6 +43,8 @@
+ #endif
+ 
+ #include "MMgc.h"
++
++#include <valgrind/memcheck.h>
+ 
+ namespace MMgc
+ {
+@@ -182,6 +184,9 @@ namespace MMgc
+ 			if (!block) {
+ 				return NULL;
+ 			}
++
++                        VALGRIND_MAKE_MEM_NOACCESS(block->baseAddr,
++                                                   block->size * kBlockSize);
+ 
+ 			GCAssert(block->size == size);
+ 			
+diff --git a/MMgc/GCLargeAlloc.cpp b/MMgc/GCLargeAlloc.cpp
+--- a/MMgc/GCLargeAlloc.cpp
++++ b/MMgc/GCLargeAlloc.cpp
+@@ -100,6 +100,8 @@ namespace MMgc
+ 
+ 		if(b->flags & kHasWeakRef)
+ 			b->gc->ClearWeakRef(GetUserPointer(item));
++
++                VALGRIND_MEMPOOL_FREE(b->gc, GetUserPointer(item));
+ 
+ 		LargeBlock **prev = &m_blocks;
+ 		while(*prev)