Bug 816064 - Assert against NULL objects in deferred release (r=mccr8)
authorBill McCloskey <wmccloskey@mozilla.com>
Thu, 13 Dec 2012 11:18:41 -0800
changeset 115958 bcc487178c04933d7fe528303c3179863655f637
parent 115957 85d46df9a1257db4a846273a5280c087d938705e
child 115959 d3171bd3585c90d2855e3b296acd230c4bc2a9e9
push id24034
push useremorley@mozilla.com
push dateFri, 14 Dec 2012 15:28:57 +0000
treeherdermozilla-central@50d8f411d305 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs816064
milestone20.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 816064 - Assert against NULL objects in deferred release (r=mccr8)
js/xpconnect/src/XPCJSRuntime.cpp
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -533,18 +533,18 @@ DoDeferredRelease(nsTArray<T> &array)
         T wrapper = array[count-1];
         array.RemoveElementAt(count-1);
         NS_RELEASE(wrapper);
     }
 }
 
 struct DeferredFinalizeFunction
 {
-  XPCJSRuntime::DeferredFinalizeFunction run;
-  void* data;
+    XPCJSRuntime::DeferredFinalizeFunction run;
+    void *data;
 };
 
 class XPCIncrementalReleaseRunnable : public nsRunnable
 {
     XPCJSRuntime *runtime;
     nsTArray<nsISupports *> items;
     nsAutoTArray<DeferredFinalizeFunction, 16> deferredFinalizeFunctions;
     uint32_t finalizeFunctionToRun;
@@ -556,21 +556,20 @@ class XPCIncrementalReleaseRunnable : pu
     virtual ~XPCIncrementalReleaseRunnable();
 
     void ReleaseNow(bool limited);
 
     NS_DECL_NSIRUNNABLE
 };
 
 bool
-ReleaseSliceNow(uint32_t slice, void* data)
+ReleaseSliceNow(uint32_t slice, void *data)
 {
     MOZ_ASSERT(slice > 0, "nonsensical/useless call with slice == 0");
-    nsTArray<nsISupports *>* items =
-        static_cast<nsTArray<nsISupports *>*>(data);
+    nsTArray<nsISupports *> *items = static_cast<nsTArray<nsISupports *>*>(data);
 
     slice = NS_MIN(slice, items->Length());
     for (uint32_t i = 0; i < slice; ++i) {
         // Remove (and NS_RELEASE) the last entry in "items":
         uint32_t lastItemIdx = items->Length() - 1;
 
         nsISupports *wrapper = items->ElementAt(lastItemIdx);
         items->RemoveElementAt(lastItemIdx);
@@ -583,22 +582,21 @@ ReleaseSliceNow(uint32_t slice, void* da
 
 XPCIncrementalReleaseRunnable::XPCIncrementalReleaseRunnable(XPCJSRuntime *rt,
                                                              nsTArray<nsISupports *> &items)
   : runtime(rt),
     finalizeFunctionToRun(0)
 {
     nsLayoutStatics::AddRef();
     this->items.SwapElements(items);
-    DeferredFinalizeFunction* function =
-        deferredFinalizeFunctions.AppendElement();
+    DeferredFinalizeFunction *function = deferredFinalizeFunctions.AppendElement();
     function->run = ReleaseSliceNow;
     function->data = &this->items;
     for (uint32_t i = 0; i < rt->mDeferredFinalizeFunctions.Length(); ++i) {
-        void* data = (rt->mDeferredFinalizeFunctions[i].start)();
+        void *data = (rt->mDeferredFinalizeFunctions[i].start)();
         if (data) {
             function = deferredFinalizeFunctions.AppendElement();
             function->run = rt->mDeferredFinalizeFunctions[i].run;
             function->data = data;
         }
     }
 }
 
@@ -616,32 +614,32 @@ XPCIncrementalReleaseRunnable::ReleaseNo
                "We should have at least ReleaseSliceNow to run");
     MOZ_ASSERT(finalizeFunctionToRun < deferredFinalizeFunctions.Length(),
                "No more finalizers to run?");
 
     TimeDuration sliceTime = TimeDuration::FromMilliseconds(SliceMillis);
     TimeStamp started = TimeStamp::Now();
     bool timeout = false;
     do {
-        const DeferredFinalizeFunction& function =
+        const DeferredFinalizeFunction &function =
             deferredFinalizeFunctions[finalizeFunctionToRun];
         if (limited) {
             bool done = false;
             while (!timeout && !done) {
-                /* We don't want to read the clock too often, so we try to
-                   release slices of 100 items. */
+                /*
+                 * We don't want to read the clock too often, so we try to
+                 * release slices of 100 items.
+                 */
                 done = function.run(100, function.data);
                 timeout = TimeStamp::Now() - started >= sliceTime;
             }
-            if (done) {
+            if (done)
                 ++finalizeFunctionToRun;
-            }
-            if (timeout) {
+            if (timeout)
                 break;
-            }
         } else {
             function.run(UINT32_MAX, function.data);
             MOZ_ASSERT(!items.Length());
             ++finalizeFunctionToRun;
         }
     } while (finalizeFunctionToRun < deferredFinalizeFunctions.Length());
 
     if (finalizeFunctionToRun == deferredFinalizeFunctions.Length()) {
@@ -731,20 +729,18 @@ XPCJSRuntime::GCCallback(JSRuntime *rt, 
                 self->mReleaseRunnable->ReleaseNow(false);
 
             // Do any deferred releases of native objects.
             if (js::WasIncrementalGC(rt)) {
                 self->ReleaseIncrementally(self->mNativesToReleaseArray);
             } else {
                 DoDeferredRelease(self->mNativesToReleaseArray);
                 for (uint32_t i = 0; i < self->mDeferredFinalizeFunctions.Length(); ++i) {
-                    void* data = self->mDeferredFinalizeFunctions[i].start();
-                    if (data) {
+                    if (void *data = self->mDeferredFinalizeFunctions[i].start())
                         self->mDeferredFinalizeFunctions[i].run(UINT32_MAX, data);
-                    }
                 }
             }
             break;
         }
     }
 
     nsTArray<JSGCCallback> callbacks(self->extraGCCallbacks);
     for (uint32_t i = 0; i < callbacks.Length(); ++i)
@@ -2602,19 +2598,19 @@ XPCJSRuntime::OnJSContextNew(JSContext *
 
     // we want to mark the global object ourselves since we use a different color
     JS_ToggleOptions(cx, JSOPTION_UNROOTED_GLOBAL);
 
     return true;
 }
 
 bool
-XPCJSRuntime::DeferredRelease(nsISupports* obj)
+XPCJSRuntime::DeferredRelease(nsISupports *obj)
 {
-    NS_ASSERTION(obj, "bad param");
+    MOZ_ASSERT(obj);
 
     if (mNativesToReleaseArray.IsEmpty()) {
         // This array sometimes has 1000's
         // of entries, and usually has 50-200 entries. Avoid lots
         // of incremental grows.  We compact it down when we're done.
         mNativesToReleaseArray.SetCapacity(256);
     }
     return mNativesToReleaseArray.AppendElement(obj) != nullptr;