Bug 1352763 part 2 - Pass borrowed child stylesheet to Gecko for loading rather than the import rule. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Mon, 03 Apr 2017 16:18:49 +1000
changeset 554966 f5a5f000d6b2876a05f8aca918db85d7cd4241d3
parent 554965 988fb51056dde6756f3ada8a86bea87328e75114
child 554967 52a8f13edb283e1e6fbe2ff6ffa1dc8953580b91
push id52103
push userxquan@mozilla.com
push dateMon, 03 Apr 2017 11:21:25 +0000
reviewersemilio
bugs1352763
milestone55.0a1
Bug 1352763 part 2 - Pass borrowed child stylesheet to Gecko for loading rather than the import rule. r?emilio This is necessary because if we pass in the import rule, we would need to invoke Servo_ImportRule_GetSheet to get the child sheet. However, Servo_ImportRule_GetSheet tries to lock the global rwlock with read access, while Servo_CssRules_InsertRule has already locked the same rwlock with write access for the CSSOM case. Since the import rule itself is never needed in the code path, it is easier to just pass in the child stylesheet. MozReview-Commit-ID: 4njNyGniPIm
layout/style/Loader.cpp
layout/style/Loader.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1406,34 +1406,31 @@ Loader::InsertSheetInDoc(StyleSheet* aSh
  * want to insert the sheet at the correct position, we'll need to
  * restore CSSStyleSheet::InsertStyleSheetAt, which was removed in
  * bug 1220506.)
  */
 nsresult
 Loader::InsertChildSheet(StyleSheet* aSheet,
                          StyleSheet* aParentSheet,
                          ImportRule* aGeckoParentRule,
-                         const RawServoImportRule* aServoParentRule)
+                         const RawServoStyleSheet* aServoChildSheet)
 {
   LOG(("css::Loader::InsertChildSheet"));
   MOZ_ASSERT(aSheet, "Nothing to insert");
   MOZ_ASSERT(aParentSheet, "Need a parent to insert into");
-  MOZ_ASSERT_IF(aSheet->IsGecko(), aGeckoParentRule && !aServoParentRule);
-  MOZ_ASSERT_IF(aSheet->IsServo(), aServoParentRule && !aGeckoParentRule);
+  MOZ_ASSERT_IF(aSheet->IsGecko(), aGeckoParentRule && !aServoChildSheet);
+  MOZ_ASSERT_IF(aSheet->IsServo(), aServoChildSheet && !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();
     if (!aSheet->AsServo()->RawSheet()) {
-      aSheet->AsServo()->SetSheetForImport(sheet);
+      aSheet->AsServo()->SetSheetForImport(aServoChildSheet);
     }
   }
   aParentSheet->AppendStyleSheet(aSheet);
 
   LOG(("  Inserting into parent sheet"));
   return NS_OK;
 }
 
