Bug 1363572 Part 3: Change ServoStyleSet to use sheet addresses as unique IDs. draft
authorBrad Werth <bwerth@mozilla.com>
Fri, 12 May 2017 12:04:55 -0700
changeset 577074 6469bf51d69da1877b5b9d7f1e8c7852cd0b5fac
parent 577073 a7b1d9d5139735c67266ff58dfb45c0a9a60896c
child 628413 4944feafb78e53aed8187a2f502d4d5670d682bb
push id58593
push userbwerth@mozilla.com
push dateFri, 12 May 2017 19:49:54 +0000
bugs1363572
milestone55.0a1
Bug 1363572 Part 3: Change ServoStyleSet to use sheet addresses as unique IDs. MozReview-Commit-ID: BZSKZx0wjL8
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -24,19 +24,27 @@
 #include "nsPrintfCString.h"
 #include "nsSMILAnimationController.h"
 #include "nsStyleContext.h"
 #include "nsStyleSet.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+static inline uint64_t UniqueIDForSheet(ServoStyleSheet* aSheet)
+{
+  // Servo tracks sheets by unique ID, and it's important that a given
+  // ServoStyleSheet has the same unique ID throughout its lifetime.
+  // Instead of tracking an arbitrary unique ID for each sheet,
+  // we use the sheet address as a unique ID.
+  return reinterpret_cast<uint64_t>(aSheet);
+}
+
 ServoStyleSet::ServoStyleSet()
   : mPresContext(nullptr)
-  , mUniqueIDCounter(0)
   , mAllowResolveStaleStyles(false)
   , mAuthorStyleDisabled(false)
   , mStylistMayNeedRebuild(false)
 {
 }
 
 ServoStyleSet::~ServoStyleSet()
 {
@@ -48,31 +56,28 @@ ServoStyleSet::Init(nsPresContext* aPres
   mPresContext = aPresContext;
   mRawSet.reset(Servo_StyleSet_Init(aPresContext));
 
   mPresContext->DeviceContext()->InitFontCache();
   gfxPlatformFontList::PlatformFontList()->InitLangService();
 
   // Now that we have an mRawSet, go ahead and notify about whatever stylesheets
   // we have so far.
-  for (auto& entryArray : mEntries) {
-    for (auto& entry : entryArray) {
+  for (auto& sheetArray : mSheets) {
+    for (auto& sheet : sheetArray) {
       // There's no guarantee this will create a list on the servo side whose
       // ordering matches the list that would have been created had all those
       // sheets been appended/prepended/etc after we had mRawSet. That's okay
       // because Servo only needs to maintain relative ordering within a sheet
       // type, which this preserves.
 
-      // Set the uniqueIDs as we go.
-      entry.uniqueID = ++mUniqueIDCounter;
-
-      MOZ_ASSERT(entry.sheet->RawSheet(), "We should only append non-null raw sheets.");
+      MOZ_ASSERT(sheet->RawSheet(), "We should only append non-null raw sheets.");
       Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
-                                      entry.sheet->RawSheet(),
-                                      entry.uniqueID);
+                                      sheet->RawSheet(),
+                                      UniqueIDForSheet(sheet));
     }
   }
 
   // No need to Servo_StyleSet_FlushStyleSheets because we just created the
   // mRawSet, so there was nothing to flush.
 }
 
 void
@@ -567,70 +572,68 @@ nsresult
 ServoStyleSet::AppendStyleSheet(SheetType aType,
                                 ServoStyleSheet* aSheet)
 {
   MOZ_ASSERT(aSheet);
   MOZ_ASSERT(aSheet->IsApplicable());
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
   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.
-  uint64_t oldUniqueID = RemoveSheetOfType(aType, aSheet);
-  uint64_t newUniqueID = AppendSheetOfType(aType, aSheet, oldUniqueID);
+  RemoveSheetOfType(aType, aSheet);
+  AppendSheetOfType(aType, aSheet);
 
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
+    // Servo will remove aSheet from its original position as part of the call
+    // to Servo_StyleSet_AppendStyleSheet.
     Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
                                     aSheet->RawSheet(),
-                                    newUniqueID);
+                                    UniqueIDForSheet(aSheet));
     mStylistMayNeedRebuild = true;
   }
 
   return NS_OK;
 }
 
 nsresult
 ServoStyleSet::PrependStyleSheet(SheetType aType,
                                  ServoStyleSheet* aSheet)
 {
   MOZ_ASSERT(aSheet);
   MOZ_ASSERT(aSheet->IsApplicable());
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
   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.
-  uint64_t oldUniqueID = RemoveSheetOfType(aType, aSheet);
-  uint64_t newUniqueID = PrependSheetOfType(aType, aSheet, oldUniqueID);
+  RemoveSheetOfType(aType, aSheet);
+  PrependSheetOfType(aType, aSheet);
 
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
+    // Servo will remove aSheet from its original position as part of the call
+    // to Servo_StyleSet_PrependStyleSheet.
     Servo_StyleSet_PrependStyleSheet(mRawSet.get(),
                                      aSheet->RawSheet(),
-                                     newUniqueID);
+                                     UniqueIDForSheet(aSheet));
     mStylistMayNeedRebuild = true;
   }
 
   return NS_OK;
 }
 
 nsresult
 ServoStyleSet::RemoveStyleSheet(SheetType aType,
                                 ServoStyleSheet* aSheet)
 {
   MOZ_ASSERT(aSheet);
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
 
-  uint64_t uniqueID = RemoveSheetOfType(aType, aSheet);
-  if (mRawSet && uniqueID) {
+  RemoveSheetOfType(aType, aSheet);
+  if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
-    Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), uniqueID);
+    Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), UniqueIDForSheet(aSheet));
     mStylistMayNeedRebuild = true;
   }
 
   return NS_OK;
 }
 
 nsresult
 ServoStyleSet::ReplaceSheets(SheetType aType,
@@ -640,30 +643,30 @@ ServoStyleSet::ReplaceSheets(SheetType a
   // 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.
 
   mStylistMayNeedRebuild = true;
 
   // Remove all the existing sheets first.
   if (mRawSet) {
-    for (const Entry& entry : mEntries[aType]) {
-      Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), entry.uniqueID);
+    for (const auto& sheet : mSheets[aType]) {
+      Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), UniqueIDForSheet(sheet));
     }
   }
