Bug 1443756: Devirtualize style-related nsIDocument methods. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 07 Mar 2018 13:04:56 +0100
changeset 462081 558db50a864aa036fa2b043f8d2e609602ec4560
parent 462080 2abeedcce11452fa670fc04adccf9dfcea7c749e
child 462082 f6ea75e2b8e1282856b23fa76302f53a05292501
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1443756
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1443756: Devirtualize style-related nsIDocument methods. r=smaug Summary: They have no particular reason to be virtual. Reviewers: smaug Bug #: 1443756 Differential Revision: https://phabricator.services.mozilla.com/D691 MozReview-Commit-ID: JN8MtfXvw3D
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1479,16 +1479,18 @@ nsIDocument::nsIDocument()
     mEncodingMenuDisabled(false),
     mIsShadowDOMEnabled(false),
     mIsSVGGlyphsDocument(false),
     mAllowUnsafeHTML(false),
     mInDestructor(false),
     mIsGoingAway(false),
     mInXBLUpdate(false),
     mNeedsReleaseAfterStackRefCntRelease(false),
+    mStyleSetFilled(false),
+    mSSApplicableStateNotificationPending(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),
@@ -1535,19 +1537,17 @@ nsDocument::nsDocument(const char* aCont
   , mHeaderData(nullptr)
   , mMayHaveTitleElement(false)
   , mHasWarnedAboutBoxObjects(false)
   , mDelayFrameLoaderInitialization(false)
   , mSynchronousDOMContentLoaded(false)
   , mParserAborted(false)
   , mCurrentOrientationAngle(0)
   , mCurrentOrientationType(OrientationType::Portrait_primary)
-  , mSSApplicableStateNotificationPending(false)
   , mReportedUseCounters(false)
-  , mStyleSetFilled(false)
   , mPendingFullscreenRequests(0)
   , mXMLDeclarationBits(0)
   , mBoxObjectTable(nullptr)
   , mOnloadBlockCount(0)
   , mAsyncOnloadBlockCount(0)
 #ifdef DEBUG
   , mStyledLinksCleared(false)
 #endif
@@ -2477,34 +2477,34 @@ nsDocument::MaybeDowngradePrincipal(nsIP
       }
     }
   }
   nsCOMPtr<nsIPrincipal> principal(aPrincipal);
   return principal.forget();
 }
 
 void
-nsDocument::RemoveDocStyleSheetsFromStyleSets()
+nsIDocument::RemoveDocStyleSheetsFromStyleSets()
 {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(mStyleSheets)) {
     sheet->ClearAssociatedDocument();
 
     if (sheet->IsApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         shell->StyleSet()->RemoveDocStyleSheet(sheet);
       }
     }
     // XXX Tell observers?
   }
 }
 
 void
-nsDocument::RemoveStyleSheetsFromStyleSets(
+nsIDocument::RemoveStyleSheetsFromStyleSets(
     const nsTArray<RefPtr<StyleSheet>>& aSheets,
     SheetType aType)
 {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(aSheets)) {
     sheet->ClearAssociatedDocument();
 
     if (sheet->IsApplicable()) {
@@ -2513,17 +2513,17 @@ nsDocument::RemoveStyleSheetsFromStyleSe
         shell->StyleSet()->RemoveStyleSheet(aType, sheet);
       }
     }
     // XXX Tell observers?
   }
 }
 
 void
-nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
+nsIDocument::ResetStylesheetsToURI(nsIURI* aURI)
 {
   MOZ_ASSERT(aURI);
 
   mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
   if (mStyleSetFilled) {
     // Skip removing style sheets from the style set if we know we haven't
     // filled the style set.  (This allows us to avoid calling
     // GetStyleBackendType() too early.)
@@ -2578,17 +2578,17 @@ AppendSheetsToStyleSet(StyleSetHandle aS
 {
   for (StyleSheet* sheet : Reversed(aSheets)) {
     aStyleSet->AppendStyleSheet(aType, sheet);
   }
 }
 
 
 void
-nsDocument::FillStyleSet(StyleSetHandle aStyleSet)
+nsIDocument::FillStyleSet(StyleSetHandle aStyleSet)
 {
   NS_PRECONDITION(aStyleSet, "Must have a style set");
   NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0,
                   "Style set already has document sheets?");
 
   MOZ_ASSERT(!mStyleSetFilled);
 
   for (StyleSheet* sheet : Reversed(mStyleSheets)) {
@@ -4344,28 +4344,28 @@ nsDocument::RemoveChildNode(nsIContent* 
   mCachedRootElement = nullptr;
   doRemoveChildAt(ComputeIndexOf(aKid), aNotify, aKid, mChildren);
   MOZ_ASSERT(mCachedRootElement != aKid,
              "Stale pointer in mCachedRootElement, after we tried to clear it "
              "(maybe somebody called GetRootElement() too early?)");
 }
 
 void
-nsDocument::EnsureOnDemandBuiltInUASheet(StyleSheet* aSheet)
+nsIDocument::EnsureOnDemandBuiltInUASheet(StyleSheet* aSheet)
 {
   if (mOnDemandBuiltInUASheets.Contains(aSheet)) {
     return;
   }
   BeginUpdate(UPDATE_STYLE);
   AddOnDemandBuiltInUASheet(aSheet);
   EndUpdate(UPDATE_STYLE);
 }
 
 void
-nsDocument::AddOnDemandBuiltInUASheet(StyleSheet* aSheet)
+nsIDocument::AddOnDemandBuiltInUASheet(StyleSheet* aSheet)
 {
   MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(aSheet));
   MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
 
   // Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in
   // the same order that they should end up in the style set.
   mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet);
 
@@ -4380,17 +4380,17 @@ nsDocument::AddOnDemandBuiltInUASheet(St
       shell->StyleSet()->PrependStyleSheet(SheetType::Agent, aSheet);
     }
   }
 
   NotifyStyleSheetAdded(aSheet, false);
 }
 
 void
-nsDocument::AddStyleSheetToStyleSets(StyleSheet* aSheet)
+nsIDocument::AddStyleSheetToStyleSets(StyleSheet* aSheet)
 {
   MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     shell->StyleSet()->AddDocStyleSheet(aSheet, this);
   }
 }
 
