After pushing lots of changes.
authorjorendorff@mozilla.com
Tue, 08 Jan 2008 08:17:09 -0600
changeset 34 ec1155ba48ec
parent 33 89e259bfffb2
child 35 9997f3ca8108
child 36 90c061d30873
push id1
push userbsmedberg@mozilla.com
push dateMon, 21 Apr 2008 01:54:18 +0000
After pushing lots of changes.
mmgc-bit-checks
mmgc-graphviz
mmgc-threadsafe
mmgc-threadsafe-gctests
series
unmerged-edits-to-mmgc-threadsafe
--- a/mmgc-bit-checks
+++ b/mmgc-bit-checks
@@ -1,12 +1,12 @@
 diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 --- a/MMgc/GC.cpp
 +++ b/MMgc/GC.cpp
-@@ -2841,27 +2841,6 @@ bail:
+@@ -2881,27 +2881,6 @@ bail:
  		collecting = false;
  		marking = false;
  	}
 -
 -	int GC::IsWhite(const void *item)
 -	{
 -		// back up to real beginning
 -		item = GetRealPointer((const void*) item);
@@ -24,32 +24,32 @@ diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 -			// in the page map (ie use 2).
 -			return GCLargeAlloc::IsWhite(item);
 -		}
 -		return false;
 -	}
  	
  	// TODO: fix headers so this can be declared there and inlined
  	void GC::WriteBarrierWrite(const void *address, const void *value)
-@@ -2963,11 +2942,6 @@ bail:
+@@ -3003,11 +2982,6 @@ bail:
  	{
  		int bits = GetPageMapValue((uintptr)item);
  		return (bits != 0);
 -	}
 -
 -	bool GC::IsQueued(const void *item)
 -	{
 -		return !GetMark(item) && !IsWhite(item);
  	}
  
  	uint32 *GC::GetBits(int numBytes, int sizeClass)
 diff --git a/MMgc/GC.h b/MMgc/GC.h
 --- a/MMgc/GC.h
 +++ b/MMgc/GC.h
-@@ -735,6 +735,17 @@ namespace MMgc
+@@ -785,6 +785,17 @@ namespace MMgc
  
  		}
  
 +	private:
 +		__forceinline static void CheckItem(const void *&item)
 +		{
 +#if defined(DEBUG) || defined(MEMORY_INFO)
 +			GCAssert(item != NULL);
@@ -57,17 +57,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +			GCAssert(GetGC(item)->IsPointerToGCPage(item));
 +#endif
 +		}
 +
 +	public:
  		/**
  		 * Tracers should employ GetMark and SetMark to
  		 * set the mark bits during the mark pass.
-@@ -753,25 +764,28 @@ namespace MMgc
+@@ -803,25 +814,28 @@ namespace MMgc
  
  		static int SetMark(const void *item)
  		{
 -			GCAssert(item != NULL);
 -#ifdef MEMORY_INFO
 -			GC *gc = GetGC(item);	
 -			item = GetRealPointer(item);
 -			GCAssert(gc->IsPointerToGCPage(item));
@@ -99,17 +99,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		}
 +
 +		static void SetQueued(const void *item)
 +		{
 +			CheckItem(item);
  			if (GCLargeAlloc::IsLargeBlock(item)) {
  				GCLargeAlloc::SetQueued(item);
  			} else {
-@@ -779,13 +793,24 @@ namespace MMgc
+@@ -829,13 +843,24 @@ namespace MMgc
  			}
  		}
  
 +		/**
 +		 * True if the item is neither marked nor queued.
 +		 *
 +		 * @access Requires(request || exclusiveGC)
 +		 */
