Refresh patches for incoming changes. Also, tweak for esc/build/main.sh to use the AVM environment variable if it's set.
authorjorendorff@mozilla.com
Thu, 06 Dec 2007 17:04:46 -0600
changeset 16 6d5128c90b51b2baf0e98b990801927febd3730c
parent 15 208dbe8b1541075ecdd53987d78ce4fa271669dd
child 17 5db526fd0a127b52b5a4023074d5f35d23a8a75e
push id1
push userbsmedberg@mozilla.com
push dateMon, 21 Apr 2008 01:54:18 +0000
Refresh patches for incoming changes. Also, tweak for esc/build/main.sh to use the AVM environment variable if it's set.
mmgc-threadsafe-take2
series
tweak-esc-main.sh
--- a/mmgc-threadsafe-take2
+++ b/mmgc-threadsafe-take2
@@ -130,17 +130,17 @@ diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
 +				GCRoot *stackRoot;
 +				void *stack;
 +				size_t stackSize;
 +
 +				// Call this macro here, not under "if
 +				// (callerHasActiveRequest)", because it introduces local
 +				// variables that must survive for the whole lifetime of
 +				// stackRoot.
-+				MMGC_GET_STACK_EXENTS(this, stack, stackSize);
++				MMGC_GET_STACK_EXTENTS(this, stack, stackSize);
 +
 +				// Before waiting, this thread must suspend any active
 +				// requests.  This avoids a deadlock where m_exclusiveGCThread
 +				// is waiting for m_requestCount to go to zero while we're
 +				// waiting for m_exclusiveGCThread to be done.
 +				//
 +				// When we do this, we root the calling thread's stack; this
 +				// way each collection scans the stack of every thread that is
