Bug 1443553: Devirtualize nsIDocument::AddObserver / RemoveObserver. r?smaug
MozReview-Commit-ID: 8JeFLusnIQd
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1475,16 +1475,17 @@ nsIDocument::nsIDocument()
mIsContentDocument(false),
mDidCallBeginLoad(false),
mBufferingCSPViolations(false),
mAllowPaymentRequest(false),
mEncodingMenuDisabled(false),
mIsShadowDOMEnabled(false),
mIsSVGGlyphsDocument(false),
mAllowUnsafeHTML(false),
+ mInDestructor(false),
mIsScopedStyleEnabled(eScopedStyle_Unknown),
mCompatMode(eCompatibility_FullStandards),
mReadyState(ReadyState::READYSTATE_UNINITIALIZED),
mStyleBackendType(StyleBackendType::None),
#ifdef MOZILLA_INTERNAL_API
mVisibilityState(dom::VisibilityState::Hidden),
#else
mDummy(0),
@@ -1523,17 +1524,16 @@ nsIDocument::nsIDocument()
}
nsDocument::nsDocument(const char* aContentType)
: nsIDocument()
, mSubDocuments(nullptr)
, mFlashClassification(FlashClassification::Unclassified)
, mHeaderData(nullptr)
, mIsGoingAway(false)
- , mInDestructor(false)
, mMayHaveTitleElement(false)
, mHasWarnedAboutBoxObjects(false)
, mDelayFrameLoaderInitialization(false)
, mSynchronousDOMContentLoaded(false)
, mInXBLUpdate(false)
, mParserAborted(false)
, mCurrentOrientationAngle(0)
, mCurrentOrientationType(OrientationType::Portrait_primary)
@@ -5124,26 +5124,26 @@ nsDocument::InternalAllowXULXBL()
mAllowXULXBL = eTriFalse;
return false;
}
// Note: We don't hold a reference to the document observer; we assume
// that it has a live reference to the document.
void
-nsDocument::AddObserver(nsIDocumentObserver* aObserver)
+nsIDocument::AddObserver(nsIDocumentObserver* aObserver)
{
NS_ASSERTION(mObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex,
"Observer already in the list");
mObservers.AppendElement(aObserver);
AddMutationObserver(aObserver);
}
bool
-nsDocument::RemoveObserver(nsIDocumentObserver* aObserver)
+nsIDocument::RemoveObserver(nsIDocumentObserver* aObserver)
{
// If we're in the process of destroying the document (and we're
// informing the observers of the destruction), don't remove the
// observers from the list. This is not a big deal, since we
// don't hold a live reference to the observers.
if (!mInDestructor) {
RemoveMutationObserver(aObserver);
return mObservers.RemoveElement(aObserver);
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -485,29 +485,16 @@ public:
/**
* Add/Remove an element to the document's id and name hashes
*/
virtual void AddToIdTable(Element* aElement, nsAtom* aId) override;
virtual void RemoveFromIdTable(Element* aElement, nsAtom* aId) override;
virtual void AddToNameTable(Element* aElement, nsAtom* aName) override;
virtual void RemoveFromNameTable(Element* aElement, nsAtom* aName) override;
- /**
- * Add a new observer of document change notifications. Whenever
- * content is changed, appended, inserted or removed the observers are
- * informed.
- */
- virtual void AddObserver(nsIDocumentObserver* aObserver) override;
-
- /**
- * Remove an observer of document change notifications. This will
- * return false if the observer cannot be found.
- */
- virtual bool RemoveObserver(nsIDocumentObserver* aObserver) override;
-
// Observation hooks used to propagate notifications to document
// observers.
virtual void BeginUpdate(nsUpdateType aUpdateType) override;
virtual void EndUpdate(nsUpdateType aUpdateType) override;
virtual void BeginLoad() override;
virtual void EndLoad() override;
virtual void SetReadyStateInternal(ReadyState rs) override;
@@ -1091,19 +1078,16 @@ protected:
// Weak reference to our sink for in case we no longer have a parser. This
// will allow us to flush out any pending stuff from the sink even if
// EndLoad() has already happened.
nsWeakPtr mWeakSink;
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
- // Array of observers
- nsTObserverArray<nsIDocumentObserver*> mObservers;
-
// Array of intersection observers
nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
mIntersectionObservers;
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
RefPtr<mozilla::PendingAnimationTracker> mPendingAnimationTracker;
@@ -1135,18 +1119,16 @@ public:
nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
// Recorded time of change to 'loading' state.
mozilla::TimeStamp mLoadingTimeStamp;
// True if the document has been detached from its content viewer.
bool mIsGoingAway:1;
- // True if the document is being destroyed.
- bool mInDestructor:1;
// True if this document has ever had an HTML or SVG <title> element
// bound to it
bool mMayHaveTitleElement:1;
bool mHasWarnedAboutBoxObjects:1;
bool mDelayFrameLoaderInitialization:1;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1663,23 +1663,23 @@ public:
// Document notification API's
/**
* Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are
* informed. An observer that is already observing the document must
* not be added without being removed first.
*/
- virtual void AddObserver(nsIDocumentObserver* aObserver) = 0;
+ void AddObserver(nsIDocumentObserver* aObserver);
/**
* Remove an observer of document change notifications. This will
* return false if the observer cannot be found.
*/
- virtual bool RemoveObserver(nsIDocumentObserver* aObserver) = 0;
+ bool RemoveObserver(nsIDocumentObserver* aObserver);
// Observation hooks used to propagate notifications to document observers.
// BeginUpdate must be called before any batch of modifications of the
// content model or of style data, EndUpdate must be called afterward.
// To make this easy and painless, use the mozAutoDocUpdate helper class.
virtual void BeginUpdate(nsUpdateType aUpdateType) = 0;
virtual void EndUpdate(nsUpdateType aUpdateType) = 0;
virtual void BeginLoad() = 0;
@@ -3554,16 +3554,19 @@ protected:
// True if this document is for an SVG-in-OpenType font.
bool mIsSVGGlyphsDocument : 1;
// True if unsafe HTML fragments should be allowed in chrome-privileged
// documents.
bool mAllowUnsafeHTML : 1;
+ // True if the document is being destroyed.
+ bool mInDestructor:1;
+
// Whether <style scoped> support is enabled in this document.
enum { eScopedStyle_Unknown, eScopedStyle_Disabled, eScopedStyle_Enabled };
unsigned int mIsScopedStyleEnabled : 2;
// Compatibility mode
nsCompatibility mCompatMode;
// Our readyState
@@ -3702,16 +3705,19 @@ protected:
nsTArray<RefPtr<mozilla::dom::AnonymousContent>> mAnonymousContents;
uint32_t mBlockDOMContentLoaded;
// Our live MediaQueryLists
mozilla::LinkedList<mozilla::dom::MediaQueryList> mDOMMediaQueryLists;
+ // Array of observers
+ nsTObserverArray<nsIDocumentObserver*> mObservers;
+
// Flags for use counters used directly by this document.
std::bitset<mozilla::eUseCounter_Count> mUseCounters;
// Flags for use counters used by any child documents of this document.
std::bitset<mozilla::eUseCounter_Count> mChildDocumentUseCounters;
// Flags for whether we've notified our top-level "page" of a use counter
// for this child document.
std::bitset<mozilla::eUseCounter_Count> mNotifiedPageForUseCounter;