backout patch for Bug 373462, Bug 385322
authorOlli.Pettay@helsinki.fi
Fri, 21 Sep 2007 03:00:47 -0700
changeset 6188 155ad2e1913a442fee25a9d28ebb17f52936a183
parent 6187 7c9aae671bfb9a998c6999aa1b3dd196006d6992
child 6189 d58d4affa7cdda598379ce011dbd4f8538112588
push idunknown
push userunknown
push dateunknown
bugs373462, 385322
milestone1.9a8pre
backout patch for Bug 373462, Bug 385322
content/base/src/nsXMLHttpRequest.cpp
dom/src/base/nsJSEnvironment.cpp
dom/src/base/nsJSEnvironment.h
dom/src/base/nsWindowRoot.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsCycleCollector.h
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -51,17 +51,16 @@
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIEventListenerManager.h"
 #include "nsGUIEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "prprf.h"
 #include "nsIDOMEventListener.h"
 #include "nsIJSContextStack.h"
-#include "nsJSEnvironment.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsWeakPtr.h"
 #include "nsICharsetAlias.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMClassInfo.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIVariant.h"
@@ -1772,17 +1771,16 @@ nsXMLHttpRequest::RequestCompleted()
     NotifyEventListeners(loadEventListeners, domevent);
   }
 
   if (!(mState & XML_HTTP_REQUEST_GOT_FINAL_STOP)) {
     // We're a multipart request, so we're not done. Reset to opened.
     ChangeState(XML_HTTP_REQUEST_OPENED);
   }
 