@@ -850,28 +850,28 @@ diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
  		// invoke postsweep callback
 +		USING_CALLBACK_LIST(this);
  		GCCallback *cb = m_callbacks;
  		while(cb) {
  			cb->allocActivity(blocks);
 diff --git a/MMgc/GC.h b/MMgc/GC.h
 --- a/MMgc/GC.h
 +++ b/MMgc/GC.h
-@@ -195,7 +195,10 @@ namespace MMgc
+@@ -198,7 +198,10 @@ namespace MMgc
  	private:
  		FixedMalloc* fm;
  		GC * gc;
 +
 +		/** @access Requires(gc->m_rootListLock) */
  		GCRoot *next;
 +		/** @access Requires(gc->m_rootListLock) */
  		GCRoot *prev;
  		const void *object;
  		size_t size;
-@@ -220,16 +223,25 @@ namespace MMgc
+@@ -223,16 +226,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
@@ -891,42 +891,42 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		/**
 +		 * 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
-@@ -241,6 +253,8 @@ namespace MMgc
+@@ -244,6 +256,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> &) {}
  
-@@ -248,11 +262,15 @@ namespace MMgc
+@@ -251,11 +265,15 @@ namespace MMgc
  		 * This method is invoked after all marking and before any
  		 * sweeping, useful for bookkeeping based on whether things
  		 * got marked
 +		 *
 +		 * @access Requires(gc->exclusiveGC)
  		 */
  		virtual void presweep() {}
  
  		/**
  		 * This method is invoked after all sweeping
 +		 *
 +		 * @access Requires(gc->exclusiveGC)
  		 */
  		virtual void postsweep() {}
  
-@@ -268,6 +286,43 @@ namespace MMgc
+@@ -271,6 +289,43 @@ namespace MMgc
  		// called after a ZCT reap completes
  		virtual void postreap() {}
  #endif
 +
 +		/**
 +		 * This callback is the first thing a collecting thread does once it
 +		 * acquires exclusiveGC status.  When this is called, no other threads
 +		 * are running in requests and the calling thread holds gc->m_lock.
@@ -960,17 +960,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * See note at GCCallback::enterExclusiveGC().
 +		 *
 +		 * @access Requires(gc->exclusiveGC && gc->m_lock)
 +		 */
 +		virtual void leaveExclusiveGC() {}
  
  		/**
  		 * This method is called before an RC object is reaped
-@@ -312,6 +367,17 @@ namespace MMgc
+@@ -315,6 +370,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
@@ -978,17 +978,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * 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();
  
-@@ -509,12 +575,19 @@ namespace MMgc
+@@ -512,12 +578,19 @@ namespace MMgc
  		 * will cause a garbage collection.  This makes code run
  		 * abysmally slow, but can be useful for detecting mark
  		 * bugs.
 +		 *
 +		 * The GC reads this flag only when holding the GC lock.  It is best
 +		 * to set it as soon as the GC is created.
 +		 *
 +		 * @access Requires(m_lock)
@@ -998,19 +998,19 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
  		/**
  		 * nogc is a debugging flag.  When set, garbage collection
  		 * never happens.
 +		 *
 +		 * @access Requires(m_lock)
  		 */
  		bool nogc;
  
-@@ -535,8 +608,28 @@ namespace MMgc
- 		 */
- 		int ISD;
+@@ -533,8 +606,28 @@ namespace MMgc
+ 		bool validateDefRef;		
+ 		bool keepDRCHistory;
  
 +		/**
 +		 * Expand, don't collect, until we reach this threshold. Units are
 +		 * pages, not KB, just like GCHeap::GetTotalHeapSize().
 +		 *
 +		 * In an MMGC_THREADSAFE build, the GC reads this configuration value
 +		 * only when holding the GC lock.  Set it during
 +		 * initialization, before the GC is visible to multiple threads.
@@ -1027,47 +1027,47 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * stop-the-world collection.  Set it during initialization, before
 +		 * the GC is visible to multiple threads.
 +		 *
 +		 * @access Requires(exclusiveGC)
 +		 */
  		bool gcstats;
  
  		bool dontAddToZCTDuringCollection;
-@@ -546,6 +639,14 @@ namespace MMgc
+@@ -544,6 +637,14 @@ namespace MMgc
  		bool incrementalValidationPedantic;
  #endif
  
 +		/**
 +		 * Configuration flag enabling incremental collection.
 +		 *
 +		 * In an MMGC_THREADSAFE build, the GC reads this flag only when
 +		 * holding the GC lock.  Set it during initialization.
 +		 *
 +		 * @access Requires(m_lock)
 +		 */
  		bool incremental;
  
  		// -- Interface
-@@ -553,7 +654,13 @@ namespace MMgc
+@@ -551,7 +652,13 @@ namespace MMgc
  		virtual ~GC();
  		
  		/**
 -		 * Causes an immediate garbage collection
 +		 * Causes an immediate garbage collection.
 +		 *
 +		 * In an MMGC_THREADSAFE build, the caller must not be inside a
 +		 * request.  If the caller is inside a request, call
 +		 * CollectFromRequest() instead.
 +		 *
 +		 * @access Requires(!m_lock && !request)
  		 */
  		void Collect();
  
-@@ -578,15 +685,26 @@ namespace MMgc
+@@ -576,15 +683,26 @@ namespace MMgc
  
  		/**
  		 * Main interface for allocating memory.  Default flags is no
 -		 * finalization, contains pointers is set and zero is set
 +		 * finalization, contains pointers is set and zero is set.
 +		 *
 +		 * Do not call this from a finalizer.
 +		 *
@@ -1085,57 +1085,57 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
  		 * Calloc(num, sizeof(thing))
 +		 *
 +		 * Do not call this from a finalizer.
 +		 *
 +		 * @access Requires(request)
  		 */
  		void *Calloc(size_t num, size_t elsize, int flags=0, int skip=3);
  
-@@ -594,11 +712,15 @@ namespace MMgc
+@@ -592,11 +710,15 @@ namespace MMgc
  		 * One can free a GC allocated pointer, this will throw an assertion
  		 * if called during the Sweep phase (ie via a finalizer) it can only be
  		 * used outside the scope of a collection
 +		 *
 +		 * @access Requires(request)
  		 */
  		void Free(void *ptr);
  
  		/**
  		 * return the size of a piece of memory, may be bigger than what was asked for
 +		 *
 +		 * @access Requires(request || exclusiveGC)
  		 */
  		static size_t Size(const void *ptr)
  		{
-@@ -612,6 +734,8 @@ namespace MMgc
+@@ -610,6 +732,8 @@ namespace MMgc
  		/**
  		 * Tracers should employ GetMark and SetMark to
  		 * set the mark bits during the mark pass.
 +		 *
 +		 * @access Requires(request || exclusiveGC)
  		 */
  		static int GetMark(const void *item)
  		{
-@@ -718,9 +842,13 @@ namespace MMgc
+@@ -716,9 +840,13 @@ namespace MMgc
  		}
  
  		/**
 -		 * Used by sub-allocators to obtain memory
 +		 * Used by sub-allocators to obtain memory.
 +		 *
 +		 * @access Requires(m_lock)
  		 */
  		void* AllocBlock(int size, int pageType, bool zero=true);
 +
 +		/** @access Requires((request && m_lock) || exclusiveGC) */
  		void FreeBlock(void *ptr, uint32 size);
  
  		GCHeap *GetGCHeap() const { return heap; }
-@@ -748,11 +876,19 @@ namespace MMgc
+@@ -746,11 +874,19 @@ namespace MMgc
  		 */
  		bool IncrementalMarking() { return marking; }
  
 -		// a magical write barriers that finds the container's address and the GC, just
 -		// make sure address is a pointer to a GC page, only used by WB smart pointers
 +		/**
 +		 * A magical write barrier that finds the container's address and the
 +		 * GC, just make sure @a address is a pointer to a GC page. Only used
@@ -1147,17 +1147,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +
 +		/** @access Requires(request) */
  		static void WriteBarrierNoSub(const void *address, const void *value);
  
 +		/** @access Requires(request) */
  		void writeBarrier(const void *container, const void *address, const void *value)
  		{
  			GCAssert(IsPointerToGCPage(container));
-@@ -764,13 +900,19 @@ namespace MMgc
+@@ -762,13 +898,19 @@ namespace MMgc
  			WriteBarrierWrite(address, value);
  		}
  
 -		// optimized version with no RC checks or pointer masking
 +		/**
 +		 * optimized version with no RC checks or pointer masking
 +		 *
 +		 * @access Requires(request)
@@ -1171,43 +1171,43 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * Write barrier when the value could be a pointer with anything in the lower 3 bits
 +		 * FIXME: maybe assert that the lower 3 bits are either zero or a pointer type signature,
 +		 * this would require the application to tell us what bit patterns are pointers.
 +		 *
 +		 * @access Requires(request)
  		 */
  		__forceinline void WriteBarrierNoSubstitute(const void *container, const void *value)
  		{
-@@ -778,9 +920,11 @@ namespace MMgc
+@@ -776,9 +918,11 @@ namespace MMgc
  		}
  			
  		/**
 -		 AVM+ write barrier, valuePtr is known to be pointer and the caller
 -		does the write
 -		*/
 +		 * AVM+ write barrier, valuePtr is known to be pointer and the caller
 +		 * does the write.
 +		 *
 +		 * @access Requires(request)
 +		 */
  		__forceinline void WriteBarrierTrap(const void *container, const void *valuePtr)
  		{
  			GCAssert(IsPointerToGCPage(container));
-@@ -804,8 +948,10 @@ namespace MMgc
+@@ -802,8 +946,10 @@ namespace MMgc
  
  	public:
  
 +		/** @access Requires(request || exclusiveGC) */
  		bool ContainsPointers(const void *item);
  
 +		/** @access Requires(request) */
  		void *FindBeginning(const void *gcItem)
  		{
  			GCAssert(gcItem != NULL);
-@@ -841,11 +987,23 @@ namespace MMgc
+@@ -839,11 +985,23 @@ namespace MMgc
  		bool IsRCObject(const void *) { return false; }
  #endif
  
 -
 -		bool Collecting() const { return collecting; }
 -
 +		/**
 +		 * True during Sweep phase.  Application code can use this to
@@ -1224,17 +1224,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +
 +		/** @access Requires(request || exclusiveGC) */
  		bool IsGCMemory (const void *);
  
 +		/** @access Requires(request || exclusiveGC) */
  		bool IsQueued(const void *item);
  
  		static uint64 GetPerformanceCounter();
-@@ -856,30 +1014,81 @@ namespace MMgc
+@@ -854,30 +1012,81 @@ namespace MMgc
  			return (double(GC::GetPerformanceCounter() - start) * 1000) / GC::GetPerformanceFrequency();
  		}
  
 +#ifndef MMGC_THREADSAFE
  		void DisableThreadCheck() { disableThreadCheck = true; }
 -		
 -		uint64 t0;
 +#endif
@@ -1311,39 +1311,39 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * incremental mark.  This means the next mark will force the GC cycle
 +		 * through to completion.
 +		 *
 +		 * @access ReadWrite(request, exclusiveGC)
 +		 */
  		bool hitZeroObjects;
  
  		// called at some apropos moment from the mututor, ideally at a point
-@@ -891,7 +1100,10 @@ namespace MMgc
+@@ -889,7 +1098,10 @@ namespace MMgc
  
  		bool Destroying() { return destroying; }
  
 +		/** @access Requires(request) */
  		static GCWeakRef *GetWeakRef(const void *obj);
 +
 +		/** @access Requires((request && m_lock) || exclusiveGC) */
  		void ClearWeakRef(const void *obj);
  
  		uintptr	GetStackTop() const;		
-@@ -907,7 +1119,10 @@ namespace MMgc
+@@ -905,7 +1117,10 @@ namespace MMgc
  		// FIXME: only used for FixedAlloc, GCAlloc sized dynamically
  		const static int kPageUsableSpace = 3936;
  
 +		/** @access Requires(request && m_lock) */
  		uint32 *GetBits(int numBytes, int sizeClass);
 +
 +		/** @access Requires((request && m_lock) || exclusiveGC) */
  		void FreeBits(uint32 *bits, int sizeClass)
  		{
  #ifdef _DEBUG
-@@ -916,32 +1131,55 @@ namespace MMgc
+@@ -914,32 +1129,55 @@ namespace MMgc
  			*(uint32**)bits = m_bitsFreelists[sizeClass];
  			m_bitsFreelists[sizeClass] = bits;
  		}
 +
 +		/** @access Requires((request && m_lock) || exclusiveGC) */
  		uint32 *m_bitsFreelists[kNumSizeClasses];
 +		/** @access Requires((request && m_lock) || exclusiveGC) */
  		uint32 *m_bitsNext;
@@ -1395,17 +1395,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 -		
 +
 +		/** @access ReadWrite(request, exclusiveGC) */
  		uint64 lastMarkTicks;
 +		/** @access ReadWrite(request, exclusiveGC) */
  		uint64 lastSweepTicks;
  
  		const static int16 kSizeClasses[kNumSizeClasses];		
-@@ -953,14 +1191,44 @@ namespace MMgc
+@@ -951,14 +1189,44 @@ namespace MMgc
  		// 0 - not in use
  		// 1 - used by GCAlloc
  		// 3 - used by GCLargeAlloc
 +
 +		/** @access Requires(pageMapLock) */
  		uintptr memStart;
 +		/** @access Requires(pageMapLock) */
  		uintptr memEnd;
@@ -1440,17 +1440,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +			return GetPageMapValueAlreadyLocked(addr);
 +		}
 +
 +		/** @access Requires(pageMapLock) */
 +		inline int GetPageMapValueAlreadyLocked(uintptr addr) const
  		{
  			uintptr index = (addr-memStart) >> 12;
  
-@@ -972,7 +1240,20 @@ namespace MMgc
+@@ -970,7 +1238,20 @@ namespace MMgc
  			//return (pageMap[addr >> 2] & (3<<shiftAmount)) >> shiftAmount;
  			return (pageMap[index >> 2] >> shiftAmount) & 3;
  		}
 +
 +		/**
 +		 * Set the pageMap bits for the given address.  Those bits must be
 +		 * zero beforehand.
 +		 *
@@ -1461,17 +1461,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		/**
 +		 * Zero out the pageMap bits for the given address.
 +		 *
 +		 * @access Requires(pageMapLock)
 +		 */
  		void ClearPageMapValue(uintptr addr);
  
  		void MarkGCPages(void *item, uint32 numpages, int val);
-@@ -991,69 +1272,163 @@ namespace MMgc
+@@ -989,69 +1270,163 @@ namespace MMgc
  		GCAlloc *noPointersAllocs[kNumSizeClasses];
  		GCLargeAlloc *largeAlloc;
  		GCHeap *heap;
 -		
 +
 +		/** @access Requires(m_lock) */
  		void* AllocBlockIncremental(int size, bool zero=true);
 +
@@ -1633,41 +1633,41 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * 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);
-@@ -1061,9 +1436,10 @@ namespace MMgc
+@@ -1059,9 +1434,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);
  
