mmgc-maybegc
author jorendorff@mozilla.com
Fri, 04 Jan 2008 16:11:56 -0600
changeset 32 5900e6424cbd989bcd7f8d3ff2c4bc2857f98ac1
parent 24 7b177201b469fd969817e2461a2cfe93cef9a883
permissions -rw-r--r--
Preliminarily split mmgc-threadsafe into two parts, mmgc-threadsafe-baseline containing only the changes that are in tamarin-central, and mmgc-threadsafe containing additional actionmonkey-specific stuff on top of that.

diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
--- a/MMgc/GC.cpp
+++ b/MMgc/GC.cpp
@@ -745,6 +745,42 @@ namespace MMgc
 		return item;
 	}
 
+	void GC::MaybeGC(bool callerHasActiveRequest)
+	{
+		if (greedy) {
+			CollectWithBookkeeping(false, callerHasActiveRequest);
+		} else if (marking) {
+			IncrementalMark();
+		} else {
+#ifdef MMGC_THREADSAFE
+			GCAutoLock _lock(m_lock);
+#endif
+
+			// Burst logic to prevent collections from happening back to back.
+			uint64 now = GetPerformanceCounter();
+			if (now - lastSweepTicks <= kMarkSweepBurstTicks)
+				return;
+
+			// Definitely start GC if the heap expanded due to FixedMalloc
+			// allocations.  The same heuristic applies to incremental and
+			// non-incremental.
+			bool force = (heapSizeAtLastAlloc > collectThreshold &&
+						  heapSizeAtLastAlloc < heap->GetTotalHeapSize());
+
+			if (incremental) {
+				if (force || (totalGCPages > collectThreshold &&
+							  allocsSinceCollect * kFreeSpaceDivisor >= totalGCPages)) {
+					StartIncrementalMark();
+				}
+			} else {
+				// Collect only if the heap is completely full (a conservative
+				// heuristic).
+				if (force || heap->GetFreeHeapSize() == 0)
+					CollectWithBookkeeping(true, callerHasActiveRequest);
+			}
+		}
+	}
+
 	void *GC::Calloc(size_t num, size_t elsize, int flags, int skip)
 	{
 		uint64 size = (uint64)num * (uint64)elsize;
diff --git a/MMgc/GC.h b/MMgc/GC.h
--- a/MMgc/GC.h
+++ b/MMgc/GC.h
@@ -673,6 +673,20 @@ namespace MMgc
 		void Collect();
 
 		/**
+		 * Perform some GC-related work if needed.  Call this during
+		 * application down time.
+		 *
+		 * In incremental mode, this may result in a call to
+		 * StartIncrementalMark() or IncrementalMark(), which may in turn push
+		 * the current GC cycle to completion.  In non-incremental mode, this
+		 * heuristically decides whether to do a full Collect().
+		 *
+		 * @param callerHasActiveRequest
+		 *     Must be true iff the calling thread is already in a request.
+		 */
+		void MaybeGC(bool callerHasActiveRequest=false);
+
+		/**
 		* flags to be passed as second argument to alloc
 		*/
 		enum AllocFlags