-  mEntries[aType].Clear();
+  mSheets[aType].Clear();
 
   // Add in all the new sheets.
   for (auto& sheet : aNewSheets) {
-    uint64_t uniqueID = AppendSheetOfType(aType, sheet);
+    AppendSheetOfType(aType, sheet);
     if (mRawSet) {
       MOZ_ASSERT(sheet->RawSheet(), "Raw sheet should be in place before replacement.");
       Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
                                       sheet->RawSheet(),
-                                      uniqueID);
+                                      UniqueIDForSheet(sheet));
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
@@ -672,55 +675,46 @@ ServoStyleSet::InsertStyleSheetBefore(Sh
 {
   MOZ_ASSERT(aNewSheet);
   MOZ_ASSERT(aReferenceSheet);
   MOZ_ASSERT(aNewSheet->IsApplicable());
   MOZ_ASSERT(aNewSheet != aReferenceSheet, "Can't place sheet before itself.");
   MOZ_ASSERT(aNewSheet->RawSheet(), "Raw sheet should be in place before insertion.");
   MOZ_ASSERT(aReferenceSheet->RawSheet(), "Reference sheet should have a raw sheet.");
 
-  uint64_t beforeUniqueID = FindSheetOfType(aType, aReferenceSheet);
-  if (beforeUniqueID == 0) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  // If we were already tracking aNewSheet, the newUniqueID will be the same
-  // as the oldUniqueID. In that case, Servo will remove aNewSheet from its
-  // original position as part of the call to Servo_StyleSet_InsertStyleSheetBefore.
-  uint64_t oldUniqueID = RemoveSheetOfType(aType, aNewSheet);
-  uint64_t newUniqueID = InsertSheetOfType(aType,
-                                           aNewSheet,
-                                           beforeUniqueID,
-                                           oldUniqueID);
+  // Servo will remove aNewSheet from its original position as part of the
+  // call to Servo_StyleSet_InsertStyleSheetBefore.
+  RemoveSheetOfType(aType, aNewSheet);
+  InsertSheetOfType(aType, aNewSheet, aReferenceSheet);
 
   if (mRawSet) {
     // Maintain a mirrored list of sheets on the servo side.
     Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(),
                                           aNewSheet->RawSheet(),
-                                          newUniqueID,
-                                          beforeUniqueID);
+                                          UniqueIDForSheet(aNewSheet),
+                                          UniqueIDForSheet(aReferenceSheet));
     mStylistMayNeedRebuild = true;
   }
 
   return NS_OK;
 }
 
 int32_t
 ServoStyleSet::SheetCount(SheetType aType) const
 {
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
-  return mEntries[aType].Length();
+  return mSheets[aType].Length();
 }
 
 ServoStyleSheet*
 ServoStyleSet::StyleSheetAt(SheetType aType,
                             int32_t aIndex) const
 {
   MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
-  return mEntries[aType][aIndex].sheet;
+  return mSheets[aType][aIndex];
 }
 
 nsresult
 ServoStyleSet::RemoveDocStyleSheet(ServoStyleSheet* aSheet)
 {
   return RemoveStyleSheet(SheetType::Doc, aSheet);
 }
 
