Backed out changesets ccdc3d4f4571, 4dcc91e771e3, 0ae14946314b, and 94d22ab0b17f (bug 937960) for Windows 7 debug xpcshell failures.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 19 Dec 2013 16:57:55 -0500
changeset 161288 e9bab00a241eaa8fdba8de3a310cb53c12f1fd5d
parent 161287 6296ca67d80b1357834ec2b0076efb8354267c2f
child 161289 3c174bf854cef3a62462ae3d76b64d57741868c0
push id37876
push userryanvm@gmail.com
push dateThu, 19 Dec 2013 21:57:53 +0000
treeherdermozilla-inbound@e9bab00a241e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs937960
milestone29.0a1
backs outccdc3d4f4571472ab95d65bd1f91c8b37bdad266
4dcc91e771e3dabdd7ff008251ce8de2f6f09c4a
0ae14946314ba1fd8c5cdde1fc0db1af285b744b
94d22ab0b17f1033726e7f7aee63c16de46dbb5e
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changesets ccdc3d4f4571, 4dcc91e771e3, 0ae14946314b, and 94d22ab0b17f (bug 937960) for Windows 7 debug xpcshell failures.
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
modules/libpref/src/init/all.js
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsCycleCollector.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -116,25 +116,16 @@ static PRLogModuleInfo* gJSDiagnostics;
 #define NS_INTERSLICE_GC_BUDGET     40 // ms
 
 // The amount of time we wait between a request to CC (after GC ran)
 // and doing the actual CC.
 #define NS_CC_DELAY                 6000 // ms
 
 #define NS_CC_SKIPPABLE_DELAY       400 // ms
 
-// Maximum amount of time that should elapse between incremental CC slices
-static const int64_t kICCIntersliceDelay = 32; // ms
-
-// Time budget for an incremental CC slice
-static const int64_t kICCSliceBudget = 10; // ms
-
-// Maximum total duration for an ICC
-static const uint32_t kMaxICCDuration = 2000; // ms
-
 // Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
 // objects in the purple buffer.
 #define NS_CC_FORCED                (2 * 60 * PR_USEC_PER_SEC) // 2 min
 #define NS_CC_FORCED_PURPLE_LIMIT   10
 
 // Don't allow an incremental GC to lock out the CC for too long.
 #define NS_MAX_CC_LOCKEDOUT_TIME    (15 * PR_USEC_PER_SEC) // 15 seconds
 
@@ -148,17 +139,16 @@ static const uint32_t kMaxICCDuration = 
 
 #define NS_MAJOR_FORGET_SKIPPABLE_CALLS 2
 
 // if you add statics here, add them to the list in StartupJSEnvironment
 
 static nsITimer *sGCTimer;
 static nsITimer *sShrinkGCBuffersTimer;
 static nsITimer *sCCTimer;
-static nsITimer *sICCTimer;
 static nsITimer *sFullGCTimer;
 static nsITimer *sInterSliceGCTimer;
 
 static PRTime sLastCCEndTime;
 
 static bool sCCLockedOut;
 static PRTime sCCLockedOutTime;
 
@@ -185,17 +175,16 @@ static uint32_t sMaxForgetSkippableTime 
 static uint32_t sTotalForgetSkippableTime = 0;
 static uint32_t sRemovedPurples = 0;
 static uint32_t sForgetSkippableBeforeCC = 0;
 static uint32_t sPreviousSuspectedCount = 0;
 static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
 static bool sNeedsFullCC = false;
 static bool sNeedsGCAfterCC = false;
 static nsJSContext *sContextList = nullptr;
-static bool sIncrementalCC = false;
 
 static nsScriptNameSpaceManager *gNameSpaceManager;
 
 static nsIJSRuntimeService *sRuntimeService;
 
 static const char kJSRuntimeServiceContractID[] =
   "@mozilla.org/js/xpc/RuntimeService;1";
 