-@@ -1086,7 +1462,9 @@ private:
+@@ -1084,7 +1460,9 @@ private:
  private:
  #endif
  
 +#ifndef MMGC_THREADSAFE
  		void CheckThread();
 +#endif
  
  		void PushWorkItem(GCStack<GCWorkItem> &stack, GCWorkItem item);
  
-@@ -1103,17 +1481,37 @@ private:
+@@ -1101,17 +1479,37 @@ private:
  		void CheckFreelists();
  
  		int m_gcLastStackTrace;
 +
 +		/**
 +		 * Used by FindUnmarkedPointers.
 +		 *
 +		 * @access Requires(exclusiveGC)
@@ -1699,17 +1699,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 +		 * Scan all GC memory (skipping roots). If a GC object is black make sure
 +		 * it has no pointers to white objects.
 +		 *
 +		 * @access Requires(exclusiveGC)
 +		 */
  		void FindMissingWriteBarriers();
  #ifdef WIN32
  		// store a handle to the thread that create the GC to ensure thread safety
-@@ -1134,7 +1532,187 @@ public:
+@@ -1132,7 +1530,187 @@ public:
  #ifdef _DEBUG
  		// Dump a list of objects that have pointers to the given location.
  		void WhosPointingAtMe(void* me, int recurseDepth=0, int currentDepth=0);
 +
 +		/**
 +		 * Used by WhosPointingAtMe.
 +		 * @access Requires(pageMapLock)
 +		 */