@@ -4408,67 +4408,67 @@ nsDocument::AddStyleSheetToStyleSets(Sty
     event->SetTarget(this);                                                   \
     RefPtr<AsyncEventDispatcher> asyncDispatcher =                          \
       new AsyncEventDispatcher(this, event);                                  \
     asyncDispatcher->mOnlyChromeDispatch = true;                              \
     asyncDispatcher->PostDOMEvent();                                          \
   } while (0);
 
 void
-nsDocument::NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet)
+nsIDocument::NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (aSheet, aDocumentSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
                                "StyleSheetAdded",
                                mDocumentSheet,
                                aDocumentSheet);
   }
 }
 
 void
-nsDocument::NotifyStyleSheetRemoved(StyleSheet* aSheet, bool aDocumentSheet)
+nsIDocument::NotifyStyleSheetRemoved(StyleSheet* aSheet, bool aDocumentSheet)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (aSheet, aDocumentSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
                                "StyleSheetRemoved",
                                mDocumentSheet,
                                aDocumentSheet);
   }
 }
 
 void
-nsDocument::AddStyleSheet(StyleSheet* aSheet)
-{
-  NS_PRECONDITION(aSheet, "null arg");
+nsIDocument::AddStyleSheet(StyleSheet* aSheet)
+{
+  MOZ_ASSERT(aSheet);
   MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
   mStyleSheets.AppendElement(aSheet);
   aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
 
   if (aSheet->IsApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
 void
-nsDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
+nsIDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     shell->StyleSet()->RemoveDocStyleSheet(aSheet);
   }
 }
 
 void
-nsDocument::RemoveStyleSheet(StyleSheet* aSheet)
+nsIDocument::RemoveStyleSheet(StyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   RefPtr<StyleSheet> sheet = aSheet; // hold ref so it won't die too soon
 
   if (!mStyleSheets.RemoveElement(aSheet)) {
     NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
     return;
   }
@@ -4480,18 +4480,18 @@ nsDocument::RemoveStyleSheet(StyleSheet*
 
     NotifyStyleSheetRemoved(aSheet, true);
   }
 
   aSheet->ClearAssociatedDocument();
 }
 
 void
-nsDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
-                              nsTArray<RefPtr<StyleSheet>>& aNewSheets)
+nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
+                               nsTArray<RefPtr<StyleSheet>>& aNewSheets)
 {
   BeginUpdate(UPDATE_STYLE);
 
   // XXX Need to set the sheet on the ownernode, if any
   NS_PRECONDITION(aOldSheets.Length() == aNewSheets.Length(),
                   "The lists must be the same length!");
   int32_t count = aOldSheets.Length();
 
@@ -4518,17 +4518,17 @@ nsDocument::UpdateStyleSheets(nsTArray<R
       NotifyStyleSheetAdded(newSheet, true);
     }
   }
 
   EndUpdate(UPDATE_STYLE);
 }
 
 void
-nsDocument::InsertStyleSheetAt(StyleSheet* aSheet, size_t aIndex)
+nsIDocument::InsertStyleSheetAt(StyleSheet* aSheet, size_t aIndex)
 {
   MOZ_ASSERT(aSheet);
   MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
 
   // FIXME(emilio): Stop touching DocumentOrShadowRoot's members directly, and use an
   // accessor.
   mStyleSheets.InsertElementAt(aIndex, aSheet);
 
@@ -4538,18 +4538,17 @@ nsDocument::InsertStyleSheetAt(StyleShee
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
 
 void
-nsDocument::SetStyleSheetApplicableState(StyleSheet* aSheet,
-                                         bool aApplicable)
+nsIDocument::SetStyleSheetApplicableState(StyleSheet* aSheet, bool aApplicable)
 {
   NS_PRECONDITION(aSheet, "null arg");
 
   // If we're actually in the document style sheet list
   //
   // FIXME(emilio): Shadow DOM.
   MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
   if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) {
@@ -4571,33 +4570,33 @@ nsDocument::SetStyleSheetApplicableState
                                "StyleSheetApplicableStateChanged",
                                mApplicable,
                                aApplicable);
   }
 
   if (!mSSApplicableStateNotificationPending) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsIRunnable> notification =
-      NewRunnableMethod("nsDocument::NotifyStyleSheetApplicableStateChanged",
+      NewRunnableMethod("nsIDocument::NotifyStyleSheetApplicableStateChanged",
                         this,
-                        &nsDocument::NotifyStyleSheetApplicableStateChanged);
+                        &nsIDocument::NotifyStyleSheetApplicableStateChanged);
     mSSApplicableStateNotificationPending =
       NS_SUCCEEDED(
         Dispatch(TaskCategory::Other, notification.forget()));
   }
 }
 
 void
