Backout 4ededc9b11f (bug 897433) for intermittent dromeao crashes
authorWes Kocher <wkocher@mozilla.com>
Wed, 24 Jul 2013 19:45:31 -0700
changeset 152170 a4c1961bf723dc7285f57f2cccbdf8144de187ab
parent 152169 0a8a8ee6daab2096898ccc6e79cfcd7eae31507f
child 152191 c6b9530205a447ebb4fda360c0eb932a42a596a5
child 152231 6cdf4912cf15fa524366d7e128ab8eaf0dd6b204
child 152247 bc2a7cfd52089d1d4009b5e892a54529cb60b927
child 170165 fda9274e0c30bb4e704e1058e301a57c6c483f33
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs897433
milestone25.0a1
first release with
nightly linux32
a4c1961bf723 / 25.0a1 / 20130724222711 / files
nightly linux64
a4c1961bf723 / 25.0a1 / 20130724222711 / files
nightly mac
a4c1961bf723 / 25.0a1 / 20130724222711 / files
nightly win32
a4c1961bf723 / 25.0a1 / 20130724222711 / files
nightly win64
a4c1961bf723 / 25.0a1 / 20130724222711 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 4ededc9b11f (bug 897433) for intermittent dromeao crashes
dom/base/nsJSEnvironment.cpp
toolkit/components/telemetry/Histograms.json
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsCycleCollector.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -130,18 +130,16 @@ static PRLogModuleInfo* gJSDiagnostics;
 // Trigger a CC if the purple buffer exceeds this size when we check it.
 #define NS_CC_PURPLE_LIMIT          200
 
 #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
 
 // Large value used to specify that a script should run essentially forever
 #define NS_UNLIMITED_SCRIPT_RUNTIME (0x40000000LL << 32)
 
-#define NS_MAJOR_FORGET_SKIPPABLE_CALLS 2
-
 // if you add statics here, add them to the list in nsJSRuntime::Startup
 
 static nsITimer *sGCTimer;
 static nsITimer *sShrinkGCBuffersTimer;
 static nsITimer *sCCTimer;
 static nsITimer *sFullGCTimer;
 static nsITimer *sInterSliceGCTimer;
 
