Bug 895578 - Make SnowWhiteKiller to use fallible TArray, r=mccr8
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 19 Jul 2013 15:53:16 +0300
changeset 152283 91168463eaf283b5b20c0a500017489bc5fa9ce3
parent 152282 0d0263a58f06f92d9648d23c9368cd05ea5241f9
child 152302 7b2c82ae98dbd9dcefbfa593be7fa7ae7ef8cbe9
push id382
push userakeybl@mozilla.com
push dateMon, 21 Oct 2013 21:47:13 +0000
treeherdermozilla-release@5f1868ee45cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs895578
milestone25.0a1
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
Bug 895578 - Make SnowWhiteKiller to use fallible TArray, r=mccr8
dom/base/nsJSEnvironment.cpp
xpcom/base/nsCycleCollector.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3022,16 +3022,19 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::G
     sCCLockedOut = true;
     nsJSContext::KillShrinkGCBuffersTimer();
   } else if (aProgress == JS::GC_CYCLE_END) {
     sCCLockedOut = false;
   }
 
   // The GC has more work to do, so schedule another GC slice.
   if (aProgress == JS::GC_SLICE_END) {
+    if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
+      nsCycleCollector_dispatchDeferredDeletion();
+    }
     nsJSContext::KillInterSliceGCTimer();
     if (!sShuttingDown) {
       CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
       sInterSliceGCTimer->InitWithFuncCallback(InterSliceGCTimerFired,
                                                NULL,
                                                NS_INTERSLICE_GC_DELAY,
                                                nsITimer::TYPE_ONE_SHOT);
     }
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2153,17 +2153,25 @@ struct SnowWhiteObject
   nsCycleCollectingAutoRefCnt* mRefCnt;
 };
 
 class SnowWhiteKiller
 {
 public:
     SnowWhiteKiller(uint32_t aMaxCount)
     {
-        mObjects.SetCapacity(aMaxCount);
+        while (true) {
+            if (mObjects.SetCapacity(aMaxCount)) {
+                break;
+            }
+            if (aMaxCount == 1) {
+                NS_RUNTIMEABORT("Not enough memory to even delete objects!");
+            }
+            aMaxCount /= 2;
+        }
     }
 
     ~SnowWhiteKiller()
     {
         for (uint32_t i = 0; i < mObjects.Length(); ++i) {
             SnowWhiteObject& o = mObjects[i];
             if (!o.mRefCnt->get() && !o.mRefCnt->IsInPurpleBuffer()) {
                 o.mRefCnt->stabilizeForDeletion();
@@ -2176,27 +2184,28 @@ public:
     Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
     {
         MOZ_ASSERT(aEntry->mObject, "Null object in purple buffer");
         if (!aEntry->mRefCnt->get()) {
             void *o = aEntry->mObject;
             nsCycleCollectionParticipant *cp = aEntry->mParticipant;
             CanonicalizeParticipant(&o, &cp);
             SnowWhiteObject swo = { o, cp, aEntry->mRefCnt };
-            mObjects.AppendElement(swo);
-            aBuffer.Remove(aEntry);
+            if (mObjects.AppendElement(swo)) {
+                aBuffer.Remove(aEntry);
+            }
         }
     }
 
     bool HasSnowWhiteObjects()
     {
       return mObjects.Length() > 0;
     }
 private:
-    nsTArray<SnowWhiteObject> mObjects;
+    FallibleTArray<SnowWhiteObject> mObjects;
 };
 
 class RemoveSkippableVisitor : public SnowWhiteKiller
 {
 public:
     RemoveSkippableVisitor(uint32_t aMaxCount, bool aRemoveChildlessNodes,
                            CC_ForgetSkippableCallback aCb)
         : SnowWhiteKiller(aMaxCount),