-nsDocument::NotifyStyleSheetApplicableStateChanged()
+nsIDocument::NotifyStyleSheetApplicableStateChanged()
 {
   mSSApplicableStateNotificationPending = false;
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (observerService) {
-    observerService->NotifyObservers(static_cast<nsIDocument*>(this),
+    observerService->NotifyObservers(this,
                                      "style-sheet-applicable-state-changed",
                                      nullptr);
   }
 }
 
 static SheetType
 ConvertAdditionalSheetType(nsIDocument::additionalSheetType aType)
 {
@@ -4625,18 +4624,18 @@ FindSheet(const nsTArray<RefPtr<StyleShe
     if (uri && NS_SUCCEEDED(uri->Equals(aSheetURI, &bEqual)) && bEqual)
       return i;
   }
 
   return -1;
 }
 
 nsresult
-nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
-                                     nsIURI* aSheetURI)
+nsIDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
+                                      nsIURI* aSheetURI)
 {
   NS_PRECONDITION(aSheetURI, "null arg");
 
   // Checking if we have loaded this one already.
   if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0)
     return NS_ERROR_INVALID_ARG;
 
   // Loading the sheet sync.
@@ -4667,17 +4666,17 @@ nsDocument::LoadAdditionalStyleSheet(add
 
   sheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
   MOZ_ASSERT(sheet->IsApplicable());
 
   return AddAdditionalStyleSheet(aType, sheet);
 }
 
 nsresult
-nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheet* aSheet)
+nsIDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheet* aSheet)
 {
   if (mAdditionalSheets[aType].Contains(aSheet))
     return NS_ERROR_INVALID_ARG;
 
   if (!aSheet->IsApplicable())
     return NS_ERROR_INVALID_ARG;
 
   mAdditionalSheets[aType].AppendElement(aSheet);
@@ -4692,17 +4691,17 @@ nsDocument::AddAdditionalStyleSheet(addi
   // Passing false, so documet.styleSheets.length will not be affected by
   // these additional sheets.
   NotifyStyleSheetAdded(aSheet, false);
   EndUpdate(UPDATE_STYLE);
   return NS_OK;
 }
 
 void
-nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
+nsIDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
 {
   MOZ_ASSERT(aSheetURI);
 
   nsTArray<RefPtr<StyleSheet>>& sheets = mAdditionalSheets[aType];
 
   int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
   if (i >= 0) {
     RefPtr<StyleSheet> sheetRef = sheets[i];
@@ -4722,22 +4721,16 @@ nsDocument::RemoveAdditionalStyleSheet(a
     // these additional sheets.
     NotifyStyleSheetRemoved(sheetRef, false);
     EndUpdate(UPDATE_STYLE);
 
     sheetRef->ClearAssociatedDocument();
   }
 }
 
-StyleSheet*
-nsDocument::GetFirstAdditionalAuthorSheet()
-{
-  return mAdditionalSheets[eAuthorSheet].SafeElementAt(0);
-}
-
 nsIGlobalObject*
 nsDocument::GetScopeObject() const
 {
   nsCOMPtr<nsIGlobalObject> scope(do_QueryReferent(mScopeObject));
   return scope;
 }
 
 void
@@ -5974,29 +5967,17 @@ nsIDocument::CreateAttributeNS(const nsA
 bool
 nsIDocument::AllowUnsafeHTML() const
 {
   return (!nsContentUtils::IsSystemPrincipal(NodePrincipal()) ||
           mAllowUnsafeHTML);
 }
 
 void
-nsDocument::ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG)
-{
-  mLazySVGPresElements.PutEntry(aSVG);
-}
-
-void
-nsDocument::UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG)
-{
-  mLazySVGPresElements.RemoveEntry(aSVG);
-}
-
-void
-nsDocument::ResolveScheduledSVGPresAttrs()
+nsIDocument::ResolveScheduledSVGPresAttrs()
 {
   for (auto iter = mLazySVGPresElements.Iter(); !iter.Done(); iter.Next()) {
     nsSVGElement* svg = iter.Get()->GetKey();
     svg->UpdateContentDeclarationBlock(StyleBackendType::Servo);
   }
   mLazySVGPresElements.Clear();
 }
 
@@ -6053,64 +6034,64 @@ nsIDocument::GetSelectedStyleSheetSet(ns
       // Sheets from multiple sets enabled; return null string, per spec.
       SetDOMStringToNull(aSheetSet);
       return;
     }
   }
 }
 
 void