@@ -728,48 +722,43 @@ nsresult
 ServoStyleSet::AddDocStyleSheet(ServoStyleSheet* aSheet,
                                 nsIDocument* aDocument)
 {
   MOZ_ASSERT(aSheet->IsApplicable());
   MOZ_ASSERT(aSheet->RawSheet(), "Raw sheet should be in place by this point.");
 
   RefPtr<StyleSheet> strong(aSheet);
 
-  uint64_t oldUniqueID = RemoveSheetOfType(SheetType::Doc, aSheet);
+  RemoveSheetOfType(SheetType::Doc, aSheet);
 
   size_t index =
-    aDocument->FindDocStyleSheetInsertionPoint(mEntries[SheetType::Doc], aSheet);
+    aDocument->FindDocStyleSheetInsertionPoint(mSheets[SheetType::Doc], aSheet);
 
-  if (index < mEntries[SheetType::Doc].Length()) {
+  if (index < mSheets[SheetType::Doc].Length()) {
     // This case is insert before.
-    uint64_t beforeUniqueID = mEntries[SheetType::Doc][index].uniqueID;
-    uint64_t newUniqueID = InsertSheetOfType(SheetType::Doc,
-                                             aSheet,
-                                             beforeUniqueID,
-                                             oldUniqueID);
+    ServoStyleSheet *beforeSheet = mSheets[SheetType::Doc][index];
+    InsertSheetOfType(SheetType::Doc, aSheet, beforeSheet);
 
     if (mRawSet) {
       // Maintain a mirrored list of sheets on the servo side.
       Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(),
                                             aSheet->RawSheet(),
-                                            newUniqueID,
-                                            beforeUniqueID);
+                                            UniqueIDForSheet(aSheet),
+                                            UniqueIDForSheet(beforeSheet));
       mStylistMayNeedRebuild = true;
     }
   } else {
     // This case is append.
-    uint64_t newUniqueID = AppendSheetOfType(SheetType::Doc,
-                                             aSheet,
-                                             oldUniqueID);
+    AppendSheetOfType(SheetType::Doc, aSheet);
 
     if (mRawSet) {
       // Maintain a mirrored list of sheets on the servo side.
       Servo_StyleSet_AppendStyleSheet(mRawSet.get(),
                                       aSheet->RawSheet(),
-                                      newUniqueID);
+                                      UniqueIDForSheet(aSheet));
       mStylistMayNeedRebuild = true;
     }
   }
 
   return NS_OK;
 }
 
 already_AddRefed<nsStyleContext>
