update patch series to apply on top of 919d02671bb8 (just line numbers)
authorjorendorff@mozilla.com
Thu, 20 Dec 2007 10:15:23 -0600
changeset 31 e76f410f999e
parent 25 bc21193f2b1c
child 32 5900e6424cbd
push id1
push userbsmedberg@mozilla.com
push dateMon, 21 Apr 2008 01:54:18 +0000
update patch series to apply on top of 919d02671bb8 (just line numbers)
mmgc-threadsafe
--- a/mmgc-threadsafe
+++ b/mmgc-threadsafe
@@ -871,28 +871,28 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
 -	class AvmCore;
 +       class AvmCore;
  }
  #endif
 -
  namespace MMgc
  {
  	/**
-@@ -198,7 +208,10 @@ namespace MMgc
+@@ -219,7 +229,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;
-@@ -223,16 +236,25 @@ namespace MMgc
+@@ -244,16 +257,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
@@ -912,42 +912,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
-@@ -244,6 +266,8 @@ namespace MMgc
+@@ -265,6 +287,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> &) {}
  
-@@ -251,11 +275,15 @@ namespace MMgc
+@@ -272,11 +296,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() {}
  
-@@ -271,6 +299,43 @@ namespace MMgc
+@@ -292,6 +320,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.
@@ -981,17 +981,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
-@@ -315,6 +380,17 @@ namespace MMgc
+@@ -336,6 +401,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
@@ -999,17 +999,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();
  
-@@ -512,12 +588,19 @@ namespace MMgc
+@@ -533,12 +609,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)
@@ -1019,17 +1019,17 @@ 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;
  
-@@ -533,8 +616,28 @@ namespace MMgc
+@@ -554,8 +637,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
@@ -1048,47 +1048,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;
-@@ -544,6 +647,14 @@ namespace MMgc
+@@ -565,6 +668,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
-@@ -551,7 +662,13 @@ namespace MMgc
+@@ -572,7 +683,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();
  
-@@ -576,15 +693,26 @@ namespace MMgc
+@@ -597,15 +714,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.
 +		 *
@@ -1106,57 +1106,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);
  
-@@ -592,11 +720,15 @@ namespace MMgc
+@@ -613,11 +741,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)
  		{
-@@ -610,6 +742,8 @@ namespace MMgc
+@@ -631,6 +763,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)
  		{
-@@ -716,9 +850,13 @@ namespace MMgc
+@@ -737,9 +871,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; }
-@@ -746,11 +884,19 @@ namespace MMgc
+@@ -767,11 +905,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
@@ -1168,17 +1168,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));
-@@ -762,13 +908,19 @@ namespace MMgc
+@@ -783,13 +929,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)
@@ -1192,43 +1192,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)
  		{
-@@ -776,9 +928,11 @@ namespace MMgc
+@@ -797,9 +949,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));
-@@ -802,8 +956,10 @@ namespace MMgc
+@@ -823,8 +977,10 @@ namespace MMgc
  
  	public:
  
 +		/** @access Requires(request || exclusiveGC) */
  		bool ContainsPointers(const void *item);
  
 +		/** @access Requires(request) */
  		void *FindBeginning(const void *gcItem)
  		{
  			GCAssert(gcItem != NULL);
-@@ -839,11 +995,23 @@ namespace MMgc
+@@ -860,11 +1016,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
@@ -1245,31 +1245,31 @@ 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();
-@@ -854,9 +1022,12 @@ namespace MMgc
+@@ -875,9 +1043,12 @@ namespace MMgc
  			return (double(GC::GetPerformanceCounter() - start) * 1000) / GC::GetPerformanceFrequency();
  		}
  
 +#ifndef MMGC_THREADSAFE
  		void DisableThreadCheck() { disableThreadCheck = true; }
 +#endif
  		
 -		uint64 t0;
 +		/** GC initialization time, in ticks.  Used for logging. */
 +		const uint64 t0;
  
  		// a tick is the unit of GetPerformanceCounter()
  		static uint64 ticksToMicros(uint64 ticks) 
-@@ -879,21 +1050,69 @@ namespace MMgc
+@@ -900,21 +1071,69 @@ namespace MMgc
  		}
  
  		// marking rate counter
 +		/**
 +		 * Total number of bytes of pointer-containing memory scanned by this
 +		 * GC.  Used to measure marking rate, which is
 +		 * <code>bytesMarked/ticksToMillis(markTicks)</code>.
 +		 *
@@ -1330,39 +1330,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
-@@ -905,7 +1124,10 @@ namespace MMgc
+@@ -926,7 +1145,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;
-@@ -922,7 +1144,10 @@ namespace MMgc
+@@ -943,7 +1165,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
-@@ -931,32 +1156,55 @@ namespace MMgc
+@@ -952,32 +1177,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;
@@ -1414,17 +1414,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];		
-@@ -968,14 +1216,44 @@ namespace MMgc
+@@ -989,14 +1237,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;
@@ -1459,17 +1459,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;
  
-@@ -987,7 +1265,20 @@ namespace MMgc
+@@ -1008,7 +1286,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.
 +		 *
@@ -1480,17 +1480,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);
-@@ -1007,12 +1298,37 @@ namespace MMgc
+@@ -1028,12 +1319,37 @@ namespace MMgc
  		GCLargeAlloc *largeAlloc;
  		GCHeap *heap;
  		
 +		/** @access Requires(m_lock) */
  		void* AllocBlockIncremental(int size, bool zero=true);
 +
 +		/** @access Requires(m_lock) */
  		void* AllocBlockNonIncremental(int size, bool zero=true);
@@ -1518,17 +1518,17 @@ diff --git a/MMgc/GC.h b/MMgc/GC.h
  
  #ifdef _DEBUG
  		public:
  #endif
 +		/** @access Requires(exclusiveGC) */
  		void ClearMarks();
  #ifdef _DEBUG
  		private:
-@@ -1022,59 +1338,127 @@ namespace MMgc
+@@ -1043,59 +1359,127 @@ namespace MMgc
  #ifdef _DEBUG
  		public:
  		// sometimes useful for mutator to call this
 +		/** @access Requires(exclusiveGC) */
  		void Trace(const void *stackStart=NULL, size_t stackSize=0);
  		private:
  #endif
  
@@ -1651,41 +1651,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);
-@@ -1082,9 +1466,10 @@ namespace MMgc
+@@ -1103,9 +1487,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);
  
-@@ -1107,7 +1492,9 @@ private:
+@@ -1128,7 +1513,9 @@ private:
  private:
  #endif
  
 +#ifndef MMGC_THREADSAFE
  		void CheckThread();
 +#endif
  
  		void PushWorkItem(GCStack<GCWorkItem> &stack, GCWorkItem item);
  
-@@ -1124,17 +1511,37 @@ private:
+@@ -1145,17 +1532,37 @@ private:
  		void CheckFreelists();
  
  		int m_gcLastStackTrace;
 +
 +		/**
 +		 * Used by FindUnmarkedPointers.
 +		 *
 +		 * @access Requires(exclusiveGC)
@@ -1717,17 +1717,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
-@@ -1155,7 +1562,187 @@ public:
+@@ -1176,7 +1583,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)
 +		 */