-nsDocument::SetSelectedStyleSheetSet(const nsAString& aSheetSet)
+nsIDocument::SetSelectedStyleSheetSet(const nsAString& aSheetSet)
 {
   if (DOMStringIsNull(aSheetSet)) {
     return;
   }
 
   // Must update mLastStyleSheetSet before doing anything else with stylesheets
   // or CSSLoaders.
   mLastStyleSheetSet = aSheetSet;
   EnableStyleSheetsForSetInternal(aSheetSet, true);
 }
 
 void
-nsDocument::GetLastStyleSheetSet(nsAString& aSheetSet)
+nsIDocument::GetLastStyleSheetSet(nsAString& aSheetSet)
 {
   aSheetSet = mLastStyleSheetSet;
 }
 
 void
 nsIDocument::GetPreferredStyleSheetSet(nsAString& aSheetSet)
 {
   GetHeaderData(nsGkAtoms::headerDefaultStyle, aSheetSet);
 }
 
 DOMStringList*
-nsDocument::StyleSheetSets()
+nsIDocument::StyleSheetSets()
 {
   if (!mStyleSheetSetList) {
     mStyleSheetSetList = new nsDOMStyleSheetSetList(this);
   }
   return mStyleSheetSetList;
 }
 
 void
-nsDocument::EnableStyleSheetsForSet(const nsAString& aSheetSet)
+nsIDocument::EnableStyleSheetsForSet(const nsAString& aSheetSet)
 {
   // Per spec, passing in null is a no-op.
   if (!DOMStringIsNull(aSheetSet)) {
     // Note: must make sure to not change the CSSLoader's preferred sheet --
     // that value should be equal to either our lastStyleSheetSet (if that's
     // non-null) or to our preferredStyleSheetSet.  And this method doesn't
     // change either of those.
     EnableStyleSheetsForSetInternal(aSheetSet, false);
   }
 }
 
 void
-nsDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
+nsIDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
                                             bool aUpdateCSSLoader)
 {
   BeginUpdate(UPDATE_STYLE);
   size_t count = SheetCount();
   nsAutoString title;
   for (size_t index = 0; index < count; index++) {
     StyleSheet* sheet = SheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
@@ -9270,38 +9251,38 @@ public:
   }
   NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver)
 
 } // namespace
 
 void
-nsDocument::PreloadStyle(nsIURI* uri,
-                         const Encoding* aEncoding,
-                         const nsAString& aCrossOriginAttr,
-                         const ReferrerPolicy aReferrerPolicy,
-                         const nsAString& aIntegrity)
+nsIDocument::PreloadStyle(nsIURI* uri,
+                          const Encoding* aEncoding,
+                          const nsAString& aCrossOriginAttr,
+                          const enum ReferrerPolicy aReferrerPolicy,
+                          const nsAString& aIntegrity)
 {
   // The CSSLoader will retain this object after we return.
   nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
 
   // Charset names are always ASCII.
   CSSLoader()->LoadSheet(uri,
                          true,
                          NodePrincipal(),
                          aEncoding,
                          obs,
                          Element::StringToCORSMode(aCrossOriginAttr),
                          aReferrerPolicy,
                          aIntegrity);
 }
 
 nsresult
-nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
+nsIDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                 RefPtr<mozilla::StyleSheet>* aSheet)
 {
   css::SheetParsingMode mode =
     isAgentSheet ? css::eAgentSheetFeatures
                  : css::eAuthorSheetFeatures;
   return CSSLoader()->LoadSheetSync(uri, mode, isAgentSheet, aSheet);
 }
 
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -429,40 +429,16 @@ public:
   }
 
   virtual nsresult SetSubDocumentFor(Element* aContent,
                                      nsIDocument* aSubDoc) override;
   virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const override;
   virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const override;
   virtual Element* GetRootElementInternal() const override;
 
-  virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet) override;
-
-  virtual void AddStyleSheet(mozilla::StyleSheet* aSheet) override;
-  virtual void RemoveStyleSheet(mozilla::StyleSheet* aSheet) override;
-
-  virtual void UpdateStyleSheets(
-      nsTArray<RefPtr<mozilla::StyleSheet>>& aOldSheets,
-      nsTArray<RefPtr<mozilla::StyleSheet>>& aNewSheets) override;
-  virtual void AddStyleSheetToStyleSets(mozilla::StyleSheet* aSheet);
-  virtual void RemoveStyleSheetFromStyleSets(mozilla::StyleSheet* aSheet);
-
-  virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
-                                  size_t aIndex) override;
-  virtual void SetStyleSheetApplicableState(mozilla::StyleSheet* aSheet,
-                                            bool aApplicable) override;
-
-  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
-                                            nsIURI* aSheetURI) override;
-  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
-                                           mozilla::StyleSheet* aSheet) override;
-  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
-                                          nsIURI* sheetURI) override;
-  virtual mozilla::StyleSheet* GetFirstAdditionalAuthorSheet() override;
-
   virtual nsIChannel* GetChannel() const override {
     return mChannel;
   }
 
   virtual nsIChannel* GetFailedChannel() const override {
     return mFailedChannel;
   }
   virtual void SetFailedChannel(nsIChannel* aChannel) override {
@@ -579,27 +555,23 @@ public:
   virtual void NotifyIntersectionObservers() override;
   virtual bool HasIntersectionObservers() const override
   {
     return !mIntersectionObservers.IsEmpty();
   }
 
   virtual void NotifyLayerManagerRecreated() override;
 
-  virtual void ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
-  virtual void UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
-  virtual void ResolveScheduledSVGPresAttrs() override;
   bool IsSynthesized();
 
   // Check whether shadow DOM is enabled for the global of aObject.
   static bool IsShadowDOMEnabled(JSContext* aCx, JSObject* aObject);
   // Check whether shadow DOM is enabled for the document this node belongs to.
   static bool IsShadowDOMEnabled(const nsINode* aNode);
 private:
-  void AddOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet);
   void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
 
 public:
   // nsIDOMDocument
   NS_DECL_NSIDOMDOCUMENT
 
   using mozilla::dom::DocumentOrShadowRoot::GetElementById;
   using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