-  nsJSContext::MaybeCC(PR_FALSE);
   return rv;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SendAsBinary(const nsAString &aBody)
 {
   char *data = static_cast<char*>(NS_Alloc(aBody.Length() + 1));
   if (!data)
@@ -2315,17 +2313,16 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEv
   mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
 
   ClearEventListeners();
   
   if (event) {
     NotifyEventListeners(errorEventListeners, event);
   }
 
-  nsJSContext::MaybeCC(PR_FALSE);
   return NS_OK;
 }
 
 nsresult
 nsXMLHttpRequest::ChangeState(PRUint32 aState, PRBool aBroadcast,
                               PRBool aClearEventListeners)
 {
   // If we are setting one of the mutually exclusive states,
--- a/dom/src/base/nsJSEnvironment.cpp
+++ b/dom/src/base/nsJSEnvironment.cpp
@@ -149,36 +149,18 @@ static PRLogModuleInfo* gJSDiagnostics;
 #define NS_LOAD_IN_PROCESS_GC_DELAY 4000 // ms
 
 // The amount of time we wait from the first request to GC to actually
 // doing the first GC.
 #define NS_FIRST_GC_DELAY           10000 // ms
 
 #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
 
-// The max number of delayed cycle collects..
-#define NS_MAX_DELAYED_CCOLLECT     45
-// The max number of user interaction notifications in inactive state before
-// we try to call cycle collector more aggressively.
-#define NS_CC_SOFT_LIMIT_INACTIVE   6
-// The max number of user interaction notifications in active state before
-// we try to call cycle collector more aggressively.
-#define NS_CC_SOFT_LIMIT_ACTIVE     12
-// When higher probability MaybeCC is used, the number of sDelayedCCollectCount
-// is multiplied with this number.
-#define NS_PROBABILITY_MULTIPLIER   3
-// Cycle collector should never run more often than this value
-#define NS_MIN_CC_INTERVAL          10000 // ms
-
 // if you add statics here, add them to the list in nsJSRuntime::Startup
 
-static PRUint32 sDelayedCCollectCount;
-static PRUint32 sCCollectCount;
-static PRTime sPreviousCCTime;
-static PRBool sPreviousCCDidCollect;
 static nsITimer *sGCTimer;
 static PRBool sReadyForGC;
 
 // The number of currently pending document loads. This count isn't
 // guaranteed to always reflect reality and can't easily as we don't
 // have an easy place to know when a load ends or is interrupted in
 // all cases. This counter also gets reset if we end up GC'ing while
 // we're waiting for a slow page to load. IOW, this count may be 0
@@ -212,85 +194,16 @@ static PRTime sMaxScriptRunTime;
 static PRTime sMaxChromeScriptRunTime;
 
 static nsIScriptSecurityManager *sSecurityManager;
 
 static nsICollation *gCollation;
 
 static nsIUnicodeDecoder *gDecoder;
 
-// nsUserActivityObserver observes user-interaction-active and
-// user-interaction-inactive notifications. It counts the number of
-// notifications and if the number is bigger than NS_CC_SOFT_LIMIT_ACTIVE
-// (in case the current notification is user-interaction-active) or
-// NS_CC_SOFT_LIMIT_INACTIVE (current notification is user-interaction-inactive)
-// MaybeCC is called with aHigherParameter set to PR_TRUE, otherwise PR_FALSE.
-//
-// When moving from active state to inactive, nsJSContext::CC() is called
-// unless the timer related to page load is active.
-
-class nsUserActivityObserver : public nsIObserver
-{
-public:
-  nsUserActivityObserver()
-  : mUserActivityCounter(0), mOldCCollectCount(0), mUserIsActive(PR_FALSE) {}
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-private:
-  PRUint32 mUserActivityCounter;
-  PRUint32 mOldCCollectCount;
-  PRBool   mUserIsActive;
-};
-
-NS_IMPL_ISUPPORTS1(nsUserActivityObserver, nsIObserver)
-
-NS_IMETHODIMP
-nsUserActivityObserver::Observe(nsISupports* aSubject, const char* aTopic,
-                                const PRUnichar* aData)
-{
-  if (mOldCCollectCount != sCCollectCount) {
-    mOldCCollectCount = sCCollectCount;
-    // Cycle collector was called between user interaction notifications, so
-    // we can reset the counter.
-    mUserActivityCounter = 0;
-  }
-  PRBool higherProbability = PR_FALSE;
-  ++mUserActivityCounter;
-  if (!strcmp(aTopic, "user-interaction-inactive")) {
-#ifdef DEBUG_smaug
-    printf("user-interaction-inactive\n");
-#endif
-    if (mUserIsActive) {
-      mUserIsActive = PR_FALSE;
-      if (!sGCTimer) {
-        nsJSContext::CC();
-        return NS_OK;
-      }
-    }
-    higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_INACTIVE);
-  } else if (!strcmp(aTopic, "user-interaction-active")) {
-#ifdef DEBUG_smaug
-    printf("user-interaction-active\n");
-#endif
-    mUserIsActive = PR_TRUE;
-    higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_ACTIVE);
-  } else if (!strcmp(aTopic, "xpcom-shutdown")) {
-    nsCOMPtr<nsIObserverService> obs =
-      do_GetService("@mozilla.org/observer-service;1");
-    if (obs) {
-      obs->RemoveObserver(this, "user-interaction-active");
-      obs->RemoveObserver(this, "user-interaction-inactive");
-      obs->RemoveObserver(this, "xpcom-shutdown");
-    }
-    return NS_OK;
-  }
-  nsJSContext::MaybeCC(higherProbability);
-  return NS_OK;
-}
-
 /****************************************************************
  ************************** AutoFree ****************************
  ****************************************************************/
 
 class AutoFree {
 public:
   AutoFree(void *aPtr) : mPtr(aPtr) {
   }
@@ -3302,60 +3215,16 @@ nsJSContext::ScriptExecuted()
 }
 
 NS_IMETHODIMP
 nsJSContext::PreserveWrapper(nsIXPConnectWrappedNative *aWrapper)
 {
   return nsDOMClassInfo::PreserveNodeWrapper(aWrapper);
 }
 
