From 4d45062dafa644c52cc990d4ba68e5744389639c Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Thu, 13 Nov 2014 07:11:55 -0800 Subject: [PATCH] Bug 868139 - Don't redo unmarking work in nsGlobalWindow::CanSkip if we already did it. r=smaug This causes quadratic behavior in forgetSkippable when there are many timeouts. To avoid this, we mark the CC generation of the last time we ran CanSkip on the window, and don't do it again if it hasn't changed. --- dom/base/nsGlobalWindow.cpp | 7 ++++++- dom/base/nsGlobalWindow.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 74d4c1e0ed7a..f7b8801b3d28 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1132,7 +1132,8 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) #endif mCleanedUp(false), mDialogAbuseCount(0), - mAreDialogsEnabled(true) + mAreDialogsEnabled(true), + mCanSkipCCGeneration(0) { nsLayoutStatics::AddRef(); @@ -1683,6 +1684,10 @@ MarkXBLHandlers(nsXBLPrototypeHandler* aKey, JS::Heap& aData, void* a NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindow) if (tmp->IsBlackForCC(false)) { + if (nsCCUncollectableMarker::InGeneration(tmp->mCanSkipCCGeneration)) { + return true; + } + tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration; if (tmp->mCachedXBLPrototypeHandlers) { tmp->mCachedXBLPrototypeHandlers->Enumerate(MarkXBLHandlers, nullptr); } diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 5150f4afca1e..3045c5515a25 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1628,6 +1628,9 @@ protected: nsRefPtr mSpeechSynthesis; #endif + // This is the CC generation the last time we called CanSkip. + uint32_t mCanSkipCCGeneration; + friend class nsDOMScriptableHelper; friend class nsDOMWindowUtils; friend class PostMessageEvent;