@@ -744,25 +716,16 @@ public:
                                  ReferrerPolicy aReferrerPolicy,
                                  bool aIsImgSet) override;
 
   virtual void ForgetImagePreload(nsIURI* aURI) override;
 
   virtual void MaybePreconnect(nsIURI* uri,
                                mozilla::CORSMode aCORSMode) override;
 
-  virtual void PreloadStyle(nsIURI* uri,
-                            const mozilla::Encoding* aEncoding,
-                            const nsAString& aCrossOriginAttr,
-                            ReferrerPolicy aReferrerPolicy,
-                            const nsAString& aIntegrity) override;
-
-  virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
-                                       RefPtr<mozilla::StyleSheet>* aSheet) override;
-
   virtual nsISupports* GetCurrentContentSink() override;
 
   // Only BlockOnload should call this!
   void AsyncBlockOnload();
 
   virtual void SetAutoFocusElement(Element* aAutoFocusElement) override;
   virtual void TriggerAutoFocus() override;
 
@@ -897,20 +860,16 @@ public:
   // DocAddSizeOfIncludingThis is inherited from nsIDocument.
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 
   // WebIDL bits
   virtual mozilla::dom::DOMImplementation*
     GetImplementation(mozilla::ErrorResult& rv) override;
 
-  virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) override;
-  virtual void GetLastStyleSheetSet(nsAString& aSheetSet) override;
-  virtual mozilla::dom::DOMStringList* StyleSheetSets() override;
-  virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) override;
   virtual already_AddRefed<Element> CreateElement(const nsAString& aTagName,
                                                   const mozilla::dom::ElementCreationOptionsOrString& aOptions,
                                                   ErrorResult& rv) override;
   virtual already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI,
                                                     const nsAString& aQualifiedName,
                                                     const mozilla::dom::ElementCreationOptionsOrString& aOptions,
                                                     mozilla::ErrorResult& rv) override;
 
@@ -971,22 +930,16 @@ public:
 
   js::ExpandoAndGeneration mExpandoAndGeneration;
 
   bool ContainsEMEContent();
 
   bool ContainsMSEContent();
 
 protected:
-  void RemoveDocStyleSheetsFromStyleSets();
-  void RemoveStyleSheetsFromStyleSets(
-      const nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets,
-      mozilla::SheetType aType);
-  void ResetStylesheetsToURI(nsIURI* aURI);
-  void FillStyleSet(mozilla::StyleSetHandle aStyleSet);
 
   void DispatchPageTransition(mozilla::dom::EventTarget* aDispatchTarget,
                               const nsAString& aType,
                               bool aPersisted);
 
   virtual nsPIDOMWindowOuter* GetWindowInternal() const override;
   virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const override;
   virtual bool InternalAllowXULXBL() override;
@@ -1010,18 +963,16 @@ protected:
   void VerifyRootContentState();
 #endif
 
   explicit nsDocument(const char* aContentType);
   virtual ~nsDocument();
 
   void EnsureOnloadBlocker();
 
-  void NotifyStyleSheetApplicableStateChanged();
-
   // Apply the fullscreen state to the document, and trigger related
   // events. It returns false if the fullscreen element ready check
   // fails and nothing gets changed.
   bool ApplyFullscreen(const FullscreenRequest& aRequest);
 
   // Retrieves the classification of the Flash plugins in the document based on
   // the classification lists.
   mozilla::dom::FlashClassification PrincipalFlashClassification();
@@ -1030,19 +981,16 @@ protected:
   // the classification lists and the classification of parent documents.
   mozilla::dom::FlashClassification ComputeFlashClassification();
 
   PLDHashTable *mSubDocuments;
 
   // Array of owning references to all children
   nsAttrAndChildArray mChildren;
 
-  nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
-  nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
-
   // 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;
 
@@ -1063,17 +1011,16 @@ protected:
   RefPtr<PrincipalFlashClassifier> mPrincipalFlashClassifier;
   mozilla::dom::FlashClassification mFlashClassification;
   // Do not use this value directly. Call the |IsThirdParty()| method, which
   // caches its result here.
   mozilla::Maybe<bool> mIsThirdParty;
 
 public:
   RefPtr<mozilla::EventListenerManager> mListenerManager;
-  RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
   RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
   nsDocHeaderData* mHeaderData;
 
   nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
 
   // Recorded time of change to 'loading' state.
   mozilla::TimeStamp mLoadingTimeStamp;
 