@@ -1068,79 +1057,52 @@ ServoStyleSet::ResolveForDeclarations(
 void
 ServoStyleSet::RebuildStylist()
 {
   MOZ_ASSERT(mStylistMayNeedRebuild);
   Servo_StyleSet_FlushStyleSheets(mRawSet.get());
   mStylistMayNeedRebuild = false;
 }
 
-uint64_t
-ServoStyleSet::FindSheetOfType(SheetType aType,
-                               ServoStyleSheet* aSheet)
+void
+ServoStyleSet::PrependSheetOfType(SheetType aType,
+                                  ServoStyleSheet* aSheet)
 {
-  for (const auto& entry : mEntries[aType]) {
-    if (entry.sheet == aSheet) {
-      return entry.uniqueID;
-    }
-  }
-  return 0;
+  mSheets[aType].InsertElementAt(0, aSheet);
 }
 
-uint64_t
-ServoStyleSet::PrependSheetOfType(SheetType aType,
-                                  ServoStyleSheet* aSheet,
-                                  uint64_t aReuseUniqueID)
+void
+ServoStyleSet::AppendSheetOfType(SheetType aType,
+                                 ServoStyleSheet* aSheet)
 {
-  Entry* entry = mEntries[aType].InsertElementAt(0);
-  entry->uniqueID = aReuseUniqueID ? aReuseUniqueID : ++mUniqueIDCounter;
-  entry->sheet = aSheet;
-  return entry->uniqueID;
+  mSheets[aType].AppendElement(aSheet);
 }
 
-uint64_t
-ServoStyleSet::AppendSheetOfType(SheetType aType,
-                                 ServoStyleSheet* aSheet,
-                                 uint64_t aReuseUniqueID)
-{
-  Entry* entry = mEntries[aType].AppendElement();
-  entry->uniqueID = aReuseUniqueID ? aReuseUniqueID : ++mUniqueIDCounter;
-  entry->sheet = aSheet;
-  return entry->uniqueID;
-}
-
-uint64_t
+void
 ServoStyleSet::InsertSheetOfType(SheetType aType,
                                  ServoStyleSheet* aSheet,
-                                 uint64_t aBeforeUniqueID,
-                                 uint64_t aReuseUniqueID)
+                                 ServoStyleSheet* aBeforeSheet)
 {
-  for (uint32_t i = 0; i < mEntries[aType].Length(); ++i) {
-    if (mEntries[aType][i].uniqueID == aBeforeUniqueID) {
-      Entry* entry = mEntries[aType].InsertElementAt(i);
-      entry->uniqueID = aReuseUniqueID ? aReuseUniqueID : ++mUniqueIDCounter;
-      entry->sheet = aSheet;
-      return entry->uniqueID;
+  for (uint32_t i = 0; i < mSheets[aType].Length(); ++i) {
+    if (mSheets[aType][i] == aBeforeSheet) {
+      mSheets[aType].InsertElementAt(i, aSheet);
+      return;
     }
   }
-  return 0;
 }
 
-uint64_t
+void
 ServoStyleSet::RemoveSheetOfType(SheetType aType,
                                  ServoStyleSheet* aSheet)
 {
-  for (uint32_t i = 0; i < mEntries[aType].Length(); ++i) {
-    if (mEntries[aType][i].sheet == aSheet) {
-      uint64_t uniqueID = mEntries[aType][i].uniqueID;
-      mEntries[aType].RemoveElementAt(i);
-      return uniqueID;
+  for (uint32_t i = 0; i < mSheets[aType].Length(); ++i) {
+    if (mSheets[aType][i] == aSheet) {
+      mSheets[aType].RemoveElementAt(i);
     }
   }
-  return 0;
 }
 
 void
 ServoStyleSet::RunPostTraversalTasks()
 {
   MOZ_ASSERT(!IsInServoTraversal());
 
   if (mPostTraversalTasks.IsEmpty()) {
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -435,49 +435,33 @@ private:
     }
   }
 
   already_AddRefed<ServoComputedValues> ResolveStyleLazily(dom::Element* aElement,
                                                            nsIAtom* aPseudoTag);
 
   void RunPostTraversalTasks();
 
-  uint64_t FindSheetOfType(SheetType aType,
-                           ServoStyleSheet* aSheet);
+  void PrependSheetOfType(SheetType aType,
+                          ServoStyleSheet* aSheet);
 
-  uint64_t PrependSheetOfType(SheetType aType,
-                              ServoStyleSheet* aSheet,
-                              uint64_t aReuseUniqueID = 0);
-
-  uint64_t AppendSheetOfType(SheetType aType,
-                             ServoStyleSheet* aSheet,
-                             uint64_t aReuseUniqueID = 0);
+  void AppendSheetOfType(SheetType aType,
+                         ServoStyleSheet* aSheet);
 
-  uint64_t InsertSheetOfType(SheetType aType,
-                             ServoStyleSheet* aSheet,
-                             uint64_t aBeforeUniqueID,
-                             uint64_t aReuseUniqueID = 0);
-
-  uint64_t RemoveSheetOfType(SheetType aType,
-                             ServoStyleSheet* aSheet);
+  void InsertSheetOfType(SheetType aType,
+                         ServoStyleSheet* aSheet,
+                         ServoStyleSheet* aBeforeSheet);
 
-  struct Entry {
-    uint64_t uniqueID;
-    RefPtr<ServoStyleSheet> sheet;
-
-    // Provide a cast operator to simplify calling
-    // nsIDocument::FindDocStyleSheetInsertionPoint.
-    operator ServoStyleSheet*() const { return sheet; }
-  };
+  void RemoveSheetOfType(SheetType aType,
+                         ServoStyleSheet* aSheet);
 
   nsPresContext* mPresContext;
   UniquePtr<RawServoStyleSet> mRawSet;
   EnumeratedArray<SheetType, SheetType::Count,
-                  nsTArray<Entry>> mEntries;
-  uint64_t mUniqueIDCounter;
+                  nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
   bool mAllowResolveStaleStyles;
   bool mAuthorStyleDisabled;
   bool mStylistMayNeedRebuild;
 
   // Stores pointers to our cached style contexts for non-inheriting anonymous
   // boxes.
   EnumeratedArray<nsCSSAnonBoxes::NonInheriting,
                   nsCSSAnonBoxes::NonInheriting::_Count,