@@ -228,17 +217,16 @@ GetCollectionTimeDelta()
 }
 
 static void
 KillTimers()
 {
   nsJSContext::KillGCTimer();
   nsJSContext::KillShrinkGCBuffersTimer();
   nsJSContext::KillCCTimer();
-  nsJSContext::KillICCTimer();
   nsJSContext::KillFullGCTimer();
   nsJSContext::KillInterSliceGCTimer();
 }
 
 class nsJSEnvironmentObserver MOZ_FINAL : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -2020,32 +2008,16 @@ struct CycleCollectorStats
   uint32_t mMaxSkippableDuration;
 
   // True if we were locked out by the GC in any slice of the current CC.
   bool mAnyLockedOut;
 };
 
 CycleCollectorStats gCCStats;
 
-static int64_t
-ICCSliceTime()
-{
-  // If CC is not incremental, use an unlimited budget.
-  if (!sIncrementalCC) {
-    return -1;
-  }
-
-  // If an ICC is in progress and is taking too long, finish it off.
-  if (gCCStats.mBeginTime != 0 &&
-      TimeBetween(gCCStats.mBeginTime, PR_Now()) >= kMaxICCDuration) {
-    return -1;
-  }
-
-  return kICCSliceBudget;
-}
 
 static void
 PrepareForCycleCollection(int32_t aExtraForgetSkippableCalls = 0)
 {
   gCCStats.mBeginSliceTime = PR_Now();
 
   // Before we begin the cycle collection, make sure there is no active GC.
   PRTime endGCTime;
@@ -2093,88 +2065,45 @@ nsJSContext::CycleCollectNow(nsICycleCol
 
   PROFILER_LABEL("CC", "CycleCollectNow");
   PrepareForCycleCollection(aExtraForgetSkippableCalls);
   nsCycleCollector_collect(aListener);
 }
 
 //static
 void
-nsJSContext::ScheduledCycleCollectNow(int64_t aSliceTime)
+nsJSContext::ScheduledCycleCollectNow()
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
   PROFILER_LABEL("CC", "ScheduledCycleCollectNow");
-
-  // Ideally, the slice time would be decreased by the amount of
-  // time spent on PrepareForCycleCollection().
   PrepareForCycleCollection();
-  nsCycleCollector_scheduledCollect(aSliceTime);
-}
-
-static void
-ICCTimerFired(nsITimer* aTimer, void* aClosure)
-{
-  if (sDidShutdown) {
-    return;
-  }
-
-  // Ignore ICC timer fires during IGC. Running ICC during an IGC will cause us
-  // to synchronously finish the GC, which is bad.
-
-  if (sCCLockedOut) {
-    PRTime now = PR_Now();
-    if (sCCLockedOutTime == 0) {
-      sCCLockedOutTime = now;
-      return;
-    }
-    if (now - sCCLockedOutTime < NS_MAX_CC_LOCKEDOUT_TIME) {
-      return;
-    }
-  }
-
-  nsJSContext::ScheduledCycleCollectNow(ICCSliceTime());
+  nsCycleCollector_scheduledCollect();
 }
 
 //static
 void
 nsJSContext::BeginCycleCollectionCallback()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   gCCStats.mBeginTime = gCCStats.mBeginSliceTime ? gCCStats.mBeginSliceTime : PR_Now();
   gCCStats.mSuspected = nsCycleCollector_suspectedCount();
 
   KillCCTimer();
-
-  MOZ_ASSERT(!sICCTimer, "Tried to create a new ICC timer when one already existed.");
-
-  if (!sIncrementalCC) {
-    return;
-  }
-
-  CallCreateInstance("@mozilla.org/timer;1", &sICCTimer);
-  if (sICCTimer) {
-    sICCTimer->InitWithFuncCallback(ICCTimerFired,
-                                    nullptr,
-                                    kICCIntersliceDelay,
-                                    nsITimer::TYPE_REPEATING_SLACK);
-  }
 }
 
 //static
 void
 nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsJSContext::KillICCTimer();
