Bug 1524328 - Don't resolve counter styles in the style system. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 02 Feb 2019 19:41:44 +0100
changeset 456576 43a3aa2199c12427c9784a9cdbb89f76cf1296a5
parent 456575 1d868390c454251d1ad828eada546bcdf3b0c302
child 456577 96fd408e650f21a4d63ea3ff09f9a3bc25676360
push id35490
push useraiakab@mozilla.com
push dateSun, 03 Feb 2019 09:50:26 +0000
treeherdermozilla-central@12b2328eedd1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1524328
milestone67.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 1524328 - Don't resolve counter styles in the style system. r=xidorn Doing it during layout instead. This also has the nice side-effect of no longer needing to do a full restyle when counter-style rules are inserted. Differential Revision: https://phabricator.services.mozilla.com/D18343
layout/base/nsCounterManager.cpp
layout/base/nsPresContext.cpp
layout/generic/ReflowInput.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsBulletFrame.h
layout/style/CounterStyleManager.cpp
layout/style/CounterStyleManager.h
layout/style/GeckoBindings.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/base/nsCounterManager.cpp
+++ b/layout/base/nsCounterManager.cpp
@@ -73,23 +73,25 @@ void nsCounterUseNode::GetText(nsString&
   stack.AppendElement(static_cast<nsCounterNode*>(this));
 
   if (mAllCounters && mScopeStart) {
     for (nsCounterNode* n = mScopeStart; n->mScopePrev; n = n->mScopeStart) {
       stack.AppendElement(n->mScopePrev);
     }
   }
 
-  WritingMode wm =
-      mPseudoFrame ? mPseudoFrame->GetWritingMode() : WritingMode();
+  WritingMode wm = mPseudoFrame->GetWritingMode();
+  CounterStyle* style =
+      mPseudoFrame->PresContext()->CounterStyleManager()->ResolveCounterStyle(
+          mCounterStyle);
   for (uint32_t i = stack.Length() - 1;; --i) {
     nsCounterNode* n = stack[i];
     nsAutoString text;
     bool isTextRTL;
-    mCounterStyle->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
+    style->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
     aResult.Append(text);
     if (i == 0) {
       break;
     }
     aResult.Append(mSeparator);
   }
 }
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1926,18 +1926,17 @@ void nsPresContext::FlushCounterStyles()
     // Still in its initial state, no need to clean.
     return;
   }
 
   if (mCounterStylesDirty) {
     bool changed = mCounterStyleManager->NotifyRuleChanged();
     if (changed) {
       PresShell()->NotifyCounterStylesAreDirty();
-      PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW,
-                                   eRestyle_ForceDescendants);
+      PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, nsRestyleHint(0));
       RefreshDriver()->AddPostRefreshObserver(
           new CounterStyleCleaner(RefreshDriver(), mCounterStyleManager));
     }
     mCounterStylesDirty = false;
   }
 }
 
 void nsPresContext::MarkCounterStylesDirty() {
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -131,31 +131,42 @@ static nscoord FontSizeInflationListMarg
 
   // We only want to adjust the margins if we're dealing with an ordered list.
   const nsBlockFrame* blockFrame = static_cast<const nsBlockFrame*>(aFrame);
   if (!blockFrame->HasBullet()) {
     return 0;
   }
 
   float inflation = nsLayoutUtils::FontSizeInflationFor(aFrame);
-  if (inflation > 1.0f) {
-    auto listStyleType = aFrame->StyleList()->mCounterStyle->GetStyle();
-    if (listStyleType != NS_STYLE_LIST_STYLE_NONE &&
-        listStyleType != NS_STYLE_LIST_STYLE_DISC &&
-        listStyleType != NS_STYLE_LIST_STYLE_CIRCLE &&
-        listStyleType != NS_STYLE_LIST_STYLE_SQUARE &&
-        listStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
-        listStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN) {
-      // The HTML spec states that the default padding for ordered lists
-      // begins at 40px, indicating that we have 40px of space to place a
-      // bullet. When performing font inflation calculations, we add space
-      // equivalent to this, but simply inflated at the same amount as the
-      // text, in app units.
-      return nsPresContext::CSSPixelsToAppUnits(40) * (inflation - 1);
-    }
+  if (inflation <= 1.0f) {
+    return 0;
+  }
+
+  // The HTML spec states that the default padding for ordered lists
+  // begins at 40px, indicating that we have 40px of space to place a
+  // bullet. When performing font inflation calculations, we add space
+  // equivalent to this, but simply inflated at the same amount as the
+  // text, in app units.
+  auto margin = nsPresContext::CSSPixelsToAppUnits(40) * (inflation - 1);
+
+  auto* list = aFrame->StyleList();
+  if (!list->mCounterStyle.IsAtom()) {
+    return margin;
+  }
+
+  // NOTE(emilio): @counter-style can override some of the styles from this
+  // list, and we won't add margin to the counter.
+  //
+  // See https://github.com/w3c/csswg-drafts/issues/3584
+  nsAtom* type = list->mCounterStyle.AsAtom();
+  if (type != nsGkAtoms::none && type != nsGkAtoms::disc &&
+      type != nsGkAtoms::circle && type != nsGkAtoms::square &&
+      type != nsGkAtoms::disclosure_closed &&
+      type != nsGkAtoms::disclosure_open) {
+    return margin;
   }
 
   return 0;
 }
 
 SizeComputationInput::SizeComputationInput(
     nsIFrame* aFrame, gfxContext* aRenderingContext,
     WritingMode aContainingBlockWritingMode, nscoord aContainingBlockISize)
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6778,20 +6778,23 @@ void nsBlockFrame::SetInitialChildList(C
   }
 }
 
 void nsBlockFrame::CreateBulletFrameForListItem() {
   MOZ_ASSERT((GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET |
                                 NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0,
              "How can we have a bullet already?");
 
-  nsIPresShell* shell = PresShell();
+  nsPresContext* pc = PresContext();
+  nsIPresShell* shell = pc->PresShell();
   const nsStyleList* styleList = StyleList();
-
-  CSSPseudoElementType pseudoType = styleList->mCounterStyle->IsBullet()
+  CounterStyle* style =
+      pc->CounterStyleManager()->ResolveCounterStyle(styleList->mCounterStyle);
+
+  CSSPseudoElementType pseudoType = style->IsBullet()
                                         ? CSSPseudoElementType::mozListBullet
                                         : CSSPseudoElementType::mozListNumber;
 
   RefPtr<ComputedStyle> kidSC =
       ResolveBulletStyle(pseudoType, shell->StyleSet());
 
   // Create bullet frame
   nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC);
@@ -6812,17 +6815,17 @@ void nsBlockFrame::CreateBulletFrameForL
 }
 
 bool nsBlockFrame::BulletIsEmpty() const {
   NS_ASSERTION(mContent->GetPrimaryFrame()->StyleDisplay()->mDisplay ==
                        mozilla::StyleDisplay::ListItem &&
                    HasOutsideBullet(),
                "should only care when we have an outside bullet");
   const nsStyleList* list = StyleList();
-  return list->mCounterStyle->IsNone() && !list->GetListStyleImage();
+  return list->mCounterStyle.IsNone() && !list->GetListStyleImage();
 }
 
 void nsBlockFrame::GetSpokenBulletText(nsAString& aText) const {
   const nsStyleList* myList = StyleList();
   if (myList->GetListStyleImage()) {
     aText.Assign(kDiscCharacter);
     aText.Append(' ');
   } else {
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -47,29 +47,35 @@
 #ifdef ACCESSIBILITY
 #  include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::layout;
+using mozilla::dom::Document;
 
 NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FontSizeInflationProperty, float)
 
 NS_IMPL_FRAMEARENA_HELPERS(nsBulletFrame)
 
 #ifdef DEBUG
 NS_QUERYFRAME_HEAD(nsBulletFrame)
   NS_QUERYFRAME_ENTRY(nsBulletFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
 #endif
 
 nsBulletFrame::~nsBulletFrame() {}
 
+CounterStyle* nsBulletFrame::ResolveCounterStyle() {
+  return PresContext()->CounterStyleManager()->ResolveCounterStyle(
+      StyleList()->mCounterStyle);
+}
+
 void nsBulletFrame::DestroyFrom(nsIFrame* aDestructRoot,
                                 PostDestroyData& aPostDestroyData) {
   // Stop image loading first.
   DeregisterAndCancelImageRequest();
 
   if (mListener) {
     mListener->SetFrame(nullptr);
   }
@@ -82,17 +88,17 @@ void nsBulletFrame::DestroyFrom(nsIFrame
 nsresult nsBulletFrame::GetFrameName(nsAString& aResult) const {
   return MakeFrameName(NS_LITERAL_STRING("Bullet"), aResult);
 }
 #endif
 
 bool nsBulletFrame::IsEmpty() { return IsSelfEmpty(); }
 
 bool nsBulletFrame::IsSelfEmpty() {
-  return StyleList()->mCounterStyle->IsNone();
+  return StyleList()->mCounterStyle.IsNone();
 }
 
 /* virtual */ void nsBulletFrame::DidSetComputedStyle(
     ComputedStyle* aOldComputedStyle) {
   nsFrame::DidSetComputedStyle(aOldComputedStyle);
 
   imgRequestProxy* newRequest = StyleList()->GetListStyleImage();
 
@@ -142,21 +148,21 @@ bool nsBulletFrame::IsSelfEmpty() {
   // Update the list bullet accessible. If old style list isn't available then
   // no need to update the accessible tree because it's not created yet.
   if (aOldComputedStyle) {
     nsAccessibilityService* accService = nsIPresShell::AccService();
     if (accService) {
       const nsStyleList* oldStyleList = aOldComputedStyle->PeekStyleList();
       if (oldStyleList) {
         bool hadBullet = oldStyleList->GetListStyleImage() ||
-                         !oldStyleList->mCounterStyle->IsNone();
+                         !oldStyleList->mCounterStyle.IsNone();
 
         const nsStyleList* newStyleList = StyleList();
         bool hasBullet = newStyleList->GetListStyleImage() ||
-                         !newStyleList->mCounterStyle->IsNone();
+                         !newStyleList->mCounterStyle.IsNone();
 
         if (hadBullet != hasBullet) {
           accService->UpdateListBullet(PresContext()->GetPresShell(), mContent,
                                        hasBullet);
         }
       }
     }
   }
@@ -645,17 +651,17 @@ void nsBulletFrame::BuildDisplayList(nsD
 
   aLists.Content()->AppendToTop(
       MakeDisplayItem<nsDisplayBullet>(aBuilder, this));
 }
 
 Maybe<BulletRenderer> nsBulletFrame::CreateBulletRenderer(
     gfxContext& aRenderingContext, nsPoint aPt) {
   const nsStyleList* myList = StyleList();
-  CounterStyle* listStyleType = myList->mCounterStyle;
+  CounterStyle* listStyleType = ResolveCounterStyle();
   nsMargin padding = mPadding.GetPhysicalMargin(GetWritingMode());
 
   if (myList->GetListStyleImage() && mImageRequest) {
     uint32_t status;
     mImageRequest->GetImageStatus(&status);
     if (status & imgIRequest::STATUS_LOAD_COMPLETE &&
         !(status & imgIRequest::STATUS_ERROR)) {
       nsCOMPtr<imgIContainer> imageCon;
@@ -761,17 +767,17 @@ Maybe<BulletRenderer> nsBulletFrame::Cre
       BulletRenderer br(path, color, listStyleType->GetStyle());
       return Some(br);
     }
 
     default: {
       RefPtr<nsFontMetrics> fm =
           nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
       nsAutoString text;
-      GetListItemText(text);
+      GetListItemText(listStyleType, GetWritingMode(), GetOrdinal(), text);
       WritingMode wm = GetWritingMode();
       nscoord ascent = wm.IsLineInverted() ? fm->MaxDescent() : fm->MaxAscent();
       aPt.MoveBy(padding.left, padding.top);
       if (wm.IsVertical()) {
         if (wm.IsVerticalLR()) {
           aPt.x = NSToCoordRound(nsLayoutUtils::GetSnappedBaselineX(
               this, &aRenderingContext, aPt.x, ascent));
         } else {
@@ -830,35 +836,37 @@ int32_t nsBulletFrame::SetListItemOrdina
     }
   }
 
   *aChanged = oldOrdinal != mOrdinal;
 
   return nsCounterManager::IncrementCounter(mOrdinal, aIncrement);
 }
 
-void nsBulletFrame::GetListItemText(nsAString& aResult) {
-  CounterStyle* style = StyleList()->mCounterStyle;
-  NS_ASSERTION(style->GetStyle() != NS_STYLE_LIST_STYLE_NONE &&
-                   style->GetStyle() != NS_STYLE_LIST_STYLE_DISC &&
-                   style->GetStyle() != NS_STYLE_LIST_STYLE_CIRCLE &&
-                   style->GetStyle() != NS_STYLE_LIST_STYLE_SQUARE &&
-                   style->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
-                   style->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN,
-               "we should be using specialized code for these types");
+void nsBulletFrame::GetListItemText(CounterStyle* aStyle,
+                                    mozilla::WritingMode aWritingMode,
+                                    int32_t aOrdinal, nsAString& aResult) {
+  NS_ASSERTION(
+      aStyle->GetStyle() != NS_STYLE_LIST_STYLE_NONE &&
+          aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISC &&
+          aStyle->GetStyle() != NS_STYLE_LIST_STYLE_CIRCLE &&
+          aStyle->GetStyle() != NS_STYLE_LIST_STYLE_SQUARE &&
+          aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
+          aStyle->GetStyle() != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN,
+      "we should be using specialized code for these types");
 
   bool isRTL;
   nsAutoString counter, prefix, suffix;
-  style->GetPrefix(prefix);
-  style->GetSuffix(suffix);
-  style->GetCounterText(mOrdinal, GetWritingMode(), counter, isRTL);
+  aStyle->GetPrefix(prefix);
+  aStyle->GetSuffix(suffix);
+  aStyle->GetCounterText(aOrdinal, aWritingMode, counter, isRTL);
 
   aResult.Truncate();
   aResult.Append(prefix);
-  if (GetWritingMode().IsBidiLTR() != isRTL) {
+  if (aWritingMode.IsBidiLTR() != isRTL) {
     aResult.Append(counter);
   } else {
     // RLM = 0x200f, LRM = 0x200e
     char16_t mark = isRTL ? 0x200f : 0x200e;
     aResult.Append(mark);
     aResult.Append(counter);
     aResult.Append(mark);
   }
@@ -914,17 +922,18 @@ void nsBulletFrame::GetDesiredSize(nsPre
   // fully there, we'll end up with mIntrinsicSize not matching our size, but
   // won't trigger a reflow in OnStartContainer (because mIntrinsicSize will
   // match the image size).
   mIntrinsicSize.SizeTo(wm, 0, 0);
 
   nscoord bulletSize;
 
   nsAutoString text;
-  switch (myList->mCounterStyle->GetStyle()) {
+  CounterStyle* style = ResolveCounterStyle();
+  switch (style->GetStyle()) {
     case NS_STYLE_LIST_STYLE_NONE:
       finalSize.ISize(wm) = finalSize.BSize(wm) = 0;
       aMetrics.SetBlockStartAscent(0);
       break;
 
     case NS_STYLE_LIST_STYLE_DISC:
     case NS_STYLE_LIST_STYLE_CIRCLE:
     case NS_STYLE_LIST_STYLE_SQUARE: {
@@ -947,17 +956,17 @@ void nsBulletFrame::GetDesiredSize(nsPre
       finalSize.ISize(wm) = finalSize.BSize(wm) = bulletSize;
       if (!wm.IsVertical()) {
         aMetrics.SetBlockStartAscent(bulletSize + aPadding->BEnd(wm));
       }
       AppendSpacingToPadding(fm, aPadding);
       break;
 
     default:
-      GetListItemText(text);
+      GetListItemText(style, GetWritingMode(), GetOrdinal(), text);
       finalSize.BSize(wm) = fm->MaxHeight();
       finalSize.ISize(wm) = nsLayoutUtils::AppUnitWidthOfStringBidi(
           text, this, *fm, *aRenderingContext);
       aMetrics.SetBlockStartAscent(wm.IsLineInverted() ? fm->MaxDescent()
                                                        : fm->MaxAscent());
       break;
   }
   aMetrics.SetSize(wm, finalSize);
@@ -1029,17 +1038,17 @@ void nsBulletFrame::Reflow(nsPresContext
 // If a bullet has zero size and is "ignorable" from its styling, we behave
 // as if it doesn't exist, from a line-breaking/isize-computation perspective.
 // Otherwise, we use the default implementation, same as nsFrame.
 static inline bool IsIgnoreable(const nsIFrame* aFrame, nscoord aISize) {
   if (aISize != nscoord(0)) {
     return false;
   }
   auto listStyle = aFrame->StyleList();
-  return listStyle->mCounterStyle->IsNone() && !listStyle->GetListStyleImage();
+  return listStyle->mCounterStyle.IsNone() && !listStyle->GetListStyleImage();
 }
 
 /* virtual */ void nsBulletFrame::AddInlineMinISize(
     gfxContext* aRenderingContext, nsIFrame::InlineMinISizeData* aData) {
   nscoord isize = nsLayoutUtils::IntrinsicForContainer(
       aRenderingContext, this, nsLayoutUtils::MIN_ISIZE);
   if (MOZ_LIKELY(!::IsIgnoreable(this, isize))) {
     aData->DefaultAddInlineMinISize(this, isize);
@@ -1204,57 +1213,64 @@ already_AddRefed<imgIContainer> nsBullet
     nsCOMPtr<imgIContainer> imageCon;
     mImageRequest->GetImage(getter_AddRefs(imageCon));
     return imageCon.forget();
   }
 
   return nullptr;
 }
 
+nscoord nsBulletFrame::GetListStyleAscent() const {
+  RefPtr<nsFontMetrics> fm =
+      nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
+  auto* list = StyleList();
+  if (list->mCounterStyle.IsNone()) {
+    return 0;
+  }
+  if (list->mCounterStyle.IsAnonymous()) {
+    return fm->MaxAscent();
+  }
+  // NOTE(emilio): @counter-style can override most of the styles from this
+  // list, and we still return the changed ascent. Do we care about that?
+  //
+  // https://github.com/w3c/csswg-drafts/issues/3584
+  nsAtom* style = list->mCounterStyle.AsAtom();
+  if (style == nsGkAtoms::disc || style == nsGkAtoms::circle ||
+      style == nsGkAtoms::square) {
+    nscoord ascent = fm->MaxAscent();
+    nscoord baselinePadding = NSToCoordRound(float(ascent) / 8.0f);
+    ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
+                      NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
+    return ascent + baselinePadding;
+  }
+  if (style == nsGkAtoms::disclosure_open ||
+      style == nsGkAtoms::disclosure_closed) {
+    nscoord ascent = fm->EmAscent();
+    nscoord baselinePadding = NSToCoordRound(0.125f * ascent);
+    ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
+                      NSToCoordRound(0.75f * ascent));
+    return ascent + baselinePadding;
+  }
+  return fm->MaxAscent();
+}
+
 nscoord nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const {
-  nscoord ascent = 0, baselinePadding;
+  nscoord ascent = 0;
   if (GetStateBits() & BULLET_FRAME_IMAGE_LOADING) {
     ascent = BSize(aWritingMode);
   } else {
-    RefPtr<nsFontMetrics> fm =
-        nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
-    CounterStyle* listStyleType = StyleList()->mCounterStyle;
-    switch (listStyleType->GetStyle()) {
-      case NS_STYLE_LIST_STYLE_NONE:
-        break;
-
-      case NS_STYLE_LIST_STYLE_DISC:
-      case NS_STYLE_LIST_STYLE_CIRCLE:
-      case NS_STYLE_LIST_STYLE_SQUARE:
-        ascent = fm->MaxAscent();
-        baselinePadding = NSToCoordRound(float(ascent) / 8.0f);
-        ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
-                          NSToCoordRound(0.8f * (float(ascent) / 2.0f)));
-        ascent += baselinePadding;
-        break;
-
-      case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
-      case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
-        ascent = fm->EmAscent();
-        baselinePadding = NSToCoordRound(0.125f * ascent);
-        ascent = std::max(nsPresContext::CSSPixelsToAppUnits(MIN_BULLET_SIZE),
-                          NSToCoordRound(0.75f * ascent));
-        ascent += baselinePadding;
-        break;
-
-      default:
-        ascent = fm->MaxAscent();
-        break;
-    }
+    ascent = GetListStyleAscent();
   }
   return ascent + GetLogicalUsedMargin(aWritingMode).BStart(aWritingMode);
 }
 
 void nsBulletFrame::GetSpokenText(nsAString& aText) {
-  CounterStyle* style = StyleList()->mCounterStyle;
+  CounterStyle* style =
+      PresContext()->CounterStyleManager()->ResolveCounterStyle(
+          StyleList()->mCounterStyle);
   bool isBullet;
   style->GetSpokenCounterText(mOrdinal, GetWritingMode(), aText, isBullet);
   if (isBullet) {
     if (!style->IsNone()) {
       aText.Append(' ');
     }
   } else {
     nsAutoString prefix, suffix;
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -88,17 +88,18 @@ class nsBulletFrame final : public nsFra
     return nsFrame::IsFrameOfType(aFlags);
   }
 
   // nsBulletFrame
   int32_t SetListItemOrdinal(int32_t aNextOrdinal, bool* aChanged,
                              int32_t aIncrement);
 
   /* get list item text, with prefix & suffix */
-  void GetListItemText(nsAString& aResult);
+  static void GetListItemText(mozilla::CounterStyle*, mozilla::WritingMode,
+                              int32_t aOrdinal, nsAString& aResult);
 
   void GetSpokenText(nsAString& aText);
 
   Maybe<BulletRenderer> CreateBulletRenderer(gfxContext& aRenderingContext,
                                              nsPoint aPt);
   ImgDrawResult PaintBullet(gfxContext& aRenderingContext, nsPoint aPt,
                             const nsRect& aDirtyRect, uint32_t aFlags,
                             bool aDisableSubpixelAA);
@@ -134,16 +135,18 @@ class nsBulletFrame final : public nsFra
   mozilla::LogicalMargin mPadding;
   RefPtr<imgRequestProxy> mImageRequest;
   RefPtr<nsBulletListener> mListener;
 
   mozilla::LogicalSize mIntrinsicSize;
   int32_t mOrdinal;
 
  private:
+  mozilla::CounterStyle* ResolveCounterStyle();
+  nscoord GetListStyleAscent() const;
   void RegisterImageRequest(bool aKnownToBeAnimated);
   void DeregisterAndCancelImageRequest();
 
   // This is a boolean flag indicating whether or not the current image request
   // has been registered with the refresh driver.
   bool mRequestRegistered : 1;
 };
 
--- a/layout/style/CounterStyleManager.cpp
+++ b/layout/style/CounterStyleManager.cpp
@@ -507,17 +507,18 @@ static bool SystemUsesNegativeSign(uint8
   }
 }
 
 class BuiltinCounterStyle : public CounterStyle {
  public:
   constexpr BuiltinCounterStyle(int32_t aStyle, nsStaticAtom* aName)
       : CounterStyle(aStyle), mName(aName) {}
 
-  nsStaticAtom* GetStyleName() const final;
+  nsStaticAtom* GetStyleName() const { return mName; }
+
   virtual void GetPrefix(nsAString& aResult) override;
   virtual void GetSuffix(nsAString& aResult) override;
   virtual void GetSpokenCounterText(CounterValue aOrdinal,
                                     WritingMode aWritingMode,
                                     nsAString& aResult,
                                     bool& aIsBullet) override;
   virtual bool IsBullet() override;
 
@@ -529,31 +530,23 @@ class BuiltinCounterStyle : public Count
   virtual uint8_t GetSpeakAs() override;
   virtual bool UseNegativeSign() override;
 
   virtual bool GetInitialCounterText(CounterValue aOrdinal,
                                      WritingMode aWritingMode,
                                      nsAString& aResult, bool& aIsRTL) override;
 
  protected:
-  BuiltinCounterStyle(const BuiltinCounterStyle& aOther)
+  constexpr BuiltinCounterStyle(const BuiltinCounterStyle& aOther)
       : CounterStyle(aOther.mStyle), mName(aOther.mName) {}
 
  private:
-  // The atom for the name of the builtin counter style.
-  // Extra indirection to point to nsGkAtoms members rather than the
-  // nsAtom, because members of nsGkAtoms are updated at runtime but
-  // we want to construct BuiltinCounterStyle at compile time.
-  nsStaticAtom* const mName;
+  nsStaticAtom* mName;
 };
 
-/* virtual */ nsStaticAtom* BuiltinCounterStyle::GetStyleName() const {
-  return mName;
-}
-
 /* virtual */ void BuiltinCounterStyle::GetPrefix(nsAString& aResult) {
   aResult.Truncate();
 }
 
 /* virtual */ void BuiltinCounterStyle::GetSuffix(nsAString& aResult) {
   switch (mStyle) {
     case NS_STYLE_LIST_STYLE_NONE:
       aResult.Truncate();
@@ -904,29 +897,28 @@ class DependentBuiltinCounterStyle final
     case NS_STYLE_LIST_STYLE_SIMP_CHINESE_INFORMAL:
     case NS_STYLE_LIST_STYLE_SIMP_CHINESE_FORMAL:
     case NS_STYLE_LIST_STYLE_TRAD_CHINESE_INFORMAL:
     case NS_STYLE_LIST_STYLE_TRAD_CHINESE_FORMAL:
       // These styles all have a larger range than cjk-decimal, so the
       // only case fallback is accessed is that they are extended.
       // Since extending styles will cache the data themselves, we need
       // not cache it here.
-      return mManager->BuildCounterStyle(nsGkAtoms::cjk_decimal);
+      return mManager->ResolveCounterStyle(nsGkAtoms::cjk_decimal);
     default:
       MOZ_ASSERT_UNREACHABLE("Not a valid dependent builtin style");
       return BuiltinCounterStyle::GetFallback();
   }
 }
 
 class CustomCounterStyle final : public CounterStyle {
  public:
-  CustomCounterStyle(nsAtom* aName, CounterStyleManager* aManager,
+  CustomCounterStyle(CounterStyleManager* aManager,
                      const RawServoCounterStyleRule* aRule)
       : CounterStyle(NS_STYLE_LIST_STYLE_CUSTOM),
-        mName(aName),
         mManager(aManager),
         mRule(aRule),
         mRuleGeneration(Servo_CounterStyleRule_GetGeneration(aRule)),
         mSystem(Servo_CounterStyleRule_GetSystem(aRule)),
         mFlags(0),
         mFallback(nullptr),
         mSpeakAsCounter(nullptr),
         mExtends(nullptr),
@@ -942,17 +934,16 @@ class CustomCounterStyle final : public 
   // For counter style extends other, in addition, all fields will be
   // reset to uninitialized state. This method should be called when any
   // other counter style is added, removed, or changed.
   void ResetDependentData();
 
   const RawServoCounterStyleRule* GetRule() const { return mRule; }
   uint32_t GetRuleGeneration() const { return mRuleGeneration; }
 
-  virtual nsAtom* GetStyleName() const override;
   virtual void GetPrefix(nsAString& aResult) override;
   virtual void GetSuffix(nsAString& aResult) override;
   virtual void GetSpokenCounterText(CounterValue aOrdinal,
                                     WritingMode aWritingMode,
                                     nsAString& aResult,
                                     bool& aIsBullet) override;
   virtual bool IsBullet() override;
 
@@ -1006,18 +997,16 @@ class CustomCounterStyle final : public 
   uint8_t GetSpeakAsAutoValue();
   void ComputeRawSpeakAs(uint8_t& aSpeakAs, CounterStyle*& aSpeakAsCounter);
   CounterStyle* ComputeSpeakAs();
 
   CounterStyle* ComputeExtends();
   CounterStyle* GetExtends();
   CounterStyle* GetExtendsRoot();
 
-  RefPtr<nsAtom> mName;
-
   // CounterStyleManager should always overlive any CounterStyle as it
   // is owned by nsPresContext, and will be released after all nodes and
   // frames are released.
   CounterStyleManager* mManager;
 
   RefPtr<const RawServoCounterStyleRule> mRule;
   uint32_t mRuleGeneration;
 
@@ -1089,18 +1078,16 @@ void CustomCounterStyle::ResetDependentD
   mExtends = nullptr;
   mExtendsRoot = nullptr;
   if (IsExtendsSystem()) {
     mFlags &= ~(FLAG_NEGATIVE_INITED | FLAG_PREFIX_INITED | FLAG_SUFFIX_INITED |
                 FLAG_PAD_INITED);
   }
 }
 
-/* virtual */ nsAtom* CustomCounterStyle::GetStyleName() const { return mName; }
-
 /* virtual */ void CustomCounterStyle::GetPrefix(nsAString& aResult) {
   if (!(mFlags & FLAG_PREFIX_INITED)) {
     mFlags |= FLAG_PREFIX_INITED;
 
     nsCSSValue value = GetDesc(eCSSCounterDesc_Prefix);
     if (value.UnitHasStringValue()) {
       value.GetStringValue(mPrefix);
     } else if (IsExtendsSystem()) {
@@ -1247,17 +1234,17 @@ static inline bool IsRangeValueInfinite(
   }
   aResult = mPad;
 }
 
 /* virtual */ CounterStyle* CustomCounterStyle::GetFallback() {
   if (!mFallback) {
     mFallback = CounterStyleManager::GetDecimalStyle();
     if (nsAtom* fallback = Servo_CounterStyleRule_GetFallback(mRule)) {
-      mFallback = mManager->BuildCounterStyle(fallback);
+      mFallback = mManager->ResolveCounterStyle(fallback);
     } else if (IsExtendsSystem()) {
       mFallback = GetExtends()->GetFallback();
     }
   }
   return mFallback;
 }
 
 /* virtual */ uint8_t CustomCounterStyle::GetSpeakAs() {
@@ -1369,17 +1356,17 @@ void CustomCounterStyle::ComputeRawSpeak
     case eCSSUnit_Auto:
       aSpeakAs = GetSpeakAsAutoValue();
       break;
     case eCSSUnit_Enumerated:
       aSpeakAs = value.GetIntValue();
       break;
     case eCSSUnit_AtomIdent:
       aSpeakAs = NS_STYLE_COUNTER_SPEAKAS_OTHER;
-      aSpeakAsCounter = mManager->BuildCounterStyle(value.GetAtomValue());
+      aSpeakAsCounter = mManager->ResolveCounterStyle(value.GetAtomValue());
       break;
     case eCSSUnit_Null: {
       if (!IsExtendsSystem()) {
         aSpeakAs = GetSpeakAsAutoValue();
       } else {
         CounterStyle* extended = GetExtends();
         if (!extended->IsCustomStyle()) {
           // It is safe to call GetSpeakAs on non-custom style.
@@ -1472,17 +1459,17 @@ CounterStyle* CustomCounterStyle::Comput
   }
   if (mFlags & FLAG_EXTENDS_VISITED) {
     // loop detected
     mFlags |= FLAG_EXTENDS_LOOP;
     return nullptr;
   }
 
   nsAtom* extended = Servo_CounterStyleRule_GetExtended(mRule);
-  CounterStyle* nextCounter = mManager->BuildCounterStyle(extended);
+  CounterStyle* nextCounter = mManager->ResolveCounterStyle(extended);
   CounterStyle* target = nextCounter;
   if (nextCounter->IsCustomStyle()) {
     mFlags |= FLAG_EXTENDS_VISITED;
     target = static_cast<CustomCounterStyle*>(nextCounter)->ComputeExtends();
     mFlags &= ~FLAG_EXTENDS_VISITED;
   }
 
   if (target) {
@@ -1551,20 +1538,16 @@ AnonymousCounterStyle::AnonymousCounterS
 
 AnonymousCounterStyle::AnonymousCounterStyle(uint8_t aSystem,
                                              nsTArray<nsString> aSymbols)
     : CounterStyle(NS_STYLE_LIST_STYLE_CUSTOM),
       mSingleString(false),
       mSystem(aSystem),
       mSymbols(std::move(aSymbols)) {}
 
-/* virtual */ nsAtom* AnonymousCounterStyle::GetStyleName() const {
-  return nullptr;
-}
-
 /* virtual */ void AnonymousCounterStyle::GetPrefix(nsAString& aResult) {
   aResult.Truncate();
 }
 
 /* virtual */ void AnonymousCounterStyle::GetSuffix(nsAString& aResult) {
   if (IsSingleString()) {
     aResult.Truncate();
   } else {
@@ -1795,30 +1778,30 @@ void CounterStyleManager::Disconnect() {
     if (style->IsDependentStyle()) {
       DestroyCounterStyle(style);
     }
   }
   mStyles.Clear();
   mPresContext = nullptr;
 }
 
-CounterStyle* CounterStyleManager::BuildCounterStyle(nsAtom* aName) {
+CounterStyle* CounterStyleManager::ResolveCounterStyle(nsAtom* aName) {
   MOZ_ASSERT(NS_IsMainThread());
   CounterStyle* data = GetCounterStyle(aName);
   if (data) {
     return data;
   }
 
   // Names are compared case-sensitively here. Predefined names should
   // have been lowercased by the parser.
   ServoStyleSet* styleSet = mPresContext->StyleSet();
   auto* rule = styleSet->CounterStyleRuleForName(aName);
   if (rule) {
     MOZ_ASSERT(Servo_CounterStyleRule_GetName(rule) == aName);
-    data = new (mPresContext) CustomCounterStyle(aName, this, rule);
+    data = new (mPresContext) CustomCounterStyle(this, rule);
   } else {
     for (const BuiltinCounterStyle& item : gBuiltinStyleTable) {
       if (item.GetStyleName() == aName) {
         int32_t style = item.GetStyle();
         data = item.IsDependentStyle()
                    ? new (mPresContext)
                          DependentBuiltinCounterStyle(style, this)
                    : GetBuiltinStyle(style);
@@ -1839,22 +1822,16 @@ CounterStyle* CounterStyleManager::Build
              "Require a valid builtin style constant");
   MOZ_ASSERT(!gBuiltinStyleTable[aStyle].IsDependentStyle(),
              "Cannot get dependent builtin style");
   // No method of BuiltinCounterStyle mutates the struct itself, so it
   // should be fine to cast const away.
   return const_cast<BuiltinCounterStyle*>(&gBuiltinStyleTable[aStyle]);
 }
 
-/* static */ nsAtom* CounterStyleManager::GetStyleNameFromType(int32_t aStyle) {
-  MOZ_ASSERT(0 <= aStyle && size_t(aStyle) < sizeof(gBuiltinStyleTable),
-             "Require a valid builtin style constant");
-  return gBuiltinStyleTable[aStyle].GetStyleName();
-}
-
 bool CounterStyleManager::NotifyRuleChanged() {
   bool changed = false;
   for (auto iter = mStyles.Iter(); !iter.Done(); iter.Next()) {
     CounterStyle* style = iter.Data();
     bool toBeUpdated = false;
     bool toBeRemoved = false;
     ServoStyleSet* styleSet = mPresContext->StyleSet();
     auto* newRule = styleSet->CounterStyleRuleForName(iter.Key());
--- a/layout/style/CounterStyleManager.h
+++ b/layout/style/CounterStyleManager.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef mozilla_CounterStyleManager_h_
 #define mozilla_CounterStyleManager_h_
 
 #include "nsAtom.h"
+#include "nsGkAtoms.h"
 #include "nsStringFwd.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 
 #include "nsStyleConsts.h"
 
 #include "mozilla/Attributes.h"
 
@@ -43,17 +44,16 @@ class CounterStyle {
   constexpr int32_t GetStyle() const { return mStyle; }
   bool IsNone() const { return mStyle == NS_STYLE_LIST_STYLE_NONE; }
   bool IsCustomStyle() const { return mStyle == NS_STYLE_LIST_STYLE_CUSTOM; }
   // A style is dependent if it depends on the counter style manager.
   // Custom styles are certainly dependent. In addition, some builtin
   // styles are dependent for fallback.
   bool IsDependentStyle() const;
 
-  virtual nsAtom* GetStyleName() const = 0;
   virtual void GetPrefix(nsAString& aResult) = 0;
   virtual void GetSuffix(nsAString& aResult) = 0;
   void GetCounterText(CounterValue aOrdinal, WritingMode aWritingMode,
                       nsAString& aResult, bool& aIsRTL);
   virtual void GetSpokenCounterText(CounterValue aOrdinal,
                                     WritingMode aWritingMode,
                                     nsAString& aResult, bool& aIsBullet);
 
@@ -93,17 +93,16 @@ class CounterStyle {
 };
 
 class AnonymousCounterStyle final : public CounterStyle {
  public:
   explicit AnonymousCounterStyle(const nsAString& aContent);
   AnonymousCounterStyle(uint8_t aSystem, nsTArray<nsString> aSymbols);
   explicit AnonymousCounterStyle(const nsCSSValue::Array* aValue);
 
-  virtual nsAtom* GetStyleName() const override;
   virtual void GetPrefix(nsAString& aResult) override;
   virtual void GetSuffix(nsAString& aResult) override;
   virtual bool IsBullet() override;
 
   virtual void GetNegative(NegativeType& aResult) override;
   virtual bool IsOrdinalInRange(CounterValue aOrdinal) override;
   virtual bool IsOrdinalInAutoRange(CounterValue aOrdinal) override;
   virtual void GetPad(PadType& aResult) override;
@@ -133,26 +132,27 @@ class AnonymousCounterStyle final : publ
 
 // A smart pointer to CounterStyle. It either owns a reference to an
 // anonymous counter style, or weakly refers to a named counter style
 // managed by counter style manager.
 class CounterStylePtr {
  public:
   CounterStylePtr() : mRaw(0) {}
   CounterStylePtr(const CounterStylePtr& aOther) : mRaw(aOther.mRaw) {
+    if (!mRaw) {
+      return;
+    }
     switch (GetType()) {
-      case eCounterStyle:
-        break;
       case eAnonymousCounterStyle:
         AsAnonymous()->AddRef();
         break;
-      case eUnresolvedAtom:
+      case eAtom:
         AsAtom()->AddRef();
         break;
-      case eMask:
+      default:
         MOZ_ASSERT_UNREACHABLE("Unknown type");
         break;
     }
   }
   CounterStylePtr(CounterStylePtr&& aOther) : mRaw(aOther.mRaw) {
     aOther.mRaw = 0;
   }
   ~CounterStylePtr() { Reset(); }
@@ -171,120 +171,100 @@ class CounterStylePtr {
       aOther.mRaw = 0;
     }
     return *this;
   }
   CounterStylePtr& operator=(decltype(nullptr)) {
     Reset();
     return *this;
   }
+  CounterStylePtr& operator=(nsStaticAtom* aStaticAtom) {
+    Reset();
+    mRaw = reinterpret_cast<uintptr_t>(aStaticAtom) | eAtom;
+    return *this;
+  }
   CounterStylePtr& operator=(already_AddRefed<nsAtom> aAtom) {
     Reset();
-    if (nsAtom* raw = aAtom.take()) {
-      AssertPointerAligned(raw);
-      mRaw = reinterpret_cast<uintptr_t>(raw) | eUnresolvedAtom;
-    }
+    mRaw = reinterpret_cast<uintptr_t>(aAtom.take()) | eAtom;
     return *this;
   }
   CounterStylePtr& operator=(AnonymousCounterStyle* aCounterStyle) {
     Reset();
     if (aCounterStyle) {
       CounterStyle* raw = do_AddRef(aCounterStyle).take();
-      AssertPointerAligned(raw);
       mRaw = reinterpret_cast<uintptr_t>(raw) | eAnonymousCounterStyle;
     }
     return *this;
   }
-  CounterStylePtr& operator=(CounterStyle* aCounterStyle) {
-    Reset();
-    if (aCounterStyle) {
-      MOZ_ASSERT(!aCounterStyle->AsAnonymous());
-      AssertPointerAligned(aCounterStyle);
-      mRaw = reinterpret_cast<uintptr_t>(aCounterStyle) | eCounterStyle;
-    }
-    return *this;
-  }
 
-  operator CounterStyle*() const& { return Get(); }
-  operator CounterStyle*() const&& = delete;
-  CounterStyle* operator->() const { return Get(); }
   explicit operator bool() const { return !!mRaw; }
   bool operator!() const { return !mRaw; }
   bool operator==(const CounterStylePtr& aOther) const {
+    // FIXME(emilio): For atoms this is all right, but for symbols doesn't this
+    // cause us to compare as unequal all the time, even if the specified
+    // symbols didn't change?
     return mRaw == aOther.mRaw;
   }
   bool operator!=(const CounterStylePtr& aOther) const {
     return mRaw != aOther.mRaw;
   }
 
-  bool IsResolved() const { return !IsUnresolved(); }
-  inline void Resolve(CounterStyleManager* aManager);
-
   nsAtom* AsAtom() const {
-    MOZ_ASSERT(IsUnresolved());
+    MOZ_ASSERT(IsAtom());
     return reinterpret_cast<nsAtom*>(mRaw & ~eMask);
   }
   AnonymousCounterStyle* AsAnonymous() const {
     MOZ_ASSERT(IsAnonymous());
     return static_cast<AnonymousCounterStyle*>(
         reinterpret_cast<CounterStyle*>(mRaw & ~eMask));
   }
 
+  bool IsAtom() const { return GetType() == eAtom; }
+  bool IsAnonymous() const { return GetType() == eAnonymousCounterStyle; }
+
+  bool IsNone() const { return IsAtom() && AsAtom() == nsGkAtoms::none; }
+
  private:
-  CounterStyle* Get() const {
-    MOZ_ASSERT(IsResolved());
-    return reinterpret_cast<CounterStyle*>(mRaw & ~eMask);
-  }
-  template <typename T>
-  void AssertPointerAligned(T* aPointer) {
-    // This can be checked at compile time via
-    // > static_assert(alignof(CounterStyle) >= 4);
-    // > static_assert(alignof(nsAtom) >= 4);
-    // but MSVC2015 doesn't support using alignof on an abstract class.
-    // Once we move to MSVC2017, we can replace this runtime check with
-    // the compile time check above.
-    MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aPointer) & eMask));
-  }
-
   enum Type : uintptr_t {
-    eCounterStyle = 0,
-    eAnonymousCounterStyle = 1,
-    eUnresolvedAtom = 2,
-    eMask = 3,
+    eAnonymousCounterStyle = 0,
+    eAtom = 1,
+    eMask = 1,
   };
 
+  static_assert(alignof(CounterStyle) >= 1 << eMask,
+                "We're gonna tag the pointer, so it better fit");
+  static_assert(alignof(nsAtom) >= 1 << eMask,
+                "We're gonna tag the pointer, so it better fit");
+
   Type GetType() const { return static_cast<Type>(mRaw & eMask); }
-  bool IsUnresolved() const { return GetType() == eUnresolvedAtom; }
-  bool IsAnonymous() const { return GetType() == eAnonymousCounterStyle; }
 
   void Reset() {
+    if (!mRaw) {
+      return;
+    }
     switch (GetType()) {
-      case eCounterStyle:
-        break;
       case eAnonymousCounterStyle:
         AsAnonymous()->Release();
         break;
-      case eUnresolvedAtom:
+      case eAtom:
         AsAtom()->Release();
         break;
-      case eMask:
+      default:
         MOZ_ASSERT_UNREACHABLE("Unknown type");
         break;
     }
     mRaw = 0;
   }
 
-  // mRaw contains the pointer, and its last two bits are used for type
-  // of the pointer.
-  // If the type is eUnresolvedAtom, the pointer owns a reference to an
-  // nsAtom, and it needs to be resolved to a counter style before use.
+  // mRaw contains the pointer, and its last bit is used to store the type of
+  // the pointer.
+  // If the type is eAtom, the pointer owns a reference to an nsAtom
+  // (potentially null).
   // If the type is eAnonymousCounterStyle, it owns a reference to an
-  // anonymous counter style.
-  // Otherwise it is a weak pointer referring a named counter style
-  // managed by CounterStyleManager.
+  // anonymous counter style (never null).
   uintptr_t mRaw;
 };
 
 class CounterStyleManager final {
  private:
   ~CounterStyleManager();
 
  public:
@@ -299,31 +279,35 @@ class CounterStyleManager final {
 
   // Returns the counter style object for the given name from the style
   // table if it is already built, and nullptr otherwise.
   CounterStyle* GetCounterStyle(nsAtom* aName) const {
     return mStyles.Get(aName);
   }
   // Same as GetCounterStyle but try to build the counter style object
   // rather than returning nullptr if that hasn't been built.
-  CounterStyle* BuildCounterStyle(nsAtom* aName);
+  CounterStyle* ResolveCounterStyle(nsAtom* aName);
+  CounterStyle* ResolveCounterStyle(const CounterStylePtr& aPtr) {
+    if (aPtr.IsAtom()) {
+      return ResolveCounterStyle(aPtr.AsAtom());
+    }
+    return aPtr.AsAnonymous();
+  }
 
   static CounterStyle* GetBuiltinStyle(int32_t aStyle);
   static CounterStyle* GetNoneStyle() {
     return GetBuiltinStyle(NS_STYLE_LIST_STYLE_NONE);
   }
   static CounterStyle* GetDecimalStyle() {
     return GetBuiltinStyle(NS_STYLE_LIST_STYLE_DECIMAL);
   }
   static CounterStyle* GetDiscStyle() {
     return GetBuiltinStyle(NS_STYLE_LIST_STYLE_DISC);
   }
 
-  static nsAtom* GetStyleNameFromType(int32_t aStyle);
-
   // This method will scan all existing counter styles generated by this
   // manager, and remove or mark data dirty accordingly. It returns true
   // if any counter style is changed, false elsewise. This method should
   // be called when any counter style may be affected.
   bool NotifyRuleChanged();
   // NotifyRuleChanged will evict no longer needed counter styles into
   // mRetiredStyles, and this function destroys all objects listed there.
   // It should be called only after no one may ever use those objects.
@@ -336,17 +320,11 @@ class CounterStyleManager final {
  private:
   void DestroyCounterStyle(CounterStyle* aCounterStyle);
 
   nsPresContext* mPresContext;
   nsDataHashtable<nsRefPtrHashKey<nsAtom>, CounterStyle*> mStyles;
   nsTArray<CounterStyle*> mRetiredStyles;
 };
 
-void CounterStylePtr::Resolve(CounterStyleManager* aManager) {
-  if (IsUnresolved()) {
-    *this = aManager->BuildCounterStyle(AsAtom());
-  }
-}
-
 }  // namespace mozilla
 
 #endif /* !defined(mozilla_CounterStyleManager_h_) */
--- a/layout/style/GeckoBindings.cpp
+++ b/layout/style/GeckoBindings.cpp
@@ -1119,25 +1119,18 @@ void Gecko_AppendAlternateValues(nsFont*
 void Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc) {
   aDest->alternateValues.Clear();
   aDest->alternateValues.AppendElements(aSrc->alternateValues);
   aDest->featureValueLookup = aSrc->featureValueLookup;
 }
 
 void Gecko_SetCounterStyleToName(CounterStylePtr* aPtr, nsAtom* aName,
                                  RawGeckoPresContextBorrowed aPresContext) {
-  // Try resolving the counter style if possible, and keep it unresolved
-  // otherwise.
-  CounterStyleManager* manager = aPresContext->CounterStyleManager();
   RefPtr<nsAtom> name = already_AddRefed<nsAtom>(aName);
-  if (CounterStyle* style = manager->GetCounterStyle(name)) {
-    *aPtr = style;
-  } else {
-    *aPtr = name.forget();
-  }
+  *aPtr = name.forget();
 }
 
 void Gecko_SetCounterStyleToSymbols(CounterStylePtr* aPtr, uint8_t aSymbolsType,
                                     nsACString const* const* aSymbols,
                                     uint32_t aSymbolsCount) {
   nsTArray<nsString> symbols(aSymbolsCount);
   for (uint32_t i = 0; i < aSymbolsCount; i++) {
     symbols.AppendElement(NS_ConvertUTF8toUTF16(*aSymbols[i]));
@@ -1151,20 +1144,17 @@ void Gecko_SetCounterStyleToString(Count
 }
 
 void Gecko_CopyCounterStyle(CounterStylePtr* aDst,
                             const CounterStylePtr* aSrc) {
   *aDst = *aSrc;
 }
 
 nsAtom* Gecko_CounterStyle_GetName(const CounterStylePtr* aPtr) {
-  if (!aPtr->IsResolved()) {
-    return aPtr->AsAtom();
-  }
-  return (*aPtr)->GetStyleName();
+  return aPtr->IsAtom() ? aPtr->AsAtom() : nullptr;
 }
 
 const AnonymousCounterStyle* Gecko_CounterStyle_GetAnonymous(
     const CounterStylePtr* aPtr) {
   return aPtr->AsAnonymous();
 }
 
 void Gecko_SetNullImageValue(nsStyleImage* aImage) {
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -454,17 +454,17 @@ nsChangeHint nsStyleOutline::CalcDiffere
 // --------------------
 // nsStyleList
 //
 nsStyleList::nsStyleList(const Document& aDocument)
     : mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE) {
   MOZ_COUNT_CTOR(nsStyleList);
   MOZ_ASSERT(NS_IsMainThread());
 
-  mCounterStyle = CounterStyleManager::GetDiscStyle();
+  mCounterStyle = nsGkAtoms::disc;
   mQuotes = Servo_Quotes_GetInitialValue().Consume();
 }
 
 nsStyleList::~nsStyleList() { MOZ_COUNT_DTOR(nsStyleList); }
 
 nsStyleList::nsStyleList(const nsStyleList& aSource)
     : mListStylePosition(aSource.mListStylePosition),
       mListStyleImage(aSource.mListStyleImage),
@@ -477,17 +477,16 @@ nsStyleList::nsStyleList(const nsStyleLi
 void nsStyleList::FinishStyle(nsPresContext* aPresContext,
                               const nsStyleList* aOldStyle) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mListStyleImage && !mListStyleImage->IsResolved()) {
     mListStyleImage->Resolve(
         aPresContext, aOldStyle ? aOldStyle->mListStyleImage.get() : nullptr);
   }
-  mCounterStyle.Resolve(aPresContext->CounterStyleManager());
 }
 
 nsChangeHint nsStyleList::CalcDifference(
     const nsStyleList& aNewData, const nsStyleDisplay* aOldDisplay) const {
   // If the quotes implementation is ever going to change we might not need
   // a framechange here and a reflow should be sufficient.  See bug 35768.
   if (mQuotes != aNewData.mQuotes &&
       !Servo_Quotes_Equal(mQuotes.get(), aNewData.mQuotes.get())) {
@@ -3632,34 +3631,25 @@ bool nsStyleContentData::operator==(cons
     return NS_strcmp(mContent.mString, aOther.mContent.mString) == 0;
   }
   MOZ_ASSERT(!mContent.mString && !aOther.mContent.mString);
   return true;
 }
 
 void nsStyleContentData::Resolve(nsPresContext* aPresContext,
                                  const nsStyleContentData* aOldStyle) {
-  switch (mType) {
-    case StyleContentType::Image:
-      if (!mContent.mImage->IsResolved()) {
-        const nsStyleImageRequest* oldRequest =
-            (aOldStyle && aOldStyle->mType == StyleContentType::Image)
-                ? aOldStyle->mContent.mImage
-                : nullptr;
-        mContent.mImage->Resolve(aPresContext, oldRequest);
-      }
-      break;
-    case StyleContentType::Counter:
-    case StyleContentType::Counters: {
-      mContent.mCounters->mCounterStyle.Resolve(
-          aPresContext->CounterStyleManager());
-      break;
-    }
-    default:
-      break;
+  if (mType != StyleContentType::Image) {
+    return;
+  }
+  if (!mContent.mImage->IsResolved()) {
+    const nsStyleImageRequest* oldRequest =
+        (aOldStyle && aOldStyle->mType == StyleContentType::Image)
+            ? aOldStyle->mContent.mImage
+            : nullptr;
+    mContent.mImage->Resolve(aPresContext, oldRequest);
   }
 }
 
 //-----------------------
 // nsStyleContent
 //
 
 nsStyleContent::nsStyleContent(const Document& aDocument) {
@@ -3683,35 +3673,19 @@ nsStyleContent::nsStyleContent(const nsS
     : mContents(aSource.mContents),
       mIncrements(aSource.mIncrements),
       mResets(aSource.mResets) {
   MOZ_COUNT_CTOR(nsStyleContent);
 }
 
 nsChangeHint nsStyleContent::CalcDifference(
     const nsStyleContent& aNewData) const {
-  // In ElementRestyler::Restyle we assume that if there's no existing
-  // ::before or ::after and we don't have to restyle children of the
-  // node then we can't end up with a ::before or ::after due to the
-  // restyle of the node itself.  That's not quite true, but the only
-  // exception to the above is when the 'content' property of the node
-  // changes and the pseudo-element inherits the changed value.  Since
-  // the code here triggers a frame change on the node in that case,
-  // the optimization in ElementRestyler::Restyle is ok.  But if we ever
-  // change this code to not reconstruct frames on changes to the
-  // 'content' property, then we will need to revisit the optimization
-  // in ElementRestyler::Restyle.
-
   // Unfortunately we need to reframe even if the content lengths are the same;
   // a simple reflow will not pick up different text or different image URLs,
   // since we set all that up in the CSSFrameConstructor
-  //
-  // Also note that we also rely on this to return ReconstructFrame when
-  // content changes to ensure that nsCounterUseNode wouldn't reference
-  // to stale counter stylex.
   if (mContents != aNewData.mContents || mIncrements != aNewData.mIncrements ||
       mResets != aNewData.mResets) {
     return nsChangeHint_ReconstructFrame;
   }
 
   return nsChangeHint(0);
 }
 
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2392,18 +2392,16 @@ class nsStyleContentData {
 
    private:
     ~CounterFunction() {}
   };
 
   CounterFunction* GetCounters() const {
     MOZ_ASSERT(mType == StyleContentType::Counter ||
                mType == StyleContentType::Counters);
-    MOZ_ASSERT(mContent.mCounters->mCounterStyle.IsResolved(),
-               "Counter style should have been resolved");
     return mContent.mCounters;
   }
 
   nsStyleImageRequest* ImageRequest() const {
     MOZ_ASSERT(mType == StyleContentType::Image);
     MOZ_ASSERT(mContent.mImage);
     return mContent.mImage;
   }