Bug 1444580: Devirtualize autofocus and navigation timing stuff. r=smaug draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 10 Mar 2018 05:24:24 +0100
changeset 765756 8736ff572380ad718541727c860b139ca41d6e6f
parent 765755 ebf3e5a5ee992816e3726813a2b54a749dab22f6
child 765757 ba06f7997c35c6b853aaa89fe6fdc4bc23423613
push id102160
push userbmo:emilio@crisal.io
push dateSat, 10 Mar 2018 06:32:21 +0000
reviewerssmaug
bugs1444580
milestone60.0a1
Bug 1444580: Devirtualize autofocus and navigation timing stuff. r=smaug MozReview-Commit-ID: K5Y9lxSJgOG
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1485,16 +1485,20 @@ nsIDocument::nsIDocument()
     mAllowUnsafeHTML(false),
     mInDestructor(false),
     mIsGoingAway(false),
     mInXBLUpdate(false),
     mNeedsReleaseAfterStackRefCntRelease(false),
     mStyleSetFilled(false),
     mSSApplicableStateNotificationPending(false),
     mMayHaveTitleElement(false),
+    mDOMLoadingSet(false),
+    mDOMInteractiveSet(false),
+    mDOMCompleteSet(false),
+    mAutoFocusFired(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),
@@ -1563,20 +1567,16 @@ nsDocument::nsDocument(const char* aCont
   , mValidScaleFloat(false)
   , mValidMaxScale(false)
   , mScaleStrEmpty(false)
   , mWidthStrEmpty(false)
   , mMaybeServiceWorkerControlled(false)
 #ifdef DEBUG
   , mWillReparent(false)
 #endif
-  , mDOMLoadingSet(false)
-  , mDOMInteractiveSet(false)
-  , mDOMCompleteSet(false)
-  , mAutoFocusFired(false)
 {
   SetContentTypeInternal(nsDependentCString(aContentType));
 
   MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this));
 
   // Start out mLastStyleSheetSet as null, per spec
   SetDOMStringToNull(mLastStyleSheetSet);
 
@@ -8886,17 +8886,17 @@ nsDocument::CloneDocHelper(nsDocument* c
   // Preallocate attributes and child arrays
   rv = clone->mChildren.EnsureCapacityToClone(mChildren, aPreallocateChildren);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 void
-nsDocument::SetReadyStateInternal(ReadyState rs)
+nsIDocument::SetReadyStateInternal(ReadyState rs)
 {
   mReadyState = rs;
   if (rs == READYSTATE_UNINITIALIZED) {
     // Transition back to uninitialized happens only to keep assertions happy
     // right before readyState transitions to something else. Make this
     // transition undetectable by Web content.
     return;
   }
@@ -9408,17 +9408,17 @@ public:
     return rv.StealNSResult();
   }
 private:
   nsCOMPtr<Element> mElement;
   nsCOMPtr<nsPIDOMWindowOuter> mTopWindow;
 };
 
 void