@@ -1095,32 +1042,24 @@ public:
 
   // ScreenOrientation "pending promise" as described by
   // http://www.w3.org/TR/screen-orientation/
   RefPtr<mozilla::dom::Promise> mOrientationPendingPromise;
 
   uint16_t mCurrentOrientationAngle;
   mozilla::dom::OrientationType mCurrentOrientationType;
 
-  // Keeps track of whether we have a pending
-  // 'style-sheet-applicable-state-changed' notification.
-  bool mSSApplicableStateNotificationPending:1;
-
   // Whether we have reported use counters for this document with Telemetry yet.
   // Normally this is only done at document destruction time, but for image
   // documents (SVG documents) that are not guaranteed to be destroyed, we
   // report use counters when the image cache no longer has any imgRequestProxys
   // pointing to them.  We track whether we ever reported use counters so
   // that we only report them once for the document.
   bool mReportedUseCounters:1;
 
-  // Whether we have filled our pres shell's style set with the document's
-  // additional sheets and sheets from the nsStyleSheetService.
-  bool mStyleSetFilled:1;
-
   uint8_t mPendingFullscreenRequests;
 
   uint8_t mXMLDeclarationBits;
 
   nsRefPtrHashtable<nsPtrHashKey<nsIContent>, mozilla::dom::BoxObject>* mBoxObjectTable;
 
   // A document "without a browsing context" that owns the content of
   // HTMLTemplateElement.
@@ -1132,30 +1071,22 @@ public:
 
   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 NotifyStyleSheetAdded(mozilla::StyleSheet* aSheet, bool aDocumentSheet);
-  void NotifyStyleSheetRemoved(mozilla::StyleSheet* aSheet, bool aDocumentSheet);
 
   void PostUnblockOnloadEvent();
   void DoUnblockOnload();
 
   nsresult InitCSP(nsIChannel* aChannel);
 
-  // Just like EnableStyleSheetsForSet, but doesn't check whether
-  // aSheetSet is null and allows the caller to control whether to set
-  // aSheetSet as the preferred set in the CSSLoader.
-  void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
-                                       bool aUpdateCSSLoader);
-
   void ClearAllBoxObjects();
 
   // Returns true if the scheme for the url for this document is "about"
   bool IsAboutPage() const;
 
   // These are not implemented and not supported.
   nsDocument(const nsDocument& aOther);
   nsDocument& operator=(const nsDocument& aOther);
@@ -1179,19 +1110,16 @@ private:
   // state so we can provide useful assertions to consumers of ForgetLink and
   // AddStyleRelevantLink.
   bool mStyledLinksCleared;
 #endif
 
   // A set of responsive images keyed by address pointer.
   nsTHashtable< nsPtrHashKey<nsIContent> > mResponsiveContent;
 
-  // Member to store out last-selected stylesheet set.
-  nsString mLastStyleSheetSet;
-
   nsTArray<RefPtr<nsFrameLoader> > mInitializableFrameLoaders;
   nsTArray<nsCOMPtr<nsIRunnable> > mFrameLoaderFinalizers;
   RefPtr<nsRunnableMethod<nsDocument> > mFrameLoaderRunner;
 
   nsCOMPtr<nsIRunnable> mMaybeEndOutermostXBLUpdateRunner;
 
   nsRevocableEventPtr<nsRunnableMethod<nsDocument, void, false> >
     mPendingTitleChangeEvent;
@@ -1248,21 +1176,16 @@ private:
   mozilla::CSSToLayoutDeviceScale mPixelRatio;
   bool mAutoSize, mAllowZoom, mAllowDoubleTapZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
   mozilla::CSSSize mViewportSize;
 
   // Set to true when the document is possibly controlled by the ServiceWorker.
   // Used to prevent multiple requests to ServiceWorkerManager.
   bool mMaybeServiceWorkerControlled;
 
-  // We lazily calculate declaration blocks for SVG elements
-  // with mapped attributes in Servo mode. This list contains all elements which
-  // need lazy resolution
-  nsTHashtable<nsPtrHashKey<nsSVGElement>> mLazySVGPresElements;
-
 #ifdef DEBUG
 public:
   bool mWillReparent;
 #endif
 
 private:
   void RecordNavigationTiming(ReadyState aReadyState);
   bool mDOMLoadingSet : 1;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -63,16 +63,17 @@ class ElementCreationOptionsOrString;
 
 class gfxUserFontSet;
 class imgIRequest;
 class nsBindingManager;
 class nsCachableElementsByNameNodeList;
 class nsIDocShell;
 class nsDocShell;
 class nsDOMNavigationTiming;
+class nsDOMStyleSheetSetList;
 class nsFrameLoader;
 class nsGlobalWindowInner;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsGenericHTMLElement;
 class nsAtom;
 class nsIBFCacheEntry;
@@ -1105,22 +1106,30 @@ public:
 
   /**
    * Add an SVG element to the list of elements that need
    * their mapped attributes resolved to a Servo declaration block.
    *
    * These are weak pointers, please manually unschedule them when an element
    * is removed.
    */
