Bug 1404297 - Change the way we iterate over our links to update. r=smaug

MozReview-Commit-ID: BTADrB9itjh

--HG--
extra : rebase_source : 858f50bdbe2c35541b6a1975b0814e560db254c8
This commit is contained in:
Blake Kaplan 2018-02-27 17:54:00 -05:00
Родитель 8ff2f4657b
Коммит 4eb24aab7b
2 изменённых файлов: 27 добавлений и 32 удалений

Просмотреть файл

@ -1445,8 +1445,8 @@ nsIDocument::nsIDocument()
mHasHadScriptHandlingObject(false),
mIsBeingUsedAsImage(false),
mIsSyntheticDocument(false),
mHasLinksToUpdate(false),
mHasLinksToUpdateRunnable(false),
mFlushingPendingLinkUpdates(false),
mMayHaveDOMMutationObservers(false),
mMayHaveAnimationObservers(false),
mHasMixedActiveContentLoaded(false),
@ -1491,7 +1491,6 @@ nsIDocument::nsIDocument()
mType(eUnknown),
mDefaultElementType(0),
mAllowXULXBL(eTriUnset),
mIsLinkUpdateRegistrationsForbidden(false),
mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS),
mSandboxFlags(0),
mPartID(0),
@ -9612,15 +9611,13 @@ nsIDocument::EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator,
void
nsIDocument::RegisterPendingLinkUpdate(Link* aLink)
{
MOZ_RELEASE_ASSERT(!mIsLinkUpdateRegistrationsForbidden);
if (aLink->HasPendingLinkUpdate()) {
return;
}
aLink->SetHasPendingLinkUpdate();
if (!mHasLinksToUpdateRunnable) {
if (!mHasLinksToUpdateRunnable && !mFlushingPendingLinkUpdates) {
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod("nsIDocument::FlushPendingLinkUpdatesFromRunnable",
this,
@ -9637,7 +9634,6 @@ nsIDocument::RegisterPendingLinkUpdate(Link* aLink)
}
mLinksToUpdate.InfallibleAppend(aLink);
mHasLinksToUpdate = true;
}
void
@ -9651,24 +9647,26 @@ nsIDocument::FlushPendingLinkUpdatesFromRunnable()
void
nsIDocument::FlushPendingLinkUpdates()
{
MOZ_RELEASE_ASSERT(!mIsLinkUpdateRegistrationsForbidden);
if (!mHasLinksToUpdate)
if (mFlushingPendingLinkUpdates) {
return;
}
AutoRestore<bool> saved(mIsLinkUpdateRegistrationsForbidden);
mIsLinkUpdateRegistrationsForbidden = true;
for (auto iter = mLinksToUpdate.Iter(); !iter.Done(); iter.Next()) {
Link* link = iter.Get();
Element* element = link->GetElement();
if (element->OwnerDoc() == this) {
link->ClearHasPendingLinkUpdate();
if (element->IsInComposedDoc()) {
element->UpdateLinkState(link->LinkState());
auto restore = MakeScopeExit([&] { mFlushingPendingLinkUpdates = false; });
mFlushingPendingLinkUpdates = true;
while (!mLinksToUpdate.IsEmpty()) {
LinksToUpdateList links(Move(mLinksToUpdate));
for (auto iter = links.Iter(); !iter.Done(); iter.Next()) {
Link* link = iter.Get();
Element* element = link->GetElement();
if (element->OwnerDoc() == this) {
link->ClearHasPendingLinkUpdate();
if (element->IsInComposedDoc()) {
element->UpdateLinkState(link->LinkState());
}
}
}
}
mLinksToUpdate.Clear();
mHasLinksToUpdate = false;
}
already_AddRefed<nsIDocument>

Просмотреть файл

@ -3344,10 +3344,13 @@ protected:
// The array of all links that need their status resolved. Links must add themselves
// to this set by calling RegisterPendingLinkUpdate when added to a document.
static const size_t kSegmentSize = 128;
mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>,
kSegmentSize,
InfallibleAllocPolicy>
mLinksToUpdate;
typedef mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>,
kSegmentSize,
InfallibleAllocPolicy>
LinksToUpdateList;
LinksToUpdateList mLinksToUpdate;
// SMIL Animation Controller, lazily-initialized in GetAnimationController
RefPtr<nsSMILAnimationController> mAnimationController;
@ -3441,12 +3444,12 @@ protected:
// file, etc.
bool mIsSyntheticDocument : 1;
// True if this document has links whose state needs updating
bool mHasLinksToUpdate : 1;
// True is there is a pending runnable which will call FlushPendingLinkUpdates().
bool mHasLinksToUpdateRunnable : 1;
// True if we're flushing pending link updates.
bool mFlushingPendingLinkUpdates : 1;
// True if a DOMMutationObserver is perhaps attached to a node in the document.
bool mMayHaveDOMMutationObservers : 1;
@ -3595,12 +3598,6 @@ protected:
Tri mAllowXULXBL;
/**
* This is true while FlushPendingLinkUpdates executes. Calls to
* [Un]RegisterPendingLinkUpdate will assert when this is true.
*/
bool mIsLinkUpdateRegistrationsForbidden;
// The document's script global object, the object from which the
// document can get its script context and scope. This is the
// *inner* window object.