Bug 669158. Don't try to unclamp the dummy timeout. r=jst
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 08 Jul 2011 14:04:25 -0400
changeset 73371 9e84bca4fc424f2f09acc6ddccb28c9cec82c854
parent 73370 cd7a7ad30fca2e4fe2fa8a46f3b1263e1c8999a8
child 73372 2ca111e7c2fb715751cca2b7ce6b0ae51d7c25b5
push id235
push userbzbarsky@mozilla.com
push dateTue, 27 Sep 2011 17:13:04 +0000
treeherdermozilla-beta@2d1e082d176a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs669158
milestone8.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 669158. Don't try to unclamp the dummy timeout. r=jst
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9084,16 +9084,18 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
   PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout);
 
   // Don't let ClearWindowTimeouts throw away our stack-allocated
   // dummy timeout.
   dummy_timeout.AddRef();
   dummy_timeout.AddRef();
 
   last_insertion_point = mTimeoutInsertionPoint;
+  // If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
+  // the logic in ResetTimersForNonBackgroundWindow will need to change.
   mTimeoutInsertionPoint = &dummy_timeout;
 
   for (timeout = FirstTimeout();
        timeout != &dummy_timeout && !IsFrozen();
        timeout = nextTimeout) {
     nextTimeout = timeout->Next();
 
     if (timeout->mFiringDepth != firingDepth) {
@@ -9421,17 +9423,26 @@ nsresult nsGlobalWindow::ResetTimersForN
                    NS_ERROR_NOT_INITIALIZED);
 
   if (IsFrozen() || mTimeoutsSuspendDepth) {
     return NS_OK;
   }
 
   TimeStamp now = TimeStamp::Now();
 
-  for (nsTimeout *timeout = FirstTimeout(); IsTimeout(timeout); ) {
+  // If mTimeoutInsertionPoint is non-null, we're in the middle of firing
+  // timers and the timers we're planning to fire all come before
+  // mTimeoutInsertionPoint; mTimeoutInsertionPoint itself is a dummy timeout
+  // with an mWhen that may be semi-bogus.  In that case, we don't need to do
+  // anything with mTimeoutInsertionPoint or anything before it, so should
+  // start at the timer after mTimeoutInsertionPoint, if there is one.
+  // Otherwise, start at the beginning of the list.
+  for (nsTimeout *timeout = mTimeoutInsertionPoint ?
+         mTimeoutInsertionPoint->Next() : FirstTimeout();
+       IsTimeout(timeout); ) {
     // It's important that this check be <= so that we guarantee that
     // taking NS_MAX with |now| won't make a quantity equal to
     // timeout->mWhen below.
     if (timeout->mWhen <= now) {
       timeout = timeout->Next();
       continue;
     }
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -909,18 +909,24 @@ protected:
   nsCOMPtr<nsIDOMStorage>      mSessionStorage;
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
   nsCOMPtr<nsIPrincipal> mOpenerScriptPrincipal; // strong; used to determine
                                                  // whether to clear scope
 
   // These member variable are used only on inner windows.
   nsRefPtr<nsEventListenerManager> mListenerManager;
+  // mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
+  // non-null.  In that case, the dummy timeout pointed to by
+  // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
+  // that come after it.
   PRCList                       mTimeouts;
   // If mTimeoutInsertionPoint is non-null, insertions should happen after it.
+  // This is a dummy timeout at the moment; if that ever changes, the logic in
+  // ResetTimersForNonBackgroundWindow needs to change.
   nsTimeout*                    mTimeoutInsertionPoint;
   PRUint32                      mTimeoutPublicIdCounter;
   PRUint32                      mTimeoutFiringDepth;
   nsRefPtr<nsLocation>          mLocation;
   nsRefPtr<nsHistory>           mHistory;
 
   // Holder of the dummy java plugin, used to expose window.java and
   // window.packages.