@@ -2202,27 +2199,27 @@ HaveAncestorDataWithURI(SheetLoadData *a
   return false;
 }
 
 nsresult
 Loader::LoadChildSheet(StyleSheet* aParentSheet,
                        nsIURI* aURL,
                        nsMediaList* aMedia,
                        ImportRule* aGeckoParentRule,
-                       const RawServoImportRule* aServoParentRule,
+                       const RawServoStyleSheet* aServoChildSheet,
                        LoaderReusableStyleSheets* aReusableSheets)
 {
   LOG(("css::Loader::LoadChildSheet"));
   NS_PRECONDITION(aURL, "Must have a URI to load");
   NS_PRECONDITION(aParentSheet, "Must have a parent sheet");
 
   // Servo doesn't support reusable sheets.
   MOZ_ASSERT_IF(aReusableSheets, aParentSheet->IsGecko());
-  MOZ_ASSERT_IF(aParentSheet->IsGecko(), aGeckoParentRule && !aServoParentRule);
-  MOZ_ASSERT_IF(aParentSheet->IsServo(), aServoParentRule && !aGeckoParentRule);
+  MOZ_ASSERT_IF(aParentSheet->IsGecko(), aGeckoParentRule && !aServoChildSheet);
+  MOZ_ASSERT_IF(aParentSheet->IsServo(), aServoChildSheet && !aGeckoParentRule);
 
   if (!mEnabled) {
     LOG_WARN(("  Not enabled"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   LOG_URI("  Child uri: '%s'", aURL);
 
@@ -2298,17 +2295,17 @@ Loader::LoadChildSheet(StyleSheet* aPare
                      parentData ? parentData->mSyncLoad : false,
                      false, empty, state, &isAlternate, &sheet);
     NS_ENSURE_SUCCESS(rv, rv);
 
     PrepareSheet(sheet, empty, empty, aMedia, nullptr, isAlternate);
   }
 
   rv = InsertChildSheet(sheet, aParentSheet, aGeckoParentRule,
-                        aServoParentRule);
+                        aServoChildSheet);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (state == eSheetComplete) {
     LOG(("  Sheet already complete"));
     // We're completely done.  No need to notify, even, since the
     // @import rule addition/modification will trigger the right style
     // changes automatically.
     return NS_OK;
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -288,26 +288,26 @@ public:
    * nsICSSLoaderObserver notification will be sent.
    *
    * @param aParentSheet the parent of this child sheet
    * @param aURL the URL of the child sheet
    * @param aMedia the already-parsed media list for the child sheet
    * @param aGeckoParentRule the @import rule importing this child, when using
    *                         Gecko's style system. This is used to properly
    *                         order the child sheet list of aParentSheet.
-   * @param aServoParentRule the @import rule importing this child, when using
-   *                         Servo's style system.
+   * @param aServoChildSheet the child stylesheet of the @import rule, when
+   *                         using Servo's style system.
    * @param aSavedSheets any saved style sheets which could be reused
    *              for this load
    */
   nsresult LoadChildSheet(StyleSheet* aParentSheet,
                           nsIURI* aURL,
                           nsMediaList* aMedia,
                           ImportRule* aGeckoParentRule,
-                          const RawServoImportRule* aServoParentRule,
+                          const RawServoStyleSheet* aServoChildSheet,
                           LoaderReusableStyleSheets* aSavedSheets);
 
   /**
    * Synchronously load and return the stylesheet at aURL.  Any child sheets
    * will also be loaded synchronously.  Note that synchronous loads over some
    * protocols may involve spinning up a new event loop, so use of this method
    * does NOT guarantee not receiving any events before the sheet loads.  This
    * method can be used to load sheets not associated with a document.
@@ -515,17 +515,17 @@ private:
 
   nsresult InsertSheetInDoc(StyleSheet* aSheet,
                             nsIContent* aLinkingContent,
                             nsIDocument* aDocument);
 
   nsresult InsertChildSheet(StyleSheet* aSheet,
                             StyleSheet* aParentSheet,
                             ImportRule* aGeckoParentRule,
-                            const RawServoImportRule* aServoParentRule);
+                            const RawServoStyleSheet* aServoChildSheet);
 
   nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
                                         bool aIsPreload,
                                         SheetParsingMode aParsingMode,
                                         bool aUseSystemPrincipal,
                                         nsIPrincipal* aOriginPrincipal,
                                         const nsCString& aCharset,
                                         RefPtr<StyleSheet>* aSheet,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1531,17 +1531,17 @@ nscoord
 Gecko_nsStyleFont_GetBaseSize(const nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext)
 {
   return aPresContext->GetDefaultFont(aFont->mGenericID, aFont->mLanguage)->size;
 }
 
 void
 Gecko_LoadStyleSheet(css::Loader* aLoader,
                      ServoStyleSheet* aParent,
-                     RawServoImportRuleBorrowed aImportRule,
+                     RawServoStyleSheetBorrowed aChildSheet,
                      RawGeckoURLExtraData* aBaseURLData,
                      const uint8_t* aURLString,
                      uint32_t aURLStringLength,
                      const uint8_t* aMediaString,
                      uint32_t aMediaStringLength)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aLoader, "Should've catched this before");
@@ -1569,17 +1569,17 @@ Gecko_LoadStyleSheet(css::Loader* aLoade
   if (NS_FAILED(rv)) {
     // Servo and Gecko have different ideas of what a valid URL is, so we might
     // get in here with a URL string that NS_NewURI can't handle.  If so,
     // silently do nothing.  Eventually we should be able to assert that the
     // NS_NewURI succeeds, here.
     return;
   }
 
-  aLoader->LoadChildSheet(aParent, uri, media, nullptr, aImportRule, nullptr);
+  aLoader->LoadChildSheet(aParent, uri, media, nullptr, aChildSheet, nullptr);
 }
 
 const nsMediaFeature*
 Gecko_GetMediaFeatures()
 {
   return nsMediaFeatures::features;
 }
 
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -106,17 +106,17 @@ RawGeckoNodeBorrowedOrNull Gecko_GetPrev
 RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node);
 RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element);
 RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element);
 RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element);
 RawGeckoElementBorrowedOrNull Gecko_GetNextSiblingElement(RawGeckoElementBorrowed element);
 RawGeckoElementBorrowedOrNull Gecko_GetDocumentElement(RawGeckoDocumentBorrowed document);
 void Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
                           mozilla::ServoStyleSheet* parent,
-                          RawServoImportRuleBorrowed import_rule,
+                          RawServoStyleSheetBorrowed child_sheet,
                           RawGeckoURLExtraData* base_url_data,
                           const uint8_t* url_bytes,
                           uint32_t url_length,
                           const uint8_t* media_bytes,
                           uint32_t media_length);
 
 // By default, Servo walks the DOM by traversing the siblings of the DOM-view
 // first child. This generally works, but misses anonymous children, which we