-
   sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed;
 
   // If we collected a substantial amount of cycles, poke the GC since more objects
   // might be unreachable now.
   if (sCCollectedWaitingForGC > 250 ||
       sLikelyShortLivingObjectsNeedingGC > 2500 ||
       sNeedsGCAfterCC) {
     PokeGC(JS::gcreason::CC_WAITING);
@@ -2332,37 +2261,26 @@ static bool
 ShouldTriggerCC(uint32_t aSuspected)
 {
   return sNeedsFullCC ||
          aSuspected > NS_CC_PURPLE_LIMIT ||
          (aSuspected > NS_CC_FORCED_PURPLE_LIMIT &&
           sLastCCEndTime + NS_CC_FORCED < PR_Now());
 }
 
-static uint32_t
-TimeToNextCC()
-{
-  if (sIncrementalCC) {
-    return NS_CC_DELAY - kMaxICCDuration;
-  }
-  return NS_CC_DELAY;
-}
-
-static_assert(NS_CC_DELAY > kMaxICCDuration, "ICC shouldn't reduce CC delay to 0");
-
 static void
 CCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   if (sDidShutdown) {
     return;
   }
 
   static uint32_t ccDelay = NS_CC_DELAY;
   if (sCCLockedOut) {
-    ccDelay = TimeToNextCC() / 3;
+    ccDelay = NS_CC_DELAY / 3;
 
     PRTime now = PR_Now();
     if (sCCLockedOutTime == 0) {
       // Reset sCCTimerFireCount so that we run forgetSkippable
       // often enough before CC. Because of reduced ccDelay
       // forgetSkippable will be called just a few times.
       // NS_MAX_CC_LOCKEDOUT_TIME limit guarantees that we end up calling
       // forgetSkippable and CycleCollectNow eventually.
@@ -2374,41 +2292,41 @@ CCTimerFired(nsITimer *aTimer, void *aCl
       return;
     }
   }
 
   ++sCCTimerFireCount;
 
   // During early timer fires, we only run forgetSkippable. During the first
   // late timer fire, we decide if we are going to have a second and final
-  // late timer fire, where we may begin to run the CC.
-  uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
+  // late timer fire, where we may run the CC.
+  const uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
   bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires;
   uint32_t suspected = nsCycleCollector_suspectedCount();
   if (isLateTimerFire && ShouldTriggerCC(suspected)) {
     if (sCCTimerFireCount == numEarlyTimerFires + 1) {
       FireForgetSkippable(suspected, true);
       if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
         // Our efforts to avoid a CC have failed, so we return to let the
         // timer fire once more to trigger a CC.
         return;
       }
     } else {
       // We are in the final timer fire and still meet the conditions for
       // triggering a CC. Let CycleCollectNow finish the current IGC, if any,
       // because that will allow us to include the GC time in the CC pause.
-      nsJSContext::ScheduledCycleCollectNow(ICCSliceTime());
+      nsJSContext::ScheduledCycleCollectNow();
     }
   } else if ((sPreviousSuspectedCount + 100) <= suspected) {
       // Only do a forget skippable if there are more than a few new objects.
       FireForgetSkippable(suspected, false);
   }
 
   if (isLateTimerFire) {
-    ccDelay = TimeToNextCC();
+    ccDelay = NS_CC_DELAY;
 
     // We have either just run the CC or decided we don't want to run the CC
     // next time, so kill the timer.
     sPreviousSuspectedCount = 0;
     nsJSContext::KillCCTimer();
   }
 }
 