-  virtual void ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) = 0;
-  // Unschedule an element scheduled by ScheduleFrameRequestCallback (e.g. for when it is destroyed)
-  virtual void UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) = 0;
+  void ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG)
+  {
+    mLazySVGPresElements.PutEntry(aSVG);
+  }
+
+  // Unschedule an element scheduled by ScheduleFrameRequestCallback (e.g. for
+  // when it is destroyed)
+  void UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG)
+  {
+    mLazySVGPresElements.RemoveEntry(aSVG);
+  }
 
   // Resolve all SVG pres attrs scheduled in ScheduleSVGForPresAttrEvaluation
-  virtual void ResolveScheduledSVGPresAttrs() = 0;
+  void ResolveScheduledSVGPresAttrs();
 
   mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const;
   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
 
 protected:
   virtual Element *GetRootElementInternal() const = 0;
 
@@ -1325,76 +1334,78 @@ public:
    * This function prepends the given style sheet to the document's style set
    * in order to make sure that it does not override user-agent style sheets
    * supplied by add-ons or by the app (Firefox OS or Firefox Mobile, for
    * example), since their sheets should override built-in sheets.
    *
    * TODO We can get rid of the whole concept of delayed loading if we fix
    * bug 77999.
    */
-  virtual void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet) = 0;
+  void EnsureOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet);
 
   mozilla::dom::StyleSheetList* StyleSheets()
   {
     return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
   }
 
   /**
    * Insert a sheet at a particular spot in the stylesheet list (zero-based)
    * @param aSheet the sheet to insert
    * @param aIndex the index to insert at.
    * @throws no exceptions
    */
-  virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
-                                  size_t aIndex) = 0;
+  void InsertStyleSheetAt(mozilla::StyleSheet* aSheet, size_t aIndex);
 
 
   /**
    * Replace the stylesheets in aOldSheets with the stylesheets in
    * aNewSheets. The two lists must have equal length, and the sheet
    * at positon J in the first list will be replaced by the sheet at
    * position J in the second list.  Some sheets in the second list
    * may be null; if so the corresponding sheets in the first list
    * will simply be removed.
    */
-  virtual void UpdateStyleSheets(
+  void UpdateStyleSheets(
       nsTArray<RefPtr<mozilla::StyleSheet>>& aOldSheets,
-      nsTArray<RefPtr<mozilla::StyleSheet>>& aNewSheets) = 0;
+      nsTArray<RefPtr<mozilla::StyleSheet>>& aNewSheets);
 
   /**
    * Add a stylesheet to the document
    */
-  virtual void AddStyleSheet(mozilla::StyleSheet* aSheet) = 0;
+  void AddStyleSheet(mozilla::StyleSheet* aSheet);
 
   /**
    * Remove a stylesheet from the document
    */
-  virtual void RemoveStyleSheet(mozilla::StyleSheet* aSheet) = 0;
+  void RemoveStyleSheet(mozilla::StyleSheet* aSheet);
 
   /**
    * Notify the document that the applicable state of the sheet changed
    * and that observers should be notified and style sets updated
    */
-  virtual void SetStyleSheetApplicableState(mozilla::StyleSheet* aSheet,
-                                            bool aApplicable) = 0;
+  void SetStyleSheetApplicableState(mozilla::StyleSheet* aSheet,
+                                    bool aApplicable);
 
   enum additionalSheetType {
     eAgentSheet,
     eUserSheet,
     eAuthorSheet,
     AdditionalSheetTypeCount
   };
 
-  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
-                                            nsIURI* aSheetURI) = 0;
-  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
-                                           mozilla::StyleSheet* aSheet) = 0;
-  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
-                                          nsIURI* sheetURI) = 0;
-  virtual mozilla::StyleSheet* GetFirstAdditionalAuthorSheet() = 0;
+  nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
+                                    nsIURI* aSheetURI);
+  nsresult AddAdditionalStyleSheet(additionalSheetType aType,
+                                   mozilla::StyleSheet* aSheet);
+  void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI);
+
+  mozilla::StyleSheet* GetFirstAdditionalAuthorSheet()
+  {
+    return mAdditionalSheets[eAuthorSheet].SafeElementAt(0);
+  }
 
   /**
    * Assuming that aDocSheets is an array of document-level style
    * sheets for this document, returns the index that aSheet should
    * be inserted at to maintain document ordering.
    *
    * Type T has to cast to StyleSheet*.
    *
@@ -2546,47 +2557,46 @@ public:
    */
   virtual void ForgetImagePreload(nsIURI* aURI) = 0;
 
   /**
    * Called by nsParser to preload style sheets.  Can also be merged into the
    * parser if and when the parser is merged with libgklayout.  aCrossOriginAttr
    * should be a void string if the attr is not present.
    */
-  virtual void PreloadStyle(nsIURI* aURI,
-                            const mozilla::Encoding* aEncoding,
-                            const nsAString& aCrossOriginAttr,
-                            ReferrerPolicyEnum aReferrerPolicy,
-                            const nsAString& aIntegrity) = 0;
+  void PreloadStyle(nsIURI* aURI,
+                    const mozilla::Encoding* aEncoding,
+                    const nsAString& aCrossOriginAttr,
+                    ReferrerPolicyEnum aReferrerPolicy,
+                    const nsAString& aIntegrity);
 
   /**
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
    */