@@ -129,75 +129,75 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 -			GC *gc = GetGC(item);	
 -			item = GetRealPointer(item);
 -			GCAssert(gc->IsPointerToGCPage(item));
 -#endif 			
 +			CheckItem(item);
  			if (GCLargeAlloc::IsLargeBlock(item)) {
  				GCLargeAlloc::ClearFinalized(item);
  			} else {
-@@ -795,11 +820,7 @@ namespace MMgc
+@@ -845,11 +870,7 @@ namespace MMgc
  
  		static void SetFinalize(const void *item)
  		{
 -#ifdef MEMORY_INFO
 -			GC *gc = GetGC(item);	
 -			item = GetRealPointer(item);
 -			GCAssert(gc->IsPointerToGCPage(item));
 -#endif 			
 +			CheckItem(item);
  			if (GCLargeAlloc::IsLargeBlock(item)) {
  				GCLargeAlloc::SetFinalize(item);
  			} else {
-@@ -809,11 +830,7 @@ namespace MMgc
+@@ -859,11 +880,7 @@ namespace MMgc
  
  		static int IsFinalized(const void *item)
  		{
 -#ifdef MEMORY_INFO
 -			GC *gc = GetGC(item);	
 -			item = GetRealPointer(item);
 -			GCAssert(gc->IsPointerToGCPage(item));
 -#endif 			
 +			CheckItem(item);
  			if (GCLargeAlloc::IsLargeBlock(item)) {
  				return GCLargeAlloc::IsFinalized(item);
  			} else {
-@@ -823,11 +840,7 @@ namespace MMgc
+@@ -873,11 +890,7 @@ namespace MMgc
  
  		static int HasWeakRef(const void *item)
  		{
 -#ifdef MEMORY_INFO
 -			GC *gc = GetGC(item);	
 -			item = GetRealPointer(item);
 -			GCAssert(gc->IsPointerToGCPage(item));
 -#endif 			
 +			CheckItem(item);
  			if (GCLargeAlloc::IsLargeBlock(item)) {
  				return GCLargeAlloc::HasWeakRef(item);
  			} else {
-@@ -1007,9 +1020,6 @@ namespace MMgc
+@@ -1057,9 +1070,6 @@ namespace MMgc
  		/** @access Requires(request || exclusiveGC) */
  		bool IsGCMemory (const void *);
  
 -		/** @access Requires(request || exclusiveGC) */
 -		bool IsQueued(const void *item);
 -
  		static uint64 GetPerformanceCounter();
  		static uint64 GetPerformanceFrequency();
  		
-@@ -1177,9 +1187,6 @@ namespace MMgc
- 		GCStack<GCWorkItem> m_incrementalWork;
+@@ -1244,9 +1254,6 @@ namespace MMgc
  		void StartIncrementalMark();
  		void FinishIncrementalMark();
--
+ 
 -		/** @access Requires(request || exclusiveGC) */
 -		int IsWhite(const void *item);
- 
+-		
  		/** @access ReadWrite(request, exclusiveGC) */
  		uint64 lastMarkTicks;
+ 		/** @access ReadWrite(request, exclusiveGC) */
 diff --git a/MMgc/GCAlloc.h b/MMgc/GCAlloc.h
 --- a/MMgc/GCAlloc.h
 +++ b/MMgc/GCAlloc.h
 @@ -110,6 +110,13 @@ namespace MMgc
  			return SetBit(block, GetIndex(block, item), kQueued);
  		}
  		
 +		static bool IsQueued(const void *item)
--- a/mmgc-graphviz
+++ b/mmgc-graphviz
@@ -1,33 +1,33 @@
 diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 --- a/MMgc/GC.cpp
 +++ b/MMgc/GC.cpp
-@@ -280,6 +280,9 @@ namespace MMgc
+@@ -274,6 +274,9 @@ namespace MMgc
  #else
  		  disableThreadCheck(false)
  #endif
 +#ifdef MMGC_GRAPHVIZ
 +		  , m_gvFile(NULL)
 +#endif
  	{
  		// sanity check for all our types
  		GCAssert (sizeof(int8) == 1);
-@@ -352,6 +355,10 @@ namespace MMgc
+@@ -346,6 +349,10 @@ namespace MMgc
  
  	GC::~GC()
  	{
 +#ifdef MMGC_GRAPHVIZ
 +		StopGraphing();
 +#endif
 +
  		// Force all objects to be destroyed
  		destroying = true;
  		ClearMarks();
-@@ -541,7 +548,19 @@ namespace MMgc
+@@ -539,7 +546,19 @@ namespace MMgc
  				cb->enterExclusiveGCNoLock();
  		}
  
 +#ifdef MMGC_GRAPHVIZ
 +		if (m_gvFile) {
 +			fprintf(m_gvFile, "digraph C%d {\n", sweeps);
 +			fprintf(m_gvFile, "    node [shape=box];\n");
 +		}
@@ -37,17 +37,17 @@ diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 +
 +#ifdef MMGC_GRAPHVIZ
 +		if (m_gvFile)
 +			fprintf(m_gvFile, "}\n");
 +#endif
  
  #ifdef MMGC_THREADSAFE
  		m_lock.Acquire();
-@@ -615,6 +634,46 @@ namespace MMgc
+@@ -597,6 +616,46 @@ namespace MMgc
  #endif
  	}
  
 +#define GRAPHVIZ_ROOT_STYLE "style=\"filled\", color=\"#ccddbb\""
 +#define GRAPHVIZ_OBJECT_STYLE "style=\"filled\", color=\"#b3cc99\""
 +#define GRAPHVIZ_CONSERVATIVE_EDGE_STYLE "color=\"#808080\""
 +
 +#ifdef MMGC_GRAPHVIZ
@@ -81,78 +81,78 @@ diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 +					   const void *toObj,
 +					   const char *style)
 +	{
 +		if (m_gvFile)
 +			fprintf(m_gvFile, "    P%p -> P%p [%s];\n", fromObj, toObj, style);
 +	}
 +#endif
 +
+ #ifdef _DEBUG
  	void GC::Trace(const void *stackStart/*=NULL*/, size_t stackSize/*=0*/)
  	{
- 		ASSERT_EXCLUSIVE_GC();
-@@ -634,6 +693,16 @@ namespace MMgc
+@@ -617,6 +676,16 @@ namespace MMgc
  			GCRoot *r = m_roots;
  			while(r) {
  				GCWorkItem item = r->GetWorkItem();
 +#ifdef MMGC_GRAPHVIZ
 +				if (m_gvFile) {
 +					fprintf(m_gvFile,
 +							"    P%p [label=\"root at %p\", %s];\n",
 +							item.ptr,
 +							item.ptr,
 +							GRAPHVIZ_ROOT_STYLE);
 +				}
 +#endif
 +
  				MarkItem(item, work);
  				r = r->next;
  			}
-@@ -2248,7 +2317,6 @@ bail:
+@@ -2290,7 +2359,6 @@ bail:
  #undef ALLOCA_AND_FILL_WITH_SPACES
  #endif
  
 -
  	void GC::StartIncrementalMark()
  	{
  		GCAssert(!marking);
-@@ -2417,6 +2485,11 @@ bail:
+@@ -2459,6 +2527,11 @@ bail:
  
  	void GC::MarkItem(GCWorkItem &wi, GCStack<GCWorkItem> &work)
  	{
 +#ifdef MMGC_GRAPHVIZ
 +		if (wi.IsGCItem())
 +			GraphNode(wi.ptr, GRAPHVIZ_OBJECT_STYLE);
 +#endif
 +
  		size_t size = wi.GetSize();
  		uintptr *p = (uintptr*) wi.ptr;
  
-@@ -2503,6 +2576,9 @@ bail:
+@@ -2545,6 +2618,9 @@ bail:
  				{
  					if(block->alloc->ContainsPointers())
  					{
 +#ifdef MMGC_GRAPHVIZ
 +						GraphEdge(wi.ptr, p, item, GRAPHVIZ_CONSERVATIVE_EDGE_STYLE);
 +#endif
  						// try custom marking
  						if ((bits2 & (GCAlloc::kFinalize<<shift)) != 0
  							&& ((GCFinalizedObject *) GetUserPointer(item))->CustomMark())
-@@ -2581,6 +2657,10 @@ bail:
+@@ -2623,6 +2699,10 @@ bail:
  					size_t usize = b->usableSize;
  					if((b->flags & GCLargeAlloc::kContainsPointers) != 0) 
  					{
 +#ifdef MMGC_GRAPHVIZ
 +						GraphEdge(wi.ptr, p, item, GRAPHVIZ_CONSERVATIVE_EDGE_STYLE);
 +#endif
 +
  						// try custom marking
  						if ((b->flags & GCLargeAlloc::kFinalizeFlag) != 0
  							&& ((GCFinalizedObject *) GetUserPointer(item))->CustomMark())
-@@ -3204,5 +3284,4 @@ bail:
+@@ -3239,5 +3319,4 @@ bail:
  	}
  #endif
  
 -
  }
 diff --git a/MMgc/GC.h b/MMgc/GC.h
 --- a/MMgc/GC.h
 +++ b/MMgc/GC.h
@@ -162,35 +162,35 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
  #define __GC__
 +
 +#ifdef MMGC_GRAPHVIZ
 +#include <typeinfo>
 +#endif
  
  #if defined MMGC_IA32
  
-@@ -1519,8 +1523,8 @@ private:
+@@ -1590,8 +1594,8 @@ private:
  #endif
  #endif
  
 -public:
  #ifdef MEMORY_INFO
 +	public:
  		void DumpBackPointerChain(void *o);
  
  		// debugging routine that records who marked who, can be used to
-@@ -1530,6 +1534,7 @@ public:
+@@ -1601,6 +1605,7 @@ public:
  		static void WriteBackPointer(const void *item, const void *container, size_t itemSize);
  #endif
  #ifdef _DEBUG
 +	public:
  		// Dump a list of objects that have pointers to the given location.
  		void WhosPointingAtMe(void* me, int recurseDepth=0, int currentDepth=0);
  
-@@ -1713,6 +1718,31 @@ public:
+@@ -1784,6 +1789,31 @@ public:
  		 * @access Requires(m_lock)
  		 */
  		GCCondition m_condNoRequests;
 +#endif
 +
 +#ifdef MMGC_GRAPHVIZ
 +	public:
 +		void StartGraphing(const char *filename)
@@ -246,25 +246,27 @@ diff --git a/MMgc/GCObject.h b/MMgc/GCOb
 @@ -39,6 +39,7 @@
  #ifndef __GCObject__
  #define __GCObject__
  
 +#include <string>
  
  // VC++ wants these declared
  //void *operator new(size_t size);
-@@ -136,6 +137,8 @@ namespace MMgc
- 	public:
- 		GCWeakRef *GetWeakRef() const;
- 
+@@ -126,6 +127,10 @@ namespace MMgc
+ 		 * nothing and returns false.
+ 		 */
+ 		virtual bool CustomMark() { return false; }
++
++#ifdef MMGC_GRAPHVIZ
 +		virtual std::string GetRepr() const;
-+
- 		static void *operator new(size_t size, GC *gc, size_t extra = 0);
- 		static void operator delete (void *gcObject);
++#endif
  	};
+ 
+ 	/**
 diff --git a/MMgc/macbuild.h b/MMgc/macbuild.h
 --- a/MMgc/macbuild.h
 +++ b/MMgc/macbuild.h
 @@ -66,6 +66,7 @@
   */
  #ifdef DEBUG
  #define MEMORY_INFO
 +#define MMGC_GRAPHVIZ
deleted file mode 100644
--- a/mmgc-threadsafe
+++ /dev/null
@@ -1,208 +0,0 @@
-diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
---- a/MMgc/GC.cpp
-+++ b/MMgc/GC.cpp
-@@ -431,11 +431,12 @@ namespace MMgc
- 
- 		// invoke precollect callback
- 		bool vetoed = false;
--		GCCallback *cb = m_callbacks;
--		while (cb) {
--			if (!cb->precollect())
--				vetoed = true;
--			cb = cb->nextCB;
-+		{
-+			USING_CALLBACK_LIST(this);
-+			for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB) {
-+				if (!cb->precollect())
-+					vetoed = true;
-+			}
- 		}
- 
- #ifdef MMGC_THREADSAFE
-@@ -568,6 +569,12 @@ namespace MMgc
- 		if (!callerHoldsLock)
- 			m_lock.Release();
- #endif
-+
-+		{
-+			USING_CALLBACK_LIST(this);
-+			for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB)
-+				cb->postcollect();
-+		}
- 	}
- 
- 	void GC::CollectImpl()
-@@ -618,8 +625,11 @@ namespace MMgc
- 		SAMPLE_CHECK();
- 
- 		// invoke lastmark on all callbacks
--		for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB)
--			cb->lastmark(work);
-+		{
-+			USING_CALLBACK_LIST(this);
-+			for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB)
-+				cb->lastmark(work);
-+		}
- 
- 		if(stackStart == NULL) {
- 			MarkQueueAndStack(work);
-@@ -646,6 +656,9 @@ namespace MMgc
- 
- 	void *GC::AllocAlreadyLocked(size_t size, int flags/*0*/, int skip/*3*/)
- 	{
-+#ifdef MMGC_THREADSAFE
-+		GCAssert(GCThread::GetCurrentThread()->IsInActiveRequest());
-+#endif
- #ifdef DEBUGGER
- 		avmplus::AvmCore *core = (avmplus::AvmCore*)GetGCContextVariable(GCV_AVMCORE);
- 		if(core)
-@@ -2730,8 +2743,11 @@ bail:
- 		}
- 
- 		// invoke lastmark on all callbacks
--		for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB)
--			cb->lastmark(m_incrementalWork);
-+		{
-+			USING_CALLBACK_LIST(this);
-+			for (GCCallback *cb = m_callbacks; cb; cb = cb->nextCB)
-+				cb->lastmark(m_incrementalWork);
-+		}
- 
- 		MarkQueueAndStack(m_incrementalWork);
- 
-@@ -2978,7 +2994,8 @@ bail:
- 
- 	void GC::AddEdgeCallback(GCEdgeCallback *cb)
- 	{
--		CheckThread();
-+		USING_CALLBACK_LIST(this);
-+
- 		cb->prevCB = NULL;
- 		cb->nextCB = m_edgeCallbacks;
- 		if(m_edgeCallbacks)
-@@ -2988,7 +3005,8 @@ bail:
- 
- 	void GC::RemoveEdgeCallback(GCEdgeCallback *cb)
- 	{
--		CheckThread();
-+		USING_CALLBACK_LIST(this);
-+
- 		if( m_edgeCallbacks == cb )
- 			m_edgeCallbacks = cb->nextCB;
- 		else
-@@ -3000,12 +3018,12 @@ bail:
- 
- 	void GC::FireFoundEdgeTo(const void *p)
- 	{
-+		// Don't acquire the spinlock here because (a) that would really hurt
-+		// performance; (b) the m_edgeCallbacks list, unlike the m_callbacks
-+		// list, is protected by the request model.
- 		p = GetUserPointer(p);
--		GCEdgeCallback *cb = m_edgeCallbacks;
--		while(cb) {
-+		for (GCEdgeCallback *cb = m_edgeCallbacks; cb; cb = cb->nextCB)
- 			cb->foundEdgeTo(p);
--			cb = cb->nextCB;
--		}
- 	}
- 
- 	void GC::PushWorkItem(GCStack<GCWorkItem> &stack, GCWorkItem item)
-diff --git a/MMgc/GC.h b/MMgc/GC.h
---- a/MMgc/GC.h
-+++ b/MMgc/GC.h
-@@ -258,16 +258,25 @@ namespace MMgc
- 		void Destroy();
- 
- 		/**
--		 * This method is called from GC::Collect(), before
--		 * anything else, even in cases where it's logically
--		 * certain that collection <em>will not start</em>
--		 * (e.g. because we're already collecting, or GC is
-+		 * GC::Collect() fires this callback before anything else, even in
-+		 * cases where it's logically certain that collection <em>will not
-+		 * start</em> (e.g. because we're already collecting, or GC is
- 		 * disabled).
-+		 *
-+		 * In an MMGC_THREADSAFE build, it is unspecified whether the calling
-+		 * thread holds the gc-wide lock when this callback is called.
-+		 * Multiple threads may fire this callback concurrently.
- 		 *
- 		 * Returns true to allow collection to happen, false
- 		 * to veto.
- 		 */
- 		virtual bool precollect() { return true; }
-+
-+		/**
-+		 * GC::Collect() fires this callback after everything else,
-+		 * only if collection actually happened in this thread.
-+		 */
-+		virtual void postcollect() {}
- 
- 		/**
- 		 * This method is invoked during the last mark phase
-@@ -279,6 +288,8 @@ namespace MMgc
- 		 * provided by the GCCallback base class.  The
- 		 * corresponding methods of <code>class GC</code> are
- 		 * private.)
-+		 *
-+		 * @access Requires(gc->exclusiveGC)
- 		 */
- 		virtual void lastmark(GCStack<GCWorkItem> &) {}
- 
-@@ -397,6 +408,17 @@ namespace MMgc
- 	{
- 		friend class GC;
- 	public:
-+		/**
-+		 * Create an edge callback.
-+		 *
-+		 * If `gc` is non-null, this constructor adds this GCEdgeCallback to a
-+		 * list of callbacks managed by `gc`.  This means the new object
-+		 * immediately starts receiving calls, even if it isn't fully
-+		 * constructed yet, potentially resulting in "Pure virtual method
-+		 * called" or some other crash.  To avoid this race condition, call
-+		 * this constructor with a non-null `gc` only from a thread that is in
-+		 * a request on `gc`.
-+		 */
- 		GCEdgeCallback(GC *gc = NULL);
- 		virtual ~GCEdgeCallback();
- 
-@@ -1446,6 +1468,24 @@ namespace MMgc
- 		void AddCallback(GCCallback *cb);
- 		void RemoveCallback(GCCallback *cb);
- 
-+		/**
-+		 * Points to the head of a linked list of edge callback objects.
-+		 *
-+		 * @access Requires((request && m_callbackListLock) || exclusiveGC)
-+		 *
-+		 * In an MMGC_THREADSAFE build, this linked list is protected by the
-+		 * request model.  A thread must only access the list (a) from
-+		 * application code that is within a request AND holds
-+		 * m_callbackListLock; or (b) from MMgc code in the
-+		 * m_exclusiveGCThread.
-+		 *
-+		 * This policy is different from the one that covers m_callbacks for
-+		 * two reasons.  First, m_callbacks can fire the precollect callback
-+		 * even if the calling thread is not in a request at all, so this
-+		 * policy would be insufficient for m_callbacks.  Second,
-+		 * m_edgeCallbacks fires very frequently during marking, so a
-+		 * lock-free policy is probably much faster.
-+		 */
- 		GCEdgeCallback *m_edgeCallbacks;
- 		void AddEdgeCallback(GCEdgeCallback *cb);
- 		void RemoveEdgeCallback(GCEdgeCallback *cb);
-@@ -1453,9 +1493,10 @@ namespace MMgc
- 		/**
- 		 * Notify GCEdgeCallbacks of an edge.
- 		 *
--		 * p is a "real pointer".  This method converts it to
--		 * a "user pointer" using GetUserPointer() before
--		 * calling callbacks.
-+		 * p is a "real pointer".  This method converts it to a "user pointer"
-+		 * using GetUserPointer() before calling callbacks.
-+		 *
-+		 * @access Requires(exclusiveGC)
- 		 */
- 		void FireFoundEdgeTo(const void *p);
- 
--- a/mmgc-threadsafe-gctests
+++ b/mmgc-threadsafe-gctests
@@ -1,66 +1,66 @@
 diff --git a/MMgc/GCTests.cpp b/MMgc/GCTests.cpp
 --- a/MMgc/GCTests.cpp
 +++ b/MMgc/GCTests.cpp
-@@ -55,6 +55,15 @@ namespace MMgc
+@@ -53,6 +53,15 @@ namespace MMgc
  {
  	GC *gc;
  
 +	void collect()
 +	{
 +#ifdef MMGC_THREADSAFE
 +		gc->CollectFromRequest();
 +#else
 +		gc->Collect();
 +#endif
 +	}
 +
- 	GCWeakRef* createWeakRef(int extra = 0)
+ 	GCWeakRef* createWeakRef(int extra=0)
  	{
  		// Bogusly use up some extra stack.
-@@ -65,11 +74,11 @@ namespace MMgc
+@@ -63,11 +72,11 @@ namespace MMgc
  		// pointer there causes the temporary to be marked, and not collected,
  		// which causes tests to fail with assertions.
  		///
 -		// The extra 32 bytes here causes the temporary to end up higher on
 +		// The extra 64 bytes here causes the temporary to end up higher on
  		// the stack (numerically lesser address, on Intel at least) where
  		// CleanStack will clobber it.
  		//
 -		char buf[32];
 +		char buf[64];
  		sprintf(buf, "%d", extra);  // don't optimize away buf
  
  		return (new (gc, extra) GCObject())->GetWeakRef();
-@@ -78,9 +87,9 @@ namespace MMgc
+@@ -76,9 +85,9 @@ namespace MMgc
  	void weakRefSweepSmall()
  	{
  		GCWeakRef *ref = createWeakRef();
 -		gc->Collect();
 +		collect();
  		gc->CleanStack(true);
 -		gc->Collect();
 +		collect();
  		(void)ref;
  		GCAssert(ref->get() == NULL);
  	}
-@@ -88,9 +97,9 @@ namespace MMgc
+@@ -86,9 +95,9 @@ namespace MMgc
  	void weakRefSweepLarge()
  	{
  		GCWeakRef *ref = createWeakRef(5000);
 -		gc->Collect();
 +		collect();
  		gc->CleanStack(true);
 -		gc->Collect();
 +		collect();
  		(void)ref;
  		GCAssert(ref->get() == NULL);
  	}
-@@ -166,11 +175,17 @@ namespace MMgc
+@@ -164,11 +173,17 @@ namespace MMgc
  	void RunGCTests(GC *g)
  	{
  		gc = g;
 +#ifdef MMGC_THREADSAFE
 +		g->OnEnterRequest();
 +#endif
  		weakRefSweepSmall();
  		weakRefSweepLarge();
--- a/series
+++ b/series
@@ -1,7 +1,5 @@
-tweak-esc-main.sh
-mmgc-threadsafe
-unmerged-edits-to-mmgc-threadsafe
 mmgc-threadsafe-gctests
 mmgc-maybegc
+tweak-esc-main.sh
 mmgc-graphviz
 mmgc-bit-checks
deleted file mode 100644
--- a/unmerged-edits-to-mmgc-threadsafe
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
---- a/MMgc/GC.cpp
-+++ b/MMgc/GC.cpp
-@@ -424,6 +424,8 @@ namespace MMgc
- 		GCAssert(callerHasActiveRequest == GCThread::GetCurrentThread()->IsInActiveRequest());
- #endif
- #else
-+		(void) callerHoldsLock;
-+		(void) callerHasActiveRequest;
- 		CheckThread();
- #endif
-