@@ -2502,17 +2420,17 @@ nsJSContext::PokeShrinkGCBuffers()
                                               NS_SHRINK_GC_BUFFERS_DELAY,
                                               nsITimer::TYPE_ONE_SHOT);
 }
 
 // static
 void
 nsJSContext::MaybePokeCC()
 {
-  if (sCCTimer || sICCTimer || sShuttingDown || !sHasRunGC) {
+  if (sCCTimer || sShuttingDown || !sHasRunGC) {
     return;
   }
 
   if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
     sCCTimerFireCount = 0;
     CallCreateInstance("@mozilla.org/timer;1", &sCCTimer);
     if (!sCCTimer) {
       return;
@@ -2574,29 +2492,16 @@ nsJSContext::KillCCTimer()
 
   if (sCCTimer) {
     sCCTimer->Cancel();
 
     NS_RELEASE(sCCTimer);
   }
 }
 
-//static
-void
-nsJSContext::KillICCTimer()
-{
-  sCCLockedOutTime = 0;
-
-  if (sICCTimer) {
-    sICCTimer->Cancel();
-
-    NS_RELEASE(sICCTimer);
-  }
-}
-
 void
 nsJSContext::GC(JS::gcreason::Reason aReason)
 {
   PokeGC(aReason);
 }
 
 class NotifyGCEndRunnable : public nsRunnable
 {
@@ -2748,17 +2653,17 @@ nsJSContext::LikelyShortLivingObjectCrea
 {
   ++sLikelyShortLivingObjectsNeedingGC;
 }
 
 void
 mozilla::dom::StartupJSEnvironment()
 {
   // initialize all our statics, so that we can restart XPCOM
-  sGCTimer = sFullGCTimer = sCCTimer = sICCTimer = nullptr;
+  sGCTimer = sFullGCTimer = sCCTimer = nullptr;
   sCCLockedOut = false;
   sCCLockedOutTime = 0;
   sLastCCEndTime = 0;
   sHasRunGC = false;
   sPendingLoadCount = 0;
   sLoadingInProgress = false;
   sCCollectedWaitingForGC = 0;
   sLikelyShortLivingObjectsNeedingGC = 0;
@@ -2844,23 +2749,16 @@ SetMemoryGCDynamicHeapGrowthPrefChangedC
 
 static void
 SetMemoryGCDynamicMarkSlicePrefChangedCallback(const char* aPrefName, void* aClosure)
 {
   bool pref = Preferences::GetBool(aPrefName);
   JS_SetGCParameter(sRuntime, JSGC_DYNAMIC_MARK_SLICE, pref);
 }
 
-static void
-SetIncrementalCCPrefChangedCallback(const char* aPrefName, void* aClosure)
-{
-  bool pref = Preferences::GetBool(aPrefName);
-  sIncrementalCC = pref;
-}
-
 JSObject*
 NS_DOMReadStructuredClone(JSContext* cx,
                           JSStructuredCloneReader* reader,
                           uint32_t tag,
                           uint32_t data,
                           void* closure)
 {
   if (tag == SCTAG_DOM_IMAGEDATA) {
@@ -3057,19 +2955,16 @@ nsJSContext::EnsureStatics()
   Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
                                        "javascript.options.mem.gc_allocation_threshold_mb",
                                        (void *)JSGC_ALLOCATION_THRESHOLD);
 
   Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
                                        "javascript.options.mem.gc_decommit_threshold_mb",
                                        (void *)JSGC_DECOMMIT_THRESHOLD);
 
-  Preferences::RegisterCallbackAndCall(SetIncrementalCCPrefChangedCallback,
-                                       "dom.cycle_collector.incremental");
-
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (!obs) {
     MOZ_CRASH();
   }
 
   Preferences::AddBoolVarCache(&sGCOnMemoryPressure,
                                "javascript.options.gc_on_memory_pressure",
                                true);
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -96,39 +96,32 @@ public:
   void EnsureStatics();
 
   static void GarbageCollectNow(JS::gcreason::Reason reason,
                                 IsIncremental aIncremental = NonIncrementalGC,
                                 IsCompartment aCompartment = NonCompartmentGC,
                                 IsShrinking aShrinking = NonShrinkingGC,
                                 int64_t aSliceMillis = 0);
   static void ShrinkGCBuffersNow();
-
   // If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
   // called even if the previous collection was GC.
   static void CycleCollectNow(nsICycleCollectorListener *aListener = nullptr,
                               int32_t aExtraForgetSkippableCalls = 0);
-
-  // If aSliceTime is negative, the CC will run to completion.  If aSliceTime
-  // is 0, only a minimum quantum of work will be done.  Otherwise, aSliceTime
-  // will be used as the time budget for the slice, in ms.
-  static void ScheduledCycleCollectNow(int64_t aSliceTime);
-
+  static void ScheduledCycleCollectNow();
   static void BeginCycleCollectionCallback();
   static void EndCycleCollectionCallback(mozilla::CycleCollectorResults &aResults);
 
   static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
   static void KillGCTimer();
 
   static void PokeShrinkGCBuffers();
   static void KillShrinkGCBuffersTimer();
 
   static void MaybePokeCC();
   static void KillCCTimer();
-  static void KillICCTimer();
   static void KillFullGCTimer();
   static void KillInterSliceGCTimer();
 
   // Calling LikelyShortLivingObjectCreated() makes a GC more likely.
   static void LikelyShortLivingObjectCreated();
 
   virtual void GC(JS::gcreason::Reason aReason) MOZ_OVERRIDE;
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -708,18 +708,16 @@ pref("dom.forms.number", true);
 pref("dom.forms.color", true);
 
 // Enables system messages and activities
 pref("dom.sysmsg.enabled", false);
 
 // Enable pre-installed applications.
 pref("dom.webapps.useCurrentProfile", false);
 
-pref("dom.cycle_collector.incremental", false);
-
 // Parsing perf prefs. For now just mimic what the old code did.
 #ifndef XP_WIN
 pref("content.sink.pending_event_mode", 0);
 #endif
 
 // Disable popups from plugins by default
 //   0 = openAllowed
 //   1 = openControlled
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -3051,18 +3051,17 @@ nsCycleCollector::Collect(ccType aCCType
 
     return collectedAny;
 }
 
 // Any JS objects we have in the graph could die when we GC, but we
 // don't want to abandon the current CC, because the graph contains
 // information about purple roots. So we synchronously finish off
 // the current CC.
-void
-nsCycleCollector::PrepareForGarbageCollection()
+void nsCycleCollector::PrepareForGarbageCollection()
 {
     if (mIncrementalPhase == IdlePhase) {
         MOZ_ASSERT(mGraph.IsEmpty(), "Non-empty graph when idle");
         MOZ_ASSERT(!mBuilder, "Non-null builder when idle");
         return;
     }
 
     SliceBudget unlimitedBudget;
@@ -3547,32 +3546,27 @@ nsCycleCollector_collect(nsICycleCollect
     MOZ_ASSERT(data->mCollector);
 
     PROFILER_LABEL("CC", "nsCycleCollector_collect");
     SliceBudget unlimitedBudget;
     data->mCollector->Collect(ManualCC, unlimitedBudget, aManualListener);
 }
 
 void
-nsCycleCollector_scheduledCollect(int64_t aSliceTime)
+nsCycleCollector_scheduledCollect()
 {
     CollectorData *data = sCollectorData.get();
 
     // We should have started the cycle collector by now.
     MOZ_ASSERT(data);
     MOZ_ASSERT(data->mCollector);
 
     PROFILER_LABEL("CC", "nsCycleCollector_scheduledCollect");
-    SliceBudget budget;
-    if (aSliceTime > 0) {
-        budget = SliceBudget::TimeBudget(aSliceTime);
-    } else if (aSliceTime == 0) {
-        budget = SliceBudget::WorkBudget(1);
-    }
-    data->mCollector->Collect(ScheduledCC, budget, nullptr);
+    SliceBudget unlimitedBudget;
+    data->mCollector->Collect(ScheduledCC, unlimitedBudget, nullptr);
 }
 
 void
 nsCycleCollector_prepareForGarbageCollection()
 {
     CollectorData *data = sCollectorData.get();
 
     MOZ_ASSERT(data);
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -36,21 +36,17 @@ void nsCycleCollector_forgetSkippable(bo
                                       bool aAsyncSnowWhiteFreeing = false);
 
 void nsCycleCollector_prepareForGarbageCollection();
 
 void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false);
 bool nsCycleCollector_doDeferredDeletion();
 
 void nsCycleCollector_collect(nsICycleCollectorListener *aManualListener);
-
-// If aSliceTime is negative, the CC will run to completion.  If aSliceTime
-// is 0, only a minimum quantum of work will be done.  Otherwise, aSliceTime
-// will be used as the time budget for the slice, in ms.
-void nsCycleCollector_scheduledCollect(int64_t aSliceTime);
+void nsCycleCollector_scheduledCollect();
 
 uint32_t nsCycleCollector_suspectedCount();
 void nsCycleCollector_shutdown();
 
 // Helpers for interacting with JS
 void nsCycleCollector_registerJSRuntime(mozilla::CycleCollectedJSRuntime *aRt);
 void nsCycleCollector_forgetJSRuntime();