-  virtual nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet,
-                                       RefPtr<mozilla::StyleSheet>* aSheet) = 0;
+  nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet,
+                               RefPtr<mozilla::StyleSheet>* aSheet);
 
   /**
    * Returns true if the locale used for the document specifies a direction of
    * right to left. For chrome documents, this comes from the chrome registry.
    * This is used to determine the current state for the :-moz-locale-dir pseudoclass
    * so once can know whether a document is expected to be rendered left-to-right
    * or right-to-left.
    */
   virtual bool IsDocumentRightToLeft() { return false; }
 
   /**
    * Called by Parser for link rel=preconnect
    */
-  virtual void MaybePreconnect(nsIURI* uri,
-                               mozilla::CORSMode aCORSMode) = 0;
+  virtual void MaybePreconnect(nsIURI* uri, mozilla::CORSMode aCORSMode) = 0;
 
   enum DocumentTheme {
     Doc_Theme_Uninitialized, // not determined yet
     Doc_Theme_None,
     Doc_Theme_Neutral,
     Doc_Theme_Dark,
     Doc_Theme_Bright
   };
@@ -2930,21 +2940,21 @@ public:
     return mVisibilityState != mozilla::dom::VisibilityState::Visible;
   }
   mozilla::dom::VisibilityState VisibilityState() const
   {
     return mVisibilityState;
   }
 #endif
   void GetSelectedStyleSheetSet(nsAString& aSheetSet);
-  virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) = 0;
-  virtual void GetLastStyleSheetSet(nsAString& aSheetSet) = 0;
+  void SetSelectedStyleSheetSet(const nsAString& aSheetSet);
+  void GetLastStyleSheetSet(nsAString& aSheetSet);
   void GetPreferredStyleSheetSet(nsAString& aSheetSet);
-  virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
-  virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
+  mozilla::dom::DOMStringList* StyleSheetSets();
+  void EnableStyleSheetsForSet(const nsAString& aSheetSet);
 
   /**
    * Retrieve the location of the caret position (DOM node and character
    * offset within that node), given a point.
    *
    * @param aX Horizontal point at which to determine the caret position, in
    *           page coordinates.
    * @param aY Vertical point at which to determine the caret position, in
@@ -3218,16 +3228,34 @@ protected:
 
   bool GetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
   {
     return mChildDocumentUseCounters[aUseCounter];
   }
 
   void UpdateDocumentStates(mozilla::EventStates);
 
+  void AddOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet);
+  void RemoveDocStyleSheetsFromStyleSets();
+  void RemoveStyleSheetsFromStyleSets(
+      const nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets,
+      mozilla::SheetType aType);
+  void ResetStylesheetsToURI(nsIURI* aURI);
+  void FillStyleSet(mozilla::StyleSetHandle aStyleSet);
+  void AddStyleSheetToStyleSets(mozilla::StyleSheet* aSheet);
+  void RemoveStyleSheetFromStyleSets(mozilla::StyleSheet* aSheet);
+  void NotifyStyleSheetAdded(mozilla::StyleSheet* aSheet, bool aDocumentSheet);
+  void NotifyStyleSheetRemoved(mozilla::StyleSheet* aSheet, bool aDocumentSheet);
+  void NotifyStyleSheetApplicableStateChanged();
+  // Just like EnableStyleSheetsForSet, but doesn't check whether
+  // aSheetSet is null and allows the caller to control whether to set
+  // aSheetSet as the preferred set in the CSSLoader.
+  void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
+                                       bool aUpdateCSSLoader);
+
 private:
   mutable std::bitset<eDeprecatedOperationCount> mDeprecationWarnedAbout;
   mutable std::bitset<eDocumentWarningCount> mDocWarningWarnedAbout;
 
   // Lazy-initialization to have mDocGroup initialized in prior to the
   // SelectorCaches.
   // FIXME(emilio): We can use a single cache when all CSSOM methods are
   // implemented for the Servo backend.
@@ -3588,16 +3616,24 @@ protected:
 
   // True if the document has been detached from its content viewer.
   bool mIsGoingAway: 1;
 
   bool mInXBLUpdate: 1;
 
   bool mNeedsReleaseAfterStackRefCntRelease: 1;
 
+  // Whether we have filled our pres shell's style set with the document's
+  // additional sheets and sheets from the nsStyleSheetService.
+  bool mStyleSetFilled: 1;
+
+  // Keeps track of whether we have a pending
+  // 'style-sheet-applicable-state-changed' notification.
+  bool mSSApplicableStateNotificationPending: 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
@@ -3790,16 +3826,28 @@ 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;
 
   // Our update nesting level
   uint32_t mUpdateNestLevel;
 
+  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
+  // attributes in Servo mode. This list contains all elements which need lazy
+  // resolution.
+  nsTHashtable<nsPtrHashKey<nsSVGElement>> mLazySVGPresElements;
+
   // Restyle root for servo's style system.
   //
   // We store this as an nsINode, rather than as an Element, so that we can store
   // the Document node as the restyle root if the entire document (along with all
   // document-level native-anonymous content) needs to be restyled.
   //
   // We also track which "descendant" bits (normal/animation-only/lazy-fc) the
   // root corresponds to.