Bug 1444580: Devirtualize autofocus and navigation timing stuff. r=smaug
MozReview-Commit-ID: K5Y9lxSJgOG
--- 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