-nsDocument::SetAutoFocusElement(Element* aAutoFocusElement)
+nsIDocument::SetAutoFocusElement(Element* aAutoFocusElement)
 {
   if (mAutoFocusFired) {
     // Too late.
     return;
   }
 
   if (mAutoFocusElement) {
     // The spec disallows multiple autofocus elements, so we consider only the
@@ -9426,17 +9426,17 @@ nsDocument::SetAutoFocusElement(Element*
     return;
   }
 
   mAutoFocusElement = do_GetWeakReference(aAutoFocusElement);
   TriggerAutoFocus();
 }
 
 void
-nsDocument::TriggerAutoFocus()
+nsIDocument::TriggerAutoFocus()
 {
   if (mAutoFocusFired) {
     return;
   }
 
   if (!mPresShell || !mPresShell->DidInitialize()) {
     // Delay autofocus until frames are constructed so that we don't thrash
     // style and layout calculations.
@@ -9794,30 +9794,23 @@ nsDocument::GetStateObject(nsIVariant** 
       DeserializeToVariant(cx, getter_AddRefs(mStateObjectCached));
   }
 
   NS_IF_ADDREF(*aState = mStateObjectCached);
 
   return NS_OK;
 }
 
-nsDOMNavigationTiming*
-nsDocument::GetNavigationTiming() const
-{
-  return mTiming;
-}
-
-nsresult
-nsDocument::SetNavigationTiming(nsDOMNavigationTiming* aTiming)
+void
+nsIDocument::SetNavigationTiming(nsDOMNavigationTiming* aTiming)
 {
   mTiming = aTiming;
   if (!mLoadingTimeStamp.IsNull() && mTiming) {
-    mTiming->SetDOMLoadingTimeStamp(nsIDocument::GetDocumentURI(), mLoadingTimeStamp);
-  }
-  return NS_OK;
+    mTiming->SetDOMLoadingTimeStamp(GetDocumentURI(), mLoadingTimeStamp);
+  }
 }
 
 Element*
 nsDocument::FindImageMap(const nsAString& aUseMapValue)
 {
   if (aUseMapValue.IsEmpty()) {
     return nullptr;
   }
@@ -13403,17 +13396,17 @@ nsIDocument::GetSelection(ErrorResult& a
   if (!window->IsCurrentInnerWindow()) {
     return nullptr;
   }
 
   return nsGlobalWindowInner::Cast(window)->GetSelection(aRv);
 }
 
 void
-nsDocument::RecordNavigationTiming(ReadyState aReadyState)
+nsIDocument::RecordNavigationTiming(ReadyState aReadyState)
 {
   if (!XRE_IsContentProcess()) {
     return;
   }
   if (!IsTopLevelContentDocument()) {
     return;
   }
   // If we dont have the timing yet (mostly because the doc is still loading),
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -401,18 +401,16 @@ public:
   virtual void RemoveFromIdTable(Element* aElement, nsAtom* aId) override;
   virtual void AddToNameTable(Element* aElement, nsAtom* aName) override;
   virtual void RemoveFromNameTable(Element* aElement, nsAtom* aName) override;
 
   virtual void EndUpdate(nsUpdateType aUpdateType) override;
   virtual void BeginLoad() override;
   virtual void EndLoad() override;
 
-  virtual void SetReadyStateInternal(ReadyState rs) override;
-
   virtual void FlushExternalResources(mozilla::FlushType aType) override;
   virtual void SetXMLDeclaration(const char16_t *aVersion,
                                  const char16_t *aEncoding,
                                  const int32_t aStandalone) override;
   virtual void GetXMLDeclaration(nsAString& aVersion,
                                  nsAString& aEncoding,
                                  nsAString& Standalone) override;
   virtual bool IsScriptEnabled() override;
@@ -654,19 +652,16 @@ public:
   virtual void MaybePreconnect(nsIURI* uri,
                                mozilla::CORSMode aCORSMode) override;
 
   virtual nsISupports* GetCurrentContentSink() override;
 
   // Only BlockOnload should call this!
   void AsyncBlockOnload();
 
-  virtual void SetAutoFocusElement(Element* aAutoFocusElement) override;
-  virtual void TriggerAutoFocus() override;
-
   virtual void SetScrollToRef(nsIURI *aDocumentURI) override;
   virtual void ScrollToRef() override;
   virtual void ResetScrolledToRefAlready() override;
   virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) override;
 
   // AddPlugin adds a plugin-related element to mPlugins when the element is
   // added to the tree.
   virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) override;
@@ -684,19 +679,16 @@ public:
   // removed from the tree.
   virtual void RemoveResponsiveContent(nsIContent* aContent) override;
   // Notifies any responsive content added by AddResponsiveContent upon media
   // features values changing.
   virtual void NotifyMediaFeatureValuesChanged() override;
 
   virtual nsresult GetStateObject(nsIVariant** aResult) override;
 
-  virtual nsDOMNavigationTiming* GetNavigationTiming() const override;
-  virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) override;
-
   virtual Element* FindImageMap(const nsAString& aNormalizedMapName) override;
 
   virtual nsTArray<Element*> GetFullscreenStack() const override;
   virtual void AsyncRequestFullScreen(
     mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
   virtual void RestorePreviousFullScreenState() override;
   virtual bool IsFullscreenLeaf() override;
   virtual nsresult
@@ -892,19 +884,16 @@ protected:
   nsWeakPtr mFullscreenRoot;
 
 public:
   RefPtr<mozilla::EventListenerManager> mListenerManager;
   RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
 
   nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
 
-  // Recorded time of change to 'loading' state.
-  mozilla::TimeStamp mLoadingTimeStamp;
-
   bool mHasWarnedAboutBoxObjects:1;
 
   bool mDelayFrameLoaderInitialization:1;
 
   bool mSynchronousDOMContentLoaded:1;
 
   // Parser aborted. True if the parser of this document was forcibly
   // terminated instead of letting it finish at its own pace.
@@ -937,18 +926,16 @@ public:
   // HTMLTemplateElement.
   nsCOMPtr<nsIDocument> mTemplateContentsOwner;
 
   // The application cache that this document is associated with, if
   // any.  This can change during the lifetime of the document.
   nsCOMPtr<nsIApplicationCache> mApplicationCache;
 
   nsCOMPtr<nsIContent> mFirstBaseNodeWithHref;
-
-  RefPtr<nsDOMNavigationTiming> mTiming;
 private:
   friend class nsUnblockOnloadEvent;
   // Recomputes the visibility state but doesn't set the new value.
   mozilla::dom::VisibilityState GetVisibilityState() const;
 
   void PostUnblockOnloadEvent();
   void DoUnblockOnload();
 
@@ -1002,18 +989,16 @@ private:
 
   // Set if we've found a URL for the current picture
   nsString mPreloadPictureFoundSource;
 
   RefPtr<mozilla::dom::DOMImplementation> mDOMImplementation;
 
   RefPtr<nsContentList> mImageMaps;
 
-  nsWeakPtr mAutoFocusElement;
-
   nsCString mScrollToRef;
   uint8_t mScrolledToRefAlready : 1;
   uint8_t mChangeScrollPosWhenScrollingToRef : 1;
 
   // Tracking for plugins in the document.
   nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
 
   RefPtr<mozilla::dom::DocumentTimeline> mDocumentTimeline;
@@ -1032,23 +1017,16 @@ private:
   // Set to true when the document is possibly controlled by the ServiceWorker.
   // Used to prevent multiple requests to ServiceWorkerManager.
   bool mMaybeServiceWorkerControlled;
 
 #ifdef DEBUG
 public:
   bool mWillReparent;
 #endif
-
-private:
-  void RecordNavigationTiming(ReadyState aReadyState);
-  bool mDOMLoadingSet : 1;
-  bool mDOMInteractiveSet : 1;
-  bool mDOMCompleteSet : 1;
-  bool mAutoFocusFired : 1;
 };
 
 class nsDocumentOnStack
 {
 public:
   explicit nsDocumentOnStack(nsIDocument* aDoc) : mDoc(aDoc)
   {
     mDoc->IncreaseStackRefCnt();
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1749,17 +1749,17 @@ public:
   // To make this easy and painless, use the mozAutoDocUpdate helper class.
   void BeginUpdate(nsUpdateType aUpdateType);
   virtual void EndUpdate(nsUpdateType aUpdateType) = 0;
 
   virtual void BeginLoad() = 0;
   virtual void EndLoad() = 0;
 
   enum ReadyState { READYSTATE_UNINITIALIZED = 0, READYSTATE_LOADING = 1, READYSTATE_INTERACTIVE = 3, READYSTATE_COMPLETE = 4};
-  virtual void SetReadyStateInternal(ReadyState rs) = 0;
+  void SetReadyStateInternal(ReadyState rs);
   ReadyState GetReadyStateEnum()
   {
     return mReadyState;
   }
 
   // notify that a content node changed state.  This must happen under
   // a scriptblocker but NOT within a begin/end update.
   void ContentStateChanged(
@@ -2702,18 +2702,18 @@ public:
    */
   mozilla::EventStates GetDocumentState() const
   {
     return mDocumentState;
   }
 
   virtual nsISupports* GetCurrentContentSink() = 0;
 
-  virtual void SetAutoFocusElement(Element* aAutoFocusElement) = 0;
-  virtual void TriggerAutoFocus() = 0;
+  void SetAutoFocusElement(Element* aAutoFocusElement);
+  void TriggerAutoFocus();
 
   virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0;
   virtual void ScrollToRef() = 0;
   virtual void ResetScrolledToRefAlready() = 0;
   virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0;
 
   using mozilla::dom::DocumentOrShadowRoot::GetElementById;
   using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
@@ -2765,19 +2765,22 @@ public:
   virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) = 0;
 
   virtual nsresult AddResponsiveContent(nsIContent* aContent) = 0;
   virtual void RemoveResponsiveContent(nsIContent* aContent) = 0;
   virtual void NotifyMediaFeatureValuesChanged() = 0;
 
   virtual nsresult GetStateObject(nsIVariant** aResult) = 0;
 
-  virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0;
-
-  virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) = 0;
+  nsDOMNavigationTiming* GetNavigationTiming() const
+  {
+    return mTiming;
+  }
+
+  void SetNavigationTiming(nsDOMNavigationTiming* aTiming);
 
   virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0;
 
   // Add aLink to the set of links that need their status resolved.
   void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink);
 
   // Update state on links in mLinksToUpdate.  This function must be called
   // prior to selector matching that needs to differentiate between :link and