-//static
-void
-nsJSContext::CC()
-{
-#ifdef DEBUG_smaug
-  printf("Will run cycle collector\n");
-#endif
-  sPreviousCCTime = PR_Now();
-  sDelayedCCollectCount = 0;
-  ++sCCollectCount;
-  // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so
-  // we do not explicitly call ::JS_GC() here.
-  sPreviousCCDidCollect = nsCycleCollector_collect();
-#ifdef DEBUG_smaug
-  printf("%s\n", sPreviousCCDidCollect ?
-                   "Cycle collector did collect nodes" :
-                   "Cycle collector did not collect nodes");
-#endif
-}
-
-//static
-void
-nsJSContext::MaybeCC(PRBool aHigherProbability)
-{
-  ++sDelayedCCollectCount;
-  // Increase the probability also if the previous call to cycle collector
-  // collected something.
-  if (aHigherProbability || sPreviousCCDidCollect) {
-    sDelayedCCollectCount *= NS_PROBABILITY_MULTIPLIER;
-  }
-
-  if (!sGCTimer && (sDelayedCCollectCount > NS_MAX_DELAYED_CCOLLECT)) {
-    if ((PR_Now() - sPreviousCCTime) >=
-        PRTime(NS_MIN_CC_INTERVAL * PR_USEC_PER_MSEC)) {
-      nsJSContext::CC();
-    }
-#ifdef DEBUG_smaug
-    else {
-      printf("Running cycle collector was delayed: NS_MIN_CC_INTERVAL\n");
-    }
-#endif
-  }
-}
-
 NS_IMETHODIMP
 nsJSContext::Notify(nsITimer *timer)
 {
   NS_ASSERTION(mContext, "No context in nsJSContext::Notify()!");
 
   NS_RELEASE(sGCTimer);
 
   if (sPendingLoadCount == 0 || sLoadInProgressGCTimer) {
@@ -3364,17 +3233,19 @@ nsJSContext::Notify(nsITimer *timer)
     // Reset sPendingLoadCount in case the timer that fired was a
     // timer we scheduled due to a normal GC timer firing while
     // documents were loading. If this happens we're waiting for a
     // document that is taking a long time to load, and we effectively
     // ignore the fact that the currently loading documents are still
     // loading and move on as if they weren't.
     sPendingLoadCount = 0;
 
-    nsJSContext::MaybeCC(PR_TRUE);
+    // nsCycleCollector_collect() will run a ::JS_GC() indirectly,
+    // so we do not explicitly call ::JS_GC() here. 
+    nsCycleCollector_collect();
   } else {
     FireGCTimer(PR_TRUE);
   }
 
   sReadyForGC = PR_TRUE;
 
   return NS_OK;
 }
