Bug 1290218 Part 9: Generalize stylesheet Loader to cache Servo sheets in the same way that it caches Gecko sheets. draft
authorBrad Werth <bwerth@mozilla.com>
Tue, 21 Feb 2017 14:05:24 -0800
changeset 488927 0b6f97472279b108b9193050ef73c0d697347bfd
parent 488926 a80f23d967f552c0a10c4e95009e4846826c8c2b
child 488928 3356f9cb981f3bdb5a00f55158e9af1a809c8522
push id46687
push userbwerth@mozilla.com
push dateFri, 24 Feb 2017 01:52:48 +0000
bugs1290218
milestone54.0a1
Bug 1290218 Part 9: Generalize stylesheet Loader to cache Servo sheets in the same way that it caches Gecko sheets. MozReview-Commit-ID: BUEvgos46By
layout/style/Loader.cpp
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1104,18 +1104,17 @@ Loader::CreateSheet(nsIURI* aURI,
 
   *aSheet = nullptr;
   aSheetState = eSheetStateUnknown;
 
   // Check the alternate state before doing anything else, because it
   // can mess with our hashtables.
   *aIsAlternate = IsAlternate(aTitle, aHasAlternateRel);
 
-  // XXXheycam Cached sheets currently must be CSSStyleSheets.
-  if (aURI && GetStyleBackendType() == StyleBackendType::Gecko) {
+  if (aURI) {
     aSheetState = eSheetComplete;
     RefPtr<StyleSheet> sheet;
 
     // First, the XUL cache
 #ifdef MOZ_XUL
     // The XUL cache is a singleton that only holds Gecko-style sheets, so
     // only use the cache if the loader is also Gecko.
     if (IsChromeURI(aURI) &&
@@ -1139,27 +1138,23 @@ Loader::CreateSheet(nsIURI* aURI,
       mSheets->mCompleteSheets.Get(&key, &completeSheet);
       sheet = completeSheet;
       LOG(("  From completed: %p", sheet.get()));
 
       fromCompleteSheets = !!sheet;
     }
 
     if (sheet) {
-      if (sheet->IsServo()) {
-        MOZ_CRASH("stylo: can't clone ServoStyleSheets yet");
-      }
-
       // This sheet came from the XUL cache or our per-document hashtable; it
       // better be a complete sheet.
-      NS_ASSERTION(sheet->AsGecko()->IsComplete(),
+      NS_ASSERTION(sheet->IsComplete(),
                    "Sheet thinks it's not complete while we think it is");
 
       // Make sure it hasn't been modified; if it has, we can't use it
-      if (sheet->AsGecko()->IsModified()) {
+      if (sheet->IsModified()) {
         LOG(("  Not cloning completed sheet %p because it's been modified",
              sheet.get()));
         sheet = nullptr;
         fromCompleteSheets = false;
       }
     }
 
     // Then loading sheets
@@ -1202,38 +1197,35 @@ Loader::CreateSheet(nsIURI* aURI,
                        "Principals should be the same");
 #endif
         }
       }
     }
 
     if (sheet) {
       // The sheet we have now should be either incomplete or unmodified
-      if (sheet->IsServo()) {
-        MOZ_CRASH("stylo: can't clone ServoStyleSheets yet");
-      }
-      NS_ASSERTION(!sheet->AsGecko()->IsModified() ||
-                   !sheet->AsGecko()->IsComplete(),
+      NS_ASSERTION(!sheet->IsModified() ||
+                   !sheet->IsComplete(),
                    "Unexpected modified complete sheet");
-      NS_ASSERTION(sheet->AsGecko()->IsComplete() ||
+      NS_ASSERTION(sheet->IsComplete() ||
                    aSheetState != eSheetComplete,
                    "Sheet thinks it's not complete while we think it is");
 
       RefPtr<StyleSheet> clonedSheet =
         sheet->Clone(nullptr, nullptr, nullptr, nullptr);
       *aSheet = Move(clonedSheet);
       if (*aSheet && fromCompleteSheets &&
-          !sheet->AsGecko()->GetOwnerNode() &&
-          !sheet->AsGecko()->GetParentSheet()) {
+          !sheet->GetOwnerNode() &&
+          !sheet->GetParentSheet()) {
         // The sheet we're cloning isn't actually referenced by
         // anyone.  Replace it in the cache, so that if our CSSOM is
         // later modified we don't end up with two copies of our inner
         // hanging around.
         URIPrincipalReferrerPolicyAndCORSModeHashKey key(aURI, aLoaderPrincipal, aCORSMode, aReferrerPolicy);
-        NS_ASSERTION((*aSheet)->AsGecko()->IsComplete(),
+        NS_ASSERTION((*aSheet)->IsComplete(),
                      "Should only be caching complete sheets");
         mSheets->mCompleteSheets.Put(&key, *aSheet);
       }
     }
   }
 
   if (!*aSheet) {
     aSheetState = eSheetNeedsParser;
@@ -1428,19 +1420,22 @@ Loader::InsertChildSheet(StyleSheet* aSh
   MOZ_ASSERT_IF(aSheet->IsGecko(), aGeckoParentRule && !aServoParentRule);
   MOZ_ASSERT_IF(aSheet->IsServo(), aServoParentRule && !aGeckoParentRule);
   if (aSheet->IsGecko()) {
     // child sheets should always start out enabled, even if they got
     // cloned off of top-level sheets which were disabled
     aSheet->AsGecko()->SetEnabled(true);
     aGeckoParentRule->SetSheet(aSheet->AsGecko()); // This sets the ownerRule on the sheet
   } else {
+    // No matter what, consume the sheet, but we might not use it.
     RefPtr<RawServoStyleSheet> sheet =
       Servo_ImportRule_GetSheet(aServoParentRule).Consume();
-    aSheet->AsServo()->SetSheetForImport(sheet);
+    if (!aSheet->AsServo()->RawSheet()) {
+      aSheet->AsServo()->SetSheetForImport(sheet);
+    }
   }
   aParentSheet->AppendStyleSheet(aSheet);
 
   LOG(("  Inserting into parent sheet"));
   return NS_OK;
 }
 
 /**
@@ -1947,54 +1942,50 @@ Loader::DoSheetComplete(SheetLoadData* a
   // If we ever start doing this for failure aStatus, we'll need to
   // adjust the PostLoadEvent code that thinks anything already
   // complete must have loaded succesfully.
   if (NS_SUCCEEDED(aStatus) && aLoadData->mURI) {
     // Pick our sheet to cache carefully.  Ideally, we want to cache
     // one of the sheets that will be kept alive by a document or
     // parent sheet anyway, so that if someone then accesses it via
     // CSSOM we won't have extra clones of the inner lying around.
-    if (aLoadData->mSheet->IsGecko()) {
-      data = aLoadData;
-      CSSStyleSheet* sheet = aLoadData->mSheet->AsGecko();
-      while (data) {
-        if (data->mSheet->GetParentSheet() || data->mSheet->GetOwnerNode()) {
-          sheet = data->mSheet->AsGecko();
-          break;
-        }
-        data = data->mNext;
+    data = aLoadData;
+    StyleSheet* sheet = aLoadData->mSheet;
+    while (data) {
+      if (data->mSheet->GetParentSheet() || data->mSheet->GetOwnerNode()) {
+        sheet = data->mSheet;
+        break;
       }
+      data = data->mNext;
+    }
 #ifdef MOZ_XUL
-      if (IsChromeURI(aLoadData->mURI) &&
-          GetStyleBackendType() == StyleBackendType::Gecko) {
-        nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
-        if (cache && cache->IsEnabled()) {
-          if (!cache->GetStyleSheet(aLoadData->mURI)) {
-            LOG(("  Putting sheet in XUL prototype cache"));
-            NS_ASSERTION(sheet->IsComplete(),
-                         "Should only be caching complete sheets");
-            cache->PutStyleSheet(sheet);
-          }
+    if (IsChromeURI(aLoadData->mURI) &&
+        GetStyleBackendType() == StyleBackendType::Gecko) {
+      nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
+      if (cache && cache->IsEnabled()) {
+        if (!cache->GetStyleSheet(aLoadData->mURI)) {
+          LOG(("  Putting sheet in XUL prototype cache"));
+          NS_ASSERTION(sheet->IsComplete(),
+                       "Should only be caching complete sheets");
+          cache->PutStyleSheet(sheet);
         }
       }
-      else {
+    }
+    else {
 #endif
-        URIPrincipalReferrerPolicyAndCORSModeHashKey key(aLoadData->mURI,
-                                           aLoadData->mLoaderPrincipal,
-                                           aLoadData->mSheet->GetCORSMode(),
-                                           aLoadData->mSheet->GetReferrerPolicy());
-        NS_ASSERTION(sheet->IsComplete(),
-                     "Should only be caching complete sheets");
-        mSheets->mCompleteSheets.Put(&key, sheet);
+      URIPrincipalReferrerPolicyAndCORSModeHashKey key(aLoadData->mURI,
+                                         aLoadData->mLoaderPrincipal,
+                                         aLoadData->mSheet->GetCORSMode(),
+                                         aLoadData->mSheet->GetReferrerPolicy());
+      NS_ASSERTION(sheet->IsComplete(),
+                   "Should only be caching complete sheets");
+      mSheets->mCompleteSheets.Put(&key, sheet);
 #ifdef MOZ_XUL
-      }
+    }
 #endif
-    } else {
-      NS_WARNING("stylo: Stylesheet caching not yet supported - see bug 1290218.");
-    }
   }
 
   NS_RELEASE(aLoadData);  // this will release parents and siblings and all that
 }
 
 nsresult
 Loader::LoadInlineStyle(nsIContent* aElement,
                         const nsAString& aBuffer,