@@ -3304,16 +3307,18 @@ protected:
   // Retrieves the classification of the Flash plugins in the document based on
   // the classification lists.
   mozilla::dom::FlashClassification PrincipalFlashClassification();
 
   // Attempts to determine the Flash classification of this page based on the
   // the classification lists and the classification of parent documents.
   mozilla::dom::FlashClassification ComputeFlashClassification();
 
+  void RecordNavigationTiming(ReadyState aReadyState);
+
   bool GetUseCounter(mozilla::UseCounter aUseCounter)
   {
     return mUseCounters[aUseCounter];
   }
 
   void SetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
   {
     if (!mChildDocumentUseCounters[aUseCounter]) {
@@ -3732,16 +3737,21 @@ protected:
   // Keeps track of whether we have a pending
   // 'style-sheet-applicable-state-changed' notification.
   bool mSSApplicableStateNotificationPending: 1;
 
   // True if this document has ever had an HTML or SVG <title> element
   // bound to it
   bool mMayHaveTitleElement: 1;
 
+  bool mDOMLoadingSet: 1;
+  bool mDOMInteractiveSet: 1;
+  bool mDOMCompleteSet: 1;
+  bool mAutoFocusFired: 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
@@ -3955,16 +3965,23 @@ protected:
   mozilla::dom::FlashClassification mFlashClassification;
   // Do not use this value directly. Call the |IsThirdParty()| method, which
   // caches its result here.
   mozilla::Maybe<bool> mIsThirdParty;
 
   nsRevocableEventPtr<nsRunnableMethod<nsIDocument, void, false>>
     mPendingTitleChangeEvent;
 
+  RefPtr<nsDOMNavigationTiming> mTiming;
+
+  // Recorded time of change to 'loading' state.
+  mozilla::TimeStamp mLoadingTimeStamp;
+
+  nsWeakPtr mAutoFocusElement;
+
   nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
   nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
 
   // Member to store out last-selected stylesheet set.
   nsString mLastStyleSheetSet;
   RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
 
   // We lazily calculate declaration blocks for SVG elements with mapped