@@ -3397,17 +3268,19 @@ nsJSContext::LoadEnd()
   }
 
   if (!sPendingLoadCount && sLoadInProgressGCTimer) {
     sGCTimer->Cancel();
 
     NS_RELEASE(sGCTimer);
     sLoadInProgressGCTimer = PR_FALSE;
 
-    nsJSContext::MaybeCC(PR_TRUE);
+    // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so
+    // we do not explicitly call ::JS_GC() here.
+    nsCycleCollector_collect();
   }
 }
 
 void
 nsJSContext::FireGCTimer(PRBool aLoadInProgress)
 {
   // Always clear the newborn roots.  If there's already a timer, this
   // will let the GC from that timer clean up properly.  If we're going
@@ -3424,17 +3297,19 @@ nsJSContext::FireGCTimer(PRBool aLoadInP
 
   if (!sGCTimer) {
     NS_WARNING("Failed to create timer");
 
     // Reset sLoadInProgressGCTimer since we're not able to fire the
     // timer.
     sLoadInProgressGCTimer = PR_FALSE;
 
-    nsJSContext::MaybeCC(PR_TRUE);
+    // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so
+    // we do not explicitly call ::JS_GC() here.
+    nsCycleCollector_collect();
 
     return;
   }
 
   static PRBool first = PR_TRUE;
 
   sGCTimer->InitWithCallback(this,
                              first ? NS_FIRST_GC_DELAY :
@@ -3533,20 +3408,16 @@ nsJSRuntime::ParseVersion(const nsString
     return NS_OK;
 }
 
 //static
 void
 nsJSRuntime::Startup()
 {
   // initialize all our statics, so that we can restart XPCOM
-  sDelayedCCollectCount = 0;
-  sCCollectCount = 0;
-  sPreviousCCTime = 0;
-  sPreviousCCDidCollect = PR_FALSE;
   sGCTimer = nsnull;
   sReadyForGC = PR_FALSE;
   sLoadInProgressGCTimer = PR_FALSE;
   sPendingLoadCount = 0;
   gNameSpaceManager = nsnull;
   sRuntimeService = nsnull;
   sRuntime = nsnull;
   gOldJSGCCallback = nsnull;
@@ -3671,25 +3542,16 @@ nsJSRuntime::Init()
   MaxScriptRunTimePrefChangedCallback("dom.max_script_run_time", nsnull);
 
   nsContentUtils::RegisterPrefCallback("dom.max_chrome_script_run_time",
                                        MaxScriptRunTimePrefChangedCallback,
                                        nsnull);
   MaxScriptRunTimePrefChangedCallback("dom.max_chrome_script_run_time",
                                       nsnull);
 
-  nsCOMPtr<nsIObserverService> obs =
-    do_GetService("@mozilla.org/observer-service;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsIObserver* activityObserver = new nsUserActivityObserver();
-  NS_ENSURE_TRUE(activityObserver, NS_ERROR_OUT_OF_MEMORY);
-  obs->AddObserver(activityObserver, "user-interaction-inactive", PR_FALSE);
-  obs->AddObserver(activityObserver, "user-interaction-active", PR_FALSE);
-  obs->AddObserver(activityObserver, "xpcom-shutdown", PR_FALSE);
-
   rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &sSecurityManager);
 
   sIsInitialized = NS_SUCCEEDED(rv);
 
   return rv;
 }
 
 void nsJSRuntime::ShutDown()
--- a/dom/src/base/nsJSEnvironment.h
+++ b/dom/src/base/nsJSEnvironment.h
@@ -165,34 +165,16 @@ public:
 
   NS_DECL_NSIXPCSCRIPTNOTIFY
 
   NS_DECL_NSITIMERCALLBACK
 
   static void LoadStart();
   static void LoadEnd();
 
-  // CC does always call cycle collector and it also updates the counters
-  // that MaybeCC uses.
-  static void CC();
-
-  // MaybeCC calls cycle collector if certain conditions are fulfilled.
-  // The conditions are:
-  // - The timer related to page load (sGCTimer) must not be active.
-  // - At least NS_MIN_CC_INTERVAL milliseconds must have elapsed since the
-  //   previous cycle collector call.
-  // - Certain number of MaybeCC calls have occurred.
-  //   The number of needed MaybeCC calls depends on the aHigherProbability
-  //   parameter. If the parameter is true, probability for calling cycle
-  //   collector rises increasingly. If the parameter is all the time false,
-  //   at least NS_MAX_DELAYED_CCOLLECT MaybeCC calls are needed.
-  //   If the previous call to cycle collector did collect something,
-  //   MaybeCC works effectively as if aHigherProbability was true.
-  static void MaybeCC(PRBool aHigherProbability);
-
 protected:
   nsresult InitializeExternalClasses();
   nsresult InitializeLiveConnectClasses(JSObject *aGlobalObj);
   // aHolder should be holding our global object
   nsresult FindXPCNativeWrapperClass(nsIXPConnectJSObjectHolder *aHolder);
 
   // Helper to convert xpcom datatypes to jsvals.
   nsresult ConvertSupportsTojsvals(nsISupports *aArgs,
--- a/dom/src/base/nsWindowRoot.cpp
+++ b/dom/src/base/nsWindowRoot.cpp
@@ -49,105 +49,40 @@
 #include "nsContentCID.h"
 #include "nsIEventStateManager.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsFocusController.h"
 #include "nsString.h"
 #include "nsEventDispatcher.h"
 #include "nsIProgrammingLanguage.h"
-#include "nsIObserverService.h"
-#include "nsServiceManagerUtils.h"
-#include "nsITimer.h"
+
 #include "nsCycleCollectionParticipant.h"
 
-#define NS_USER_INTERACTION_INTERVAL 5000 // ms
-
 static NS_DEFINE_CID(kEventListenerManagerCID,    NS_EVENTLISTENERMANAGER_CID);
-static PRUint32 gMouseOrKeyboardEventCounter = 0;
-static PRUint32 gWindowRootCount = 0;
-static nsITimer* gUserInteractionTimer = nsnull;
-static nsITimerCallback* gUserInteractionTimerCallback = nsnull;
-
-class nsUITimerCallback : public nsITimerCallback
-{
-public:
-  nsUITimerCallback() : mPreviousCount(0) {}
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITIMERCALLBACK
-private:
-  PRUint32 mPreviousCount;
-};
-
-NS_IMPL_ISUPPORTS1(nsUITimerCallback, nsITimerCallback)
-
-// If aTimer is nsnull, this method always sends "user-interaction-inactive"
-// notification.
-NS_IMETHODIMP
-nsUITimerCallback::Notify(nsITimer* aTimer)
-{
-  nsresult rv;
-  nsCOMPtr<nsIObserverService> obs =
-      do_GetService("@mozilla.org/observer-service;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) {
-    gMouseOrKeyboardEventCounter = 0;
-    obs->NotifyObservers(nsnull, "user-interaction-inactive", nsnull);
-  } else {
-    obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
-  }
-  mPreviousCount = gMouseOrKeyboardEventCounter;
-  return NS_OK;
-}
 
 nsWindowRoot::nsWindowRoot(nsIDOMWindow* aWindow)
 {
   mWindow = aWindow;
 
   // Create and init our focus controller.
   nsFocusController::Create(getter_AddRefs(mFocusController));
 
   nsCOMPtr<nsIDOMFocusListener> focusListener(do_QueryInterface(mFocusController));
   mRefCnt.incr(static_cast<nsIDOMEventTarget*>(this));
   AddEventListener(NS_LITERAL_STRING("focus"), focusListener, PR_TRUE);
   AddEventListener(NS_LITERAL_STRING("blur"), focusListener, PR_TRUE);
   mRefCnt.decr(static_cast<nsIDOMEventTarget*>(this));
-
-  if (gWindowRootCount == 0) {
-    gUserInteractionTimerCallback = new nsUITimerCallback();
-    if (gUserInteractionTimerCallback) {
-      NS_ADDREF(gUserInteractionTimerCallback);
-      CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer);
-      if (gUserInteractionTimer) {
-        gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback,
-                                                NS_USER_INTERACTION_INTERVAL,
-                                                nsITimer::TYPE_REPEATING_SLACK);
-      }
-    }
-  }
-  ++gWindowRootCount;
 }
 
 nsWindowRoot::~nsWindowRoot()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
-
-  --gWindowRootCount;
-  if (gWindowRootCount == 0) {
-    if (gUserInteractionTimerCallback) {
-      gUserInteractionTimerCallback->Notify(nsnull);
-      NS_RELEASE(gUserInteractionTimerCallback);
-    }
-    if (gUserInteractionTimer) {
-      gUserInteractionTimer->Cancel();
-      NS_RELEASE(gUserInteractionTimer);
-    }
-  }
 }
 
 NS_IMPL_CYCLE_COLLECTION_2(nsWindowRoot, mListenerManager, mFocusController)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
@@ -307,31 +242,16 @@ nsWindowRoot::GetSystemEventGroup(nsIDOM
 
 nsresult
 nsWindowRoot::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = PR_TRUE;
   aVisitor.mForceContentDispatch = PR_TRUE; //FIXME! Bug 329119
   // To keep mWindow alive
   aVisitor.mItemData = mWindow;
-  if (NS_IS_TRUSTED_EVENT(aVisitor.mEvent) &&
-      ((aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT  &&
-        static_cast<nsMouseEvent*>(aVisitor.mEvent)->reason ==
-          nsMouseEvent::eReal) ||
-       aVisitor.mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT ||
-       aVisitor.mEvent->eventStructType == NS_KEY_EVENT)) {
-    if (gMouseOrKeyboardEventCounter == 0) {
-      nsCOMPtr<nsIObserverService> obs =
-        do_GetService("@mozilla.org/observer-service;1");
-      if (obs) {
-        obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
-      }
-    }
-    ++gMouseOrKeyboardEventCounter;
-  }
   return NS_OK;
 }
 
 nsresult
 nsWindowRoot::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   return NS_OK;
 }
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -864,17 +864,17 @@ struct nsCycleCollector
 
     nsCycleCollector();
     ~nsCycleCollector();
 
     PRBool Suspect(nsISupports *n, PRBool current = PR_FALSE);
     PRBool Forget(nsISupports *n);
     void Allocated(void *n, size_t sz);
     void Freed(void *n);
