Bug 1443553: Devirtualize nsIDocument::AddObserver / RemoveObserver. r?smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 06 Mar 2018 16:37:36 +0100
changeset 763999 d7379bb22221177ca1511b8e99a9c40eb6945c1b
parent 763998 8749e6b5eb0a4e7c961242591a853ee325d7dbe5
child 764000 96b3c41bccdef5389396dac6da2c88b4ee33f9fe
push id101639
push userbmo:emilio@crisal.io
push dateWed, 07 Mar 2018 02:26:30 +0000
reviewerssmaug
bugs1443553
milestone60.0a1
Bug 1443553: Devirtualize nsIDocument::AddObserver / RemoveObserver. r?smaug MozReview-Commit-ID: 8JeFLusnIQd
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
--- 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;