--- a/series
+++ b/series
@@ -1,4 +1,5 @@
+tweak-esc-main.sh
 configure-with-threadsafe-mmgc
 mmgc-threadsafe-take2
 mmgc-graphviz
 mmgc-bit-checks
new file mode 100644
--- /dev/null
+++ b/tweak-esc-main.sh
@@ -0,0 +1,7 @@
+diff --git a/esc/build/main.sh b/esc/build/main.sh
+--- a/esc/build/main.sh
++++ b/esc/build/main.sh
+@@ -1,1 +1,2 @@
+-/work/tamarin/bin/shell ../bin/debug.es.abc ../bin/ast.es.abc ../bin/ast-decode.es.abc ../bin/ast-encode.es.abc ../bin/util.es.abc ../bin/lex-char.es.abc ../bin/lex-token.es.abc ../bin/lex-scan.es.abc ../bin/parse.es.abc ../bin/util-tamarin.es.abc ../bin/bytes-tamarin.es.abc ../bin/util-tamarin.es.abc ../bin/asm.es.abc ../bin/abc.es.abc ../bin/emit.es.abc ../bin/cogen.es.abc ../bin/cogen-stmt.es.abc ../bin/cogen-expr.es.abc ../bin/main.es.abc -- $1
++AVM=${AVM:-/work/tamarin/bin/shell}
++$AVM ../bin/debug.es.abc ../bin/ast.es.abc ../bin/ast-decode.es.abc ../bin/ast-encode.es.abc ../bin/util.es.abc ../bin/lex-char.es.abc ../bin/lex-token.es.abc ../bin/lex-scan.es.abc ../bin/parse.es.abc ../bin/util-tamarin.es.abc ../bin/bytes-tamarin.es.abc ../bin/util-tamarin.es.abc ../bin/asm.es.abc ../bin/abc.es.abc ../bin/emit.es.abc ../bin/cogen.es.abc ../bin/cogen-stmt.es.abc ../bin/cogen-expr.es.abc ../bin/main.es.abc -- $1