-    PRBool Collect(PRUint32 aTryCollections = 1);
+    void Collect(PRUint32 aTryCollections = 1);
     void Shutdown();
 
 #ifdef DEBUG_CC
     nsCycleCollectorStats mStats;    
 
     FILE *mPtrLog;
 
     void MaybeDrawGraphs(GCGraph &graph);
@@ -2016,28 +2016,27 @@ nsCycleCollector::Freed(void *n)
             if (!mPtrLog)
                 mPtrLog = fopen("pointer_log", "w");
             fprintf(mPtrLog, "R %p\n", n);
         }
     }
 }
 #endif
 
-PRBool
+void
 nsCycleCollector::Collect(PRUint32 aTryCollections)
 {
-    PRBool didCollect = PR_FALSE;
 #if defined(DEBUG_CC) && !defined(__MINGW32__)
     if (!mParams.mDoNothing && mParams.mHookMalloc)
         InitMemHook();
 #endif
 
     // This can legitimately happen in a few cases. See bug 383651.
     if (mCollectionInProgress)
-        return didCollect;
+        return;
 
 #ifdef COLLECT_TIME_DEBUG
     printf("cc: Starting nsCycleCollector::Collect(%d)\n", aTryCollections);
     PRTime start = PR_Now(), now;
 #endif
 
     mCollectionInProgress = PR_TRUE;
 
@@ -2164,21 +2163,18 @@ nsCycleCollector::Collect(PRUint32 aTryC
 
                 --aTryCollections;
 
                 // Since runtimes may add wrappers to the purple buffer
                 // (which will mean we won't stop repeating due to the
                 // mBuf.GetSize() == 0 check above), we should stop
                 // repeating collections if we didn't collect anything
                 // this time.
-                if (!collected) {
+                if (!collected)
                     aTryCollections = 0;
-                } else {
-                    didCollect = PR_TRUE;
-                }
             }
 
 #ifdef DEBUG_CC
             mStats.mCollection++;
             if (mParams.mReportStats)
                 mStats.Dump();
 #endif
         }
