Bug 1429529 - Use the same cache for lazy pseudos and anonymous boxes. r=emilio
authorBobby Holley <bobbyholley@gmail.com>
Wed, 10 Jan 2018 11:04:23 -0800
changeset 450670 ea45022c163ec2fd9a2ce9c5444d1593b9c8aa9d
parent 450669 85f9b85ae324a57ed28c1c268d96bd80eefd17da
child 450671 6d539e4a02bd5a819c798c16ffc2fdbe9fb5fab2
push id8531
push userryanvm@gmail.com
push dateFri, 12 Jan 2018 16:47:01 +0000
treeherdermozilla-beta@0bc627ade5a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1429529
milestone59.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 1429529 - Use the same cache for lazy pseudos and anonymous boxes. r=emilio MozReview-Commit-ID: FaSK8RAlrW2
layout/style/CachedInheritingStyles.cpp
layout/style/ServoStyleContext.cpp
layout/style/ServoStyleContext.h
--- a/layout/style/CachedInheritingStyles.cpp
+++ b/layout/style/CachedInheritingStyles.cpp
@@ -9,17 +9,17 @@
 #include "mozilla/ServoStyleContext.h"
 
 namespace mozilla {
 
 void
 CachedInheritingStyles::Insert(ServoStyleContext* aStyle)
 {
   MOZ_ASSERT(aStyle);
-  MOZ_ASSERT(aStyle->IsInheritingAnonBox());
+  MOZ_ASSERT(aStyle->IsInheritingAnonBox() || aStyle->IsLazilyCascadedPseudoElement());
 
   if (IsEmpty()) {
     RefPtr<ServoStyleContext> s = aStyle;
     mBits = reinterpret_cast<uintptr_t>(s.forget().take());
     MOZ_ASSERT(!IsEmpty() && !IsIndirect());
   } else if (IsIndirect()) {
     AsIndirect()->AppendElement(aStyle);
   } else {
@@ -29,17 +29,18 @@ CachedInheritingStyles::Insert(ServoStyl
     mBits = reinterpret_cast<uintptr_t>(cache) | 1;
     MOZ_ASSERT(IsIndirect());
   }
 }
 
 ServoStyleContext*
 CachedInheritingStyles::Lookup(nsAtom* aPseudoTag) const
 {
-  MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aPseudoTag));
+  MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aPseudoTag) ||
+             nsCSSPseudoElements::IsPseudoElement(aPseudoTag));
   if (IsIndirect()) {
     for (auto& style : *AsIndirect()) {
       if (style->GetPseudo() == aPseudoTag) {
         return style;
       }
     }
 
     return nullptr;
--- a/layout/style/ServoStyleContext.cpp
+++ b/layout/style/ServoStyleContext.cpp
@@ -40,18 +40,12 @@ ServoStyleContext::GetCachedLazyPseudoSt
              aPseudo != CSSPseudoElementType::InheritingAnonBox &&
              aPseudo != CSSPseudoElementType::NonInheritingAnonBox);
   MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "Lazy pseudos can't inherit lazy pseudos");
 
   if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudo)) {
     return nullptr;
   }
 
-  auto* current = mNextLazyPseudoStyle.get();
-
-  while (current && current->GetPseudoType() != aPseudo) {
-    current = current->mNextLazyPseudoStyle.get();
-  }
-
-  return current;
+  return mCachedInheritingStyles.Lookup(nsCSSPseudoElements::GetPseudoAtom(aPseudo));
 }
 
 } // namespace mozilla
--- a/layout/style/ServoStyleContext.h
+++ b/layout/style/ServoStyleContext.h
@@ -60,35 +60,33 @@ public:
   }
 
   ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
 
   void SetCachedLazyPseudoStyle(ServoStyleContext* aStyle)
   {
     MOZ_ASSERT(aStyle->GetPseudo() && !aStyle->IsAnonBox());
     MOZ_ASSERT(!GetCachedLazyPseudoStyle(aStyle->GetPseudoType()));
-    MOZ_ASSERT(!aStyle->mNextLazyPseudoStyle);
     MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "lazy pseudos can't inherit lazy pseudos");
     MOZ_ASSERT(aStyle->IsLazilyCascadedPseudoElement());
 
     // Since we're caching lazy pseudo styles on the ComputedValues of the
     // originating element, we can assume that we either have the same
     // originating element, or that they were at least similar enough to share
     // the same ComputedValues, which means that they would match the same
     // pseudo rules. This allows us to avoid matching selectors and checking
     // the rule node before deciding to share.
     //
     // The one place this optimization breaks is with pseudo-elements that
     // support state (like :hover). So we just avoid sharing in those cases.
     if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aStyle->GetPseudoType())) {
       return;
     }
 
-    mNextLazyPseudoStyle.swap(aStyle->mNextLazyPseudoStyle);
-    mNextLazyPseudoStyle = aStyle;
+    mCachedInheritingStyles.Insert(aStyle);
   }
 
   /**
    * Makes this context match |aOther| in terms of which style structs have
    * been resolved.
    */
   inline void ResolveSameStructsAs(const ServoStyleContext* aOther);
 
@@ -99,37 +97,21 @@ public:
   {
     // Note: |this| sits within a servo_arc::Arc, i.e. it is preceded by a
     // refcount. So we need to measure it with a function that can handle an
     // interior pointer. We use ServoComputedValuesMallocEnclosingSizeOf to
     // clearly identify in DMD's output the memory measured here.
     *aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
     mSource.AddSizeOfExcludingThis(aSizes);
     mCachedInheritingStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
-
-    if (mNextLazyPseudoStyle &&
-        !aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
-      mNextLazyPseudoStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
-    }
   }
 
 private:
   nsPresContext* mPresContext;
   ServoComputedData mSource;
 
   // A cache of anonymous box and lazy pseudo styles inheriting from this style.
   CachedInheritingStyles mCachedInheritingStyles;
-
-  // A linked-list cache of lazy pseudo styles inheriting from this style _if
-  // the style isn't a lazy pseudo style itself_.
-  //
-  // Otherwise it represents the next entry in the cache of the parent style
-  // context.
-  //
-  // Note that we store these separately from inheriting anonymous boxes so that
-  // text nodes inheriting from lazy pseudo styles can share styles, which is
-  // very important on some pages.
-  RefPtr<ServoStyleContext> mNextLazyPseudoStyle;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoStyleContext_h