Bug 795086 - Make nsConsoleService only post a LogMessageRunnable to the event queue if there are any observers for it. r=bz
authorSeth Fowler <seth@mozilla.com>
Fri, 28 Sep 2012 09:54:36 -0700
changeset 108622 8e0593f974bb0b79e2b7d099444df1595d48c70b
parent 108621 33fc8988282dc4ec37726bf1c51db75b0482892c
child 108623 ec0dcd401a3ff735815f4209a7ba26d57bcf87a1
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbz
bugs795086
milestone18.0a1
Bug 795086 - Make nsConsoleService only post a LogMessageRunnable to the event queue if there are any observers for it. r=bz
xpcom/base/nsConsoleService.cpp
--- a/xpcom/base/nsConsoleService.cpp
+++ b/xpcom/base/nsConsoleService.cpp
@@ -130,17 +130,17 @@ nsConsoleService::LogMessage(nsIConsoleM
     if (message == nullptr)
         return NS_ERROR_INVALID_ARG;
 
     if (NS_IsMainThread() && mDeliveringMessage) {
         NS_WARNING("Some console listener threw an error while inside itself. Discarding this message");
         return NS_ERROR_FAILURE;
     }
 
-    nsRefPtr<LogMessageRunnable> r = new LogMessageRunnable(message, this);
+    nsRefPtr<LogMessageRunnable> r;
     nsIConsoleMessage *retiredMessage;
 
     NS_ADDREF(message); // early, in case it's same as replaced below.
 
     /*
      * Lock while updating buffer, and while taking snapshot of
      * listeners array.
      */
@@ -175,24 +175,32 @@ nsConsoleService::LogMessage(nsIConsoleM
         mMessages[mCurrent++] = message;
         if (mCurrent == mBufferSize) {
             mCurrent = 0; // wrap around.
             mFull = true;
         }
 
         /*
          * Copy the listeners into the snapshot array - in case a listener
-         * is removed during an Observe(...) notification...
+         * is removed during an Observe(...) notification. If there are no
+         * listeners, don't bother to create the Runnable, since we don't
+         * need to run it and it will hold onto the memory for the message
+         * unnecessarily.
          */
-        mListeners.EnumerateRead(CollectCurrentListeners, r);
+        if (mListeners.Count() > 0) {
+            r = new LogMessageRunnable(message, this);
+            mListeners.EnumerateRead(CollectCurrentListeners, r);
+        }
     }
+
     if (retiredMessage != nullptr)
         NS_RELEASE(retiredMessage);
 
-    NS_DispatchToMainThread(r);
+    if (r)
+        NS_DispatchToMainThread(r);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsConsoleService::LogStringMessage(const PRUnichar *message)
 {
     nsConsoleMessage *msg = new nsConsoleMessage(message);