@@ -2193,17 +2189,16 @@ nsCycleCollector::Collect(PRUint32 aTryC
 
 #ifdef COLLECT_TIME_DEBUG
     printf("cc: Collect() took %lldms\n",
            (PR_Now() - start) / PR_USEC_PER_MSEC);
 #endif
 #ifdef DEBUG_CC
     ExplainLiveExpectedGarbage();
 #endif
-    return didCollect;
 }
 
 void
 nsCycleCollector::Shutdown()
 {
     // Here we want to run a final collection on everything we've seen
     // buffered, irrespective of age; then permanently disable
     // the collector because the program is shutting down.
@@ -2594,20 +2589,21 @@ PRBool
 NS_CycleCollectorForget(nsISupports *n)
 {
     if (sCollector)
         return sCollector->Forget(n);
     return PR_FALSE;
 }
 
 
-PRBool
+void 
 nsCycleCollector_collect()
 {
-    return sCollector ? sCollector->Collect() : PR_FALSE;
+    if (sCollector)
+        sCollector->Collect();
 }
 
 nsresult 
 nsCycleCollector_startup()
 {
     NS_ASSERTION(!sCollector, "Forgot to call nsCycleCollector_shutdown?");
 
     sCollector = new nsCycleCollector();
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -61,18 +61,17 @@ struct nsCycleCollectionLanguageRuntime
     virtual void SuspectExtraPointers() = 0;
 #endif
 };
 
 // PRBool nsCycleCollector_suspect(nsISupports *n);
 NS_COM void nsCycleCollector_suspectCurrent(nsISupports *n);
 // NS_COM PRBool nsCycleCollector_forget(nsISupports *n);
 nsresult nsCycleCollector_startup();
-// Returns PR_TRUE if some nodes were collected.
-NS_COM PRBool nsCycleCollector_collect();
+NS_COM void nsCycleCollector_collect();
 void nsCycleCollector_shutdown();
 
 #ifdef DEBUG
 NS_COM void nsCycleCollector_DEBUG_shouldBeFreed(nsISupports *n);
 NS_COM void nsCycleCollector_DEBUG_wasFreed(nsISupports *n);
 #endif
 
 // Helpers for interacting with language-identified scripts