@@ -2499,19 +2497,17 @@ FinishAnyIncrementalGC()
   }
 }
 
 static void
 FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless)
 {
   PRTime startTime = PR_Now();
   FinishAnyIncrementalGC();
-  bool earlyForgetSkippable =
-    sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS;
-  nsCycleCollector_forgetSkippable(aRemoveChildless, earlyForgetSkippable);
+  nsCycleCollector_forgetSkippable(aRemoveChildless);
   sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
   ++sCleanupsSinceLastGC;
   PRTime delta = PR_Now() - startTime;
   if (sMinForgetSkippableTime > delta) {
     sMinForgetSkippableTime = delta;
   }
   if (sMaxForgetSkippableTime < delta) {
     sMaxForgetSkippableTime = delta;
@@ -2551,19 +2547,18 @@ nsJSContext::CycleCollectNow(nsICycleCol
 
   KillCCTimer();
 
   uint32_t suspected = nsCycleCollector_suspectedCount();
   bool ranSyncForgetSkippable = false;
 
   // Run forgetSkippable synchronously to reduce the size of the CC graph. This
   // is particularly useful if we recently finished a GC.
-  if (sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS &&
-      aExtraForgetSkippableCalls >= 0) {
-    while (sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS) {
+  if (sCleanupsSinceLastGC < 2 && aExtraForgetSkippableCalls >= 0) {
+    while (sCleanupsSinceLastGC < 2) {
       FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
       ranSyncForgetSkippable = true;
     }
   }
 
   for (int32_t i = 0; i < aExtraForgetSkippableCalls; ++i) {
     FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
     ranSyncForgetSkippable = true;
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -81,22 +81,16 @@
     "high": "10000",
     "n_buckets": 50,
     "description": "Time spent on one ContentUnbinder (ms)"
   },
   "CYCLE_COLLECTOR_OOM": {
     "kind": "flag",
     "description": "Set if the cycle collector ran out of memory at some point"
   },
-  "CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING": {
-    "kind": "exponential",
-    "high": "10000",
-    "n_buckets": 50,
-    "description": "Time spent on one asynchronous SnowWhite freeing (ms)"
-  },
   "FORGET_SKIPPABLE_MAX": {
     "kind": "exponential",
     "high": "10000",
     "n_buckets": 50,
     "description": "Max time spent on one forget skippable (ms)"
   },
   "GC_REASON_2": {
     "kind": "enumerated",
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -770,25 +770,24 @@ public:
     void UnmarkRemainingPurple(Block *b)
     {
         UnmarkRemainingPurpleVisitor visitor;
         b->VisitEntries(*this, visitor);
     }
 
     void SelectPointers(GCGraphBuilder &builder);
 
-    // RemoveSkippable removes entries from the purple buffer synchronously
-    // (1) if aAsyncSnowWhiteFreeing is false and nsPurpleBufferEntry::mRefCnt is 0 or
-    // (2) if the object's nsXPCOMCycleCollectionParticipant::CanSkip() returns true or
-    // (3) if nsPurpleBufferEntry::mRefCnt->IsPurple() is false.
-    // (4) If removeChildlessNodes is true, then any nodes in the purple buffer
-    //     that will have no children in the cycle collector graph will also be
-    //     removed. CanSkip() may be run on these children.
+    // RemoveSkippable removes entries from the purple buffer if
+    // nsPurpleBufferEntry::mRefCnt is 0 or if the object's
+    // nsXPCOMCycleCollectionParticipant::CanSkip() returns true or
+    // if nsPurpleBufferEntry::mRefCnt->IsPurple() is false.
+    // If removeChildlessNodes is true, then any nodes in the purple buffer
+    // that will have no children in the cycle collector graph will also be
+    // removed. CanSkip() may be run on these children.
     void RemoveSkippable(bool removeChildlessNodes,
-                         bool aAsyncSnowWhiteFreeing,
                          CC_ForgetSkippableCallback aCb);
 
     nsPurpleBufferEntry* NewEntry()
     {
         if (!mFreeList) {
             Block *b = new Block;
             StartBlock(b);
 
@@ -1033,17 +1032,17 @@ public:
         mForgetSkippableCB = aForgetSkippableCB;
     }
 
     void SelectPurple(GCGraphBuilder &builder);
     void MarkRoots(GCGraphBuilder &builder);
     void ScanRoots();
     void ScanWeakMaps();
 
-    void ForgetSkippable(bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing);
+    void ForgetSkippable(bool removeChildlessNodes);
 
     // returns whether anything was collected
     bool CollectWhite(nsICycleCollectorListener *aListener);
 
     nsCycleCollector(CCThreadingModel aModel);
     ~nsCycleCollector();
 
     nsresult Init();
@@ -2205,22 +2204,19 @@ public:
 private:
     FallibleTArray<SnowWhiteObject> mObjects;
 };
 
 class RemoveSkippableVisitor : public SnowWhiteKiller
 {
 public:
     RemoveSkippableVisitor(uint32_t aMaxCount, bool aRemoveChildlessNodes,
-                           bool aAsyncSnowWhiteFreeing,
                            CC_ForgetSkippableCallback aCb)
-        : SnowWhiteKiller(aAsyncSnowWhiteFreeing ? 0 : aMaxCount),
+        : SnowWhiteKiller(aMaxCount),
           mRemoveChildlessNodes(aRemoveChildlessNodes),
-          mAsyncSnowWhiteFreeing(aAsyncSnowWhiteFreeing),
-          mDispatchedDeferredDeletion(false),
           mCallback(aCb)
     {}
 
     ~RemoveSkippableVisitor()
     {
         // Note, we must call the callback before SnowWhiteKiller calls
         // DeleteCycleCollectable!
         if (mCallback) {
@@ -2228,65 +2224,53 @@ public:
         }
     }
 
     void
     Visit(nsPurpleBuffer &aBuffer, nsPurpleBufferEntry *aEntry)
     {
         MOZ_ASSERT(aEntry->mObject, "null mObject in purple buffer");
         if (!aEntry->mRefCnt->get()) {
-            if (!mAsyncSnowWhiteFreeing) {
-                SnowWhiteKiller::Visit(aBuffer, aEntry);
-            } else if (!mDispatchedDeferredDeletion) {
-                mDispatchedDeferredDeletion = true;
-                nsCycleCollector_dispatchDeferredDeletion();
-            }
+            SnowWhiteKiller::Visit(aBuffer, aEntry);
             return;
         }
         void *o = aEntry->mObject;
         nsCycleCollectionParticipant *cp = aEntry->mParticipant;
         CanonicalizeParticipant(&o, &cp);
         if (aEntry->mRefCnt->IsPurple() && !cp->CanSkip(o, false) &&
             (!mRemoveChildlessNodes || MayHaveChild(o, cp))) {
             return;
         }
         aBuffer.Remove(aEntry);
     }
 
 private:
     bool mRemoveChildlessNodes;
-    bool mAsyncSnowWhiteFreeing;
-    bool mDispatchedDeferredDeletion;
     CC_ForgetSkippableCallback mCallback;
 };
 
 void
-nsPurpleBuffer::RemoveSkippable(bool aRemoveChildlessNodes,
-                                bool aAsyncSnowWhiteFreeing,
+nsPurpleBuffer::RemoveSkippable(bool removeChildlessNodes,
                                 CC_ForgetSkippableCallback aCb)
 {
-    RemoveSkippableVisitor visitor(Count(), aRemoveChildlessNodes,
-                                   aAsyncSnowWhiteFreeing, aCb);
+    RemoveSkippableVisitor visitor(Count(), removeChildlessNodes, aCb);
     VisitEntries(visitor);
     // If we're about to delete some objects when visitor goes out of scope,
     // try to delete some more soon.
     if (visitor.HasSnowWhiteObjects()) {
         nsCycleCollector_dispatchDeferredDeletion();
     }
 }
 
 class AsyncFreeSnowWhite : public nsRunnable
 {
 public:
   NS_IMETHOD Run()
   {
-      PRTime start = PR_Now();
       nsCycleCollector::TryToFreeSnowWhite();
-      Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING,
-                            uint32_t(PR_Now() - start) / PR_USEC_PER_MSEC);
       return NS_OK;
   }
 
   static void Dispatch()
   {
       nsRefPtr<AsyncFreeSnowWhite> ev = new AsyncFreeSnowWhite();
       NS_DispatchToCurrentThread(ev);
   }
@@ -2315,24 +2299,22 @@ nsCycleCollector::TryToFreeSnowWhite()
 
 void
 nsCycleCollector::SelectPurple(GCGraphBuilder &builder)
 {
     mPurpleBuf.SelectPointers(builder);
 }
 
 void
-nsCycleCollector::ForgetSkippable(bool aRemoveChildlessNodes,
-                                  bool aAsyncSnowWhiteFreeing)
+nsCycleCollector::ForgetSkippable(bool removeChildlessNodes)
 {
     if (mJSRuntime) {
         mJSRuntime->PrepareForForgetSkippable();
     }
-    mPurpleBuf.RemoveSkippable(aRemoveChildlessNodes, aAsyncSnowWhiteFreeing,
-                               mForgetSkippableCB);
+    mPurpleBuf.RemoveSkippable(removeChildlessNodes, mForgetSkippableCB);
 }
 
 MOZ_NEVER_INLINE void
 nsCycleCollector::MarkRoots(GCGraphBuilder &builder)
 {
     mGraph.mRootCount = builder.Count();
 
     // read the PtrInfo out of the graph that we are building
@@ -3270,29 +3252,27 @@ nsCycleCollector_setForgetSkippableCallb
     // We should have started the cycle collector by now.
     MOZ_ASSERT(data);
     MOZ_ASSERT(data->mCollector);
 
     data->mCollector->SetForgetSkippableCallback(aCB);
 }
 
 void
-nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes,
-                                 bool aAsyncSnowWhiteFreeing)
+nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes)
 {
     CollectorData *data = sCollectorData.get();
 
     // We should have started the cycle collector by now.
     MOZ_ASSERT(data);
     MOZ_ASSERT(data->mCollector);
 
     PROFILER_LABEL("CC", "nsCycleCollector_forgetSkippable");
     TimeLog timeLog;
-    data->mCollector->ForgetSkippable(aRemoveChildlessNodes,
-                                      aAsyncSnowWhiteFreeing);
+    data->mCollector->ForgetSkippable(aRemoveChildlessNodes);
     timeLog.Checkpoint("ForgetSkippable()");
 }
 
 void
 nsCycleCollector_dispatchDeferredDeletion()
 {
     AsyncFreeSnowWhite::Dispatch();
 }
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -49,18 +49,17 @@ enum CCThreadingModel {
 nsresult nsCycleCollector_startup(CCThreadingModel aThreadingModel);
 
 typedef void (*CC_BeforeUnlinkCallback)(void);
 void nsCycleCollector_setBeforeUnlinkCallback(CC_BeforeUnlinkCallback aCB);
 
 typedef void (*CC_ForgetSkippableCallback)(void);
 void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB);
 
-void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false,
-                                      bool aAsyncSnowWhiteFreeing = false);
+void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false);
 
 void nsCycleCollector_dispatchDeferredDeletion();
 
 void nsCycleCollector_collect(bool aManuallyTriggered,
                               nsCycleCollectorResults *aResults,
                               nsICycleCollectorListener *aListener);
 uint32_t nsCycleCollector_suspectedCount();
 void nsCycleCollector_shutdownThreads();