Bug 1339629 Part 6: Change ServoStyleSet to maintain mStyleSets. draft
authorBrad Werth <bwerth@mozilla.com>
Thu, 04 May 2017 14:02:44 -0700
changeset 574541 cde37439195d8b05be5196bd06f0e0122ea58b2b
parent 574540 3b65142040ce73c13629a613e9633def3b6ffb65
child 574542 94d077a88fd246d85ea50940efdaa8e8a2155c4c
push id57746
push userbwerth@mozilla.com
push dateTue, 09 May 2017 01:15:01 +0000
bugs1339629
milestone55.0a1
Bug 1339629 Part 6: Change ServoStyleSet to maintain mStyleSets. MozReview-Commit-ID: 6gCnYa2EeNE
layout/style/ServoStyleSet.cpp
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -34,16 +34,21 @@ ServoStyleSet::ServoStyleSet()
   , mUniqueIDCounter(0)
   , mAllowResolveStaleStyles(false)
   , mAuthorStyleDisabled(false)
 {
 }
 
 ServoStyleSet::~ServoStyleSet()
 {
+  for (auto& entryArray : mEntries) {
+    for (auto& entry : entryArray) {
+      entry.sheet->DropStyleSet(StyleSetHandle(this));
+    }
+  }
 }
 
 void
 ServoStyleSet::Init(nsPresContext* aPresContext)
 {
   mPresContext = aPresContext;
   mRawSet.reset(Servo_StyleSet_Init(aPresContext));
 
@@ -556,16 +561,20 @@ ServoStyleSet::AppendStyleSheet(SheetTyp
   MOZ_ASSERT(aSheet->RawSheet(), "Raw sheet should be in place before insertion.");
 
   // If we were already tracking aSheet, the newUniqueID will be the same
   // as the oldUniqueID. In that case, Servo will remove aSheet from its
   // original position as part of the call to Servo_StyleSet_AppendStyleSheet.
   uint32_t oldUniqueID = RemoveSheetOfType(aType, aSheet);
   uint32_t newUniqueID = AppendSheetOfType(aType, aSheet, oldUniqueID);
 
+  if (!oldUniqueID) {
+    aSheet->AddStyleSet(StyleSetHandle(this));
+  }
+
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
     Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
                                     aSheet->RawSheet(),
                                     newUniqueID,
                                     !mBatching);
   }
 
@@ -582,16 +591,20 @@ ServoStyleSet::PrependStyleSheet(SheetTy
   MOZ_ASSERT(aSheet->RawSheet(), "Raw sheet should be in place before insertion.");
 
   // If we were already tracking aSheet, the newUniqueID will be the same
   // as the oldUniqueID. In that case, Servo will remove aSheet from its
   // original position as part of the call to Servo_StyleSet_PrependStyleSheet.
   uint32_t oldUniqueID = RemoveSheetOfType(aType, aSheet);
   uint32_t newUniqueID = PrependSheetOfType(aType, aSheet, oldUniqueID);
 
+  if (!oldUniqueID) {
+    aSheet->AddStyleSet(StyleSetHandle(this));
+  }
+
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
     Servo_StyleSet_PrependStyleSheet(mRawSet.get(),
                                      aSheet->RawSheet(),
                                      newUniqueID,
                                      !mBatching);
   }
 
@@ -601,44 +614,61 @@ ServoStyleSet::PrependStyleSheet(SheetTy
 nsresult
 ServoStyleSet::RemoveStyleSheet(SheetType aType,
                                 ServoStyleSheet* aSheet)
 {
   MOZ_ASSERT(aSheet);
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
 
   uint32_t uniqueID = RemoveSheetOfType(aType, aSheet);
-  if (mRawSet && uniqueID) {
-    // Maintain a mirrored list of sheets on the servo side.
-    Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), uniqueID, !mBatching);
+
+  if (uniqueID) {
+    aSheet->DropStyleSet(StyleSetHandle(this));
+
+    if (mRawSet) {
+      // Maintain a mirrored list of sheets on the servo side.
+      Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), uniqueID, !mBatching);
+    }
   }
 
   return NS_OK;
 }
 
 nsresult
 ServoStyleSet::ReplaceSheets(SheetType aType,
                              const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets)
 {
+  MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
+
   // Gecko uses a two-dimensional array keyed by sheet type, whereas Servo
   // stores a flattened list. This makes ReplaceSheets a pretty clunky thing
   // to express. If the need ever arises, we can easily make this more efficent,
   // probably by aligning the representations better between engines.
 
-  // Remove all the existing sheets first.
-  if (mRawSet) {
-    for (const Entry& entry : mEntries[aType]) {
+  StyleSetHandle styleSetHandleThis(this);
+
+  // Remove all the existing sheets.
+  for (const Entry& entry : mEntries[aType]) {
+    // Make the sheets stop tracking this ServoStyleSet.
+    entry.sheet->DropStyleSet(styleSetHandleThis);
+
+    if (mRawSet) {
+      // Remove them from Servo tracking.
       Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), entry.uniqueID, false);
     }
   }
+
+  // Now we can clear out the entries.
   mEntries[aType].Clear();
 
   // Add in all the new sheets.
   for (auto& sheet : aNewSheets) {
     uint32_t uniqueID = AppendSheetOfType(aType, sheet);
+    sheet->AddStyleSet(styleSetHandleThis);
+
     if (mRawSet) {
       MOZ_ASSERT(sheet->RawSheet(), "Raw sheet should be in place before replacement.");
       Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
                                       sheet->RawSheet(),
                                       uniqueID,
                                       false);
     }
   }
@@ -671,16 +701,20 @@ ServoStyleSet::InsertStyleSheetBefore(Sh
   // as the oldUniqueID. In that case, Servo will remove aNewSheet from its
   // original position as part of the call to Servo_StyleSet_InsertStyleSheetBefore.
   uint32_t oldUniqueID = RemoveSheetOfType(aType, aNewSheet);
   uint32_t newUniqueID = InsertSheetOfType(aType,
                                            aNewSheet,
                                            beforeUniqueID,
                                            oldUniqueID);
 
+  if (!oldUniqueID) {
+    aNewSheet->AddStyleSet(StyleSetHandle(this));
+  }
+
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
     Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(),
                                           aNewSheet->RawSheet(),
                                           newUniqueID,
                                           beforeUniqueID,
                                           !mBatching);
   }
@@ -715,16 +749,20 @@ ServoStyleSet::AddDocStyleSheet(ServoSty
 {
   MOZ_ASSERT(aSheet->IsApplicable());
   MOZ_ASSERT(aSheet->RawSheet(), "Raw sheet should be in place by this point.");
 
   RefPtr<StyleSheet> strong(aSheet);
 
   uint32_t oldUniqueID = RemoveSheetOfType(SheetType::Doc, aSheet);
 
+  if (!oldUniqueID) {
+    aSheet->AddStyleSet(StyleSetHandle(this));
+  }
+
   size_t index =
     aDocument->FindDocStyleSheetInsertionPoint(mEntries[SheetType::Doc], aSheet);
 
   if (index < mEntries[SheetType::Doc].Length()) {
     // This case is insert before.
     uint32_t beforeUniqueID = mEntries[SheetType::Doc][index].uniqueID;
     uint32_t newUniqueID = InsertSheetOfType(SheetType::Doc,
                                              aSheet,