Bug 1350244 - Back out bug 1348606 part 5 (Use a threadsafe array for counters). r=me
authorBobby Holley <bobbyholley@gmail.com>
Mon, 27 Mar 2017 13:22:32 -0700
changeset 398600 8bd66bfcf13ef6ad640b52abf9752f5b6e51e9bb
parent 398599 10ec81ee84c42a6951ffbf86af7e9cd2fa3538dd
child 398601 650053787c73c874e28162e74d2812a877d379eb
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1350244, 1348606
milestone55.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 1350244 - Back out bug 1348606 part 5 (Use a threadsafe array for counters). r=me This reverts commit 07301f1c3f71b36dbe2345e8faa9bc6d643cfc97. MozReview-Commit-ID: 8tLjUhki2C1
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCounterManager.h
layout/style/ServoBindings.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1736,17 +1736,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
       nsCOMPtr<nsIContent> content;
       NS_NewAttributeContent(mDocument->NodeInfoManager(),
                              attrNameSpace, attrName, getter_AddRefs(content));
       return content.forget();
     }
 
     case eStyleContentType_Counter:
     case eStyleContentType_Counters: {
-      nsCSSValue::ThreadSafeArray* counters = data.GetCounters();
+      nsCSSValue::Array* counters = data.GetCounters();
       nsCounterList* counterList = mCounterManager.CounterListFor(
           nsDependentString(counters->Item(0).GetStringBufferValue()));
 
       nsCounterUseNode* node =
         new nsCounterUseNode(mPresShell->GetPresContext(),
                              counters, aContentIndex,
                              type == eStyleContentType_Counters);
 
--- a/layout/base/nsCounterManager.h
+++ b/layout/base/nsCounterManager.h
@@ -74,27 +74,27 @@ struct nsCounterNode : public nsGenConNo
     // to avoid virtual function calls in the common case
     inline void Calc(nsCounterList* aList);
 };
 
 struct nsCounterUseNode : public nsCounterNode {
     // The same structure passed through the style system:  an array
     // containing the values in the counter() or counters() in the order
     // given in the CSS spec.
-    RefPtr<nsCSSValue::ThreadSafeArray> mCounterFunction;
+    RefPtr<nsCSSValue::Array> mCounterFunction;
 
     nsPresContext* mPresContext;
     RefPtr<mozilla::CounterStyle> mCounterStyle;
 
     // false for counter(), true for counters()
     bool mAllCounters;
 
     // args go directly to member variables here and of nsGenConNode
     nsCounterUseNode(nsPresContext* aPresContext,
-                     nsCSSValue::ThreadSafeArray* aCounterFunction,
+                     nsCSSValue::Array* aCounterFunction,
                      uint32_t aContentIndex, bool aAllCounters)
         : nsCounterNode(aContentIndex, USE)
         , mCounterFunction(aCounterFunction)
         , mPresContext(aPresContext)
         , mCounterStyle(nullptr)
         , mAllCounters(aAllCounters)
     {
         NS_ASSERTION(aContentIndex <= INT32_MAX, "out of range");
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -973,17 +973,17 @@ Gecko_SetContentDataImage(nsStyleContent
   RefPtr<nsStyleImageRequest> req = CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aURI);
   aContent->SetImageRequest(req.forget());
 }
 
 void
 Gecko_SetContentDataArray(nsStyleContentData* aContent,
                           nsStyleContentType aType, uint32_t aLen)
 {
-  nsCSSValue::ThreadSafeArray* arr = nsCSSValue::ThreadSafeArray::Create(aLen);
+  nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
   aContent->SetCounters(aType, arr);
 }
 
 nsStyleGradient*
 Gecko_CreateGradient(uint8_t aShape,
                      uint8_t aSize,
                      bool aRepeating,
                      bool aLegacySyntax,
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -8021,18 +8021,18 @@ CSSParserImpl::ParseCounter(nsCSSValue& 
     if (!GetToken(true)) {
       break;
     }
     if (eCSSToken_Ident != mToken.mType) {
       UngetToken();
       break;
     }
 
-    RefPtr<nsCSSValue::ThreadSafeArray> val =
-      nsCSSValue::ThreadSafeArray::Create(unit == eCSSUnit_Counter ? 2 : 3);
+    RefPtr<nsCSSValue::Array> val =
+      nsCSSValue::Array::Create(unit == eCSSUnit_Counter ? 2 : 3);
 
     val->Item(0).SetStringValue(mToken.mIdent, eCSSUnit_Ident);
 
     if (eCSSUnit_Counters == unit) {
       // must have a comma and then a separator string
       if (!ExpectSymbol(',', true) || !GetToken(true)) {
         break;
       }
@@ -8053,17 +8053,17 @@ CSSParserImpl::ParseCounter(nsCSSValue& 
     } else {
       type.SetStringValue(NS_LITERAL_STRING("decimal"), eCSSUnit_Ident);
     }
 
     if (!ExpectSymbol(')', true)) {
       break;
     }
 
-    aValue.SetThreadSafeArrayValue(val, unit);
+    aValue.SetArrayValue(val, unit);
     return true;
   }
 
   SkipUntil(')');
   return false;
 }
 
 bool
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -167,20 +167,16 @@ nsCSSValue::nsCSSValue(const nsCSSValue&
   else if (eCSSUnit_ComplexColor == mUnit) {
     mValue.mComplexColor = aCopy.mValue.mComplexColor;
     mValue.mComplexColor->AddRef();
   }
   else if (UnitHasArrayValue()) {
     mValue.mArray = aCopy.mValue.mArray;
     mValue.mArray->AddRef();
   }
-  else if (UnitHasThreadSafeArrayValue()) {
-    mValue.mThreadSafeArray = aCopy.mValue.mThreadSafeArray;
-    mValue.mThreadSafeArray->AddRef();
-  }
   else if (eCSSUnit_URL == mUnit) {
     mValue.mURL = aCopy.mValue.mURL;
     mValue.mURL->AddRef();
   }
   else if (eCSSUnit_Image == mUnit) {
     mValue.mImage = aCopy.mValue.mImage;
     mValue.mImage->AddRef();
   }
@@ -287,19 +283,16 @@ bool nsCSSValue::operator==(const nsCSSV
       return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
     }
     else if (eCSSUnit_ComplexColor == mUnit) {
       return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
     }
     else if (UnitHasArrayValue()) {
       return *mValue.mArray == *aOther.mValue.mArray;
     }
-    else if (UnitHasThreadSafeArrayValue()) {
-      return *mValue.mThreadSafeArray == *aOther.mValue.mThreadSafeArray;
-    }
     else if (eCSSUnit_URL == mUnit) {
       return mValue.mURL->Equals(*aOther.mValue.mURL);
     }
     else if (eCSSUnit_Image == mUnit) {
       return mValue.mImage->Equals(*aOther.mValue.mImage);
     }
     else if (eCSSUnit_Gradient == mUnit) {
       return *mValue.mGradient == *aOther.mValue.mGradient;
@@ -438,19 +431,16 @@ void nsCSSValue::DoReset()
   if (UnitHasStringValue()) {
     mValue.mString->Release();
   } else if (IsFloatColorUnit()) {
     DO_RELEASE(mFloatColor);
   } else if (eCSSUnit_ComplexColor == mUnit) {
     DO_RELEASE(mComplexColor);
   } else if (UnitHasArrayValue()) {
     DO_RELEASE(mArray);
-  } else if (UnitHasThreadSafeArrayValue()) {
-    // ThreadSafe arrays are ok to release on any thread.
-    mValue.mThreadSafeArray->Release();
   } else if (eCSSUnit_URL == mUnit) {
     DO_RELEASE(mURL);
   } else if (eCSSUnit_Image == mUnit) {
     DO_RELEASE(mImage);
   } else if (eCSSUnit_Gradient == mUnit) {
     DO_RELEASE(mGradient);
   } else if (eCSSUnit_TokenStream == mUnit) {
     DO_RELEASE(mTokenStream);
@@ -576,25 +566,16 @@ void nsCSSValue::SetArrayValue(nsCSSValu
 {
   Reset();
   mUnit = aUnit;
   MOZ_ASSERT(UnitHasArrayValue(), "bad unit");
   mValue.mArray = aValue;
   mValue.mArray->AddRef();
 }
 
-void nsCSSValue::SetThreadSafeArrayValue(nsCSSValue::ThreadSafeArray* aValue, nsCSSUnit aUnit)
-{
-  Reset();
-  mUnit = aUnit;
-  MOZ_ASSERT(UnitHasThreadSafeArrayValue(), "bad unit");
-  mValue.mThreadSafeArray = aValue;
-  mValue.mThreadSafeArray->AddRef();
-}
-
 void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue)
 {
   Reset();
   mUnit = eCSSUnit_URL;
   mValue.mURL = aValue;
   mValue.mURL->AddRef();
 }
 
@@ -1353,39 +1334,20 @@ nsCSSValue::AppendToString(nsCSSProperty
     nsAutoString  buffer;
     GetStringValue(buffer);
     if (unit == eCSSUnit_String) {
       nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
     } else {
       nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
     }
   }
-  else if (eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) {
+  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Symbols) {
     switch (unit) {
       case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
       case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
-      default: MOZ_ASSERT_UNREACHABLE("bad enum");
-    }
-
-    nsCSSValue::ThreadSafeArray *array = GetThreadSafeArrayValue();
-    bool mark = false;
-    for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
-      if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
-        aResult.AppendLiteral(", ");
-      }
-      nsCSSPropertyID prop = (i == array->Count() - 1)
-        ? eCSSProperty_list_style_type : aProperty;
-      if (array->Item(i).GetUnit() != eCSSUnit_Null) {
-        array->Item(i).AppendToString(prop, aResult, aSerialization);
-        mark = true;
-      }
-    }
-  }
-  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Symbols) {
-    switch (unit) {
       case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
       case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
       case eCSSUnit_Symbols: aResult.AppendLiteral("symbols("); break;
       default: break;
     }
 
     nsCSSValue::Array *array = GetArrayValue();
     bool mark = false;
@@ -1419,17 +1381,20 @@ nsCSSValue::AppendToString(nsCSSProperty
         int32_t system = array->Item(i).GetIntValue();
         if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
           AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
                   system, nsCSSProps::kCounterSystemKTable), aResult);
           mark = true;
         }
         continue;
       }
-      nsCSSPropertyID prop = aProperty;
+      nsCSSPropertyID prop =
+        ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
+         i == array->Count() - 1)
+        ? eCSSProperty_list_style_type : aProperty;
       if (array->Item(i).GetUnit() != eCSSUnit_Null) {
         array->Item(i).AppendToString(prop, aResult, aSerialization);
         mark = true;
       }
     }
     if (eCSSUnit_Array == unit &&
         aProperty == eCSSProperty_transition_timing_function) {
       aResult.Append(')');
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -438,19 +438,19 @@ enum nsCSSUnit {
 
   eCSSUnit_String       = 11,     // (char16_t*) a string value
   eCSSUnit_Ident        = 12,     // (char16_t*) a string value
   eCSSUnit_Attr         = 14,     // (char16_t*) a attr(string) value
   eCSSUnit_Local_Font   = 15,     // (char16_t*) a local font name
   eCSSUnit_Font_Format  = 16,     // (char16_t*) a font format name
   eCSSUnit_Element      = 17,     // (char16_t*) an element id
 
-  eCSSUnit_Counter      = 20,     // (nsCSSValue::ThreadSafeArray*) a counter(string,[string]) value
-  eCSSUnit_Counters     = 21,     // (nsCSSValue::ThreadSafeArray*) a counters(string,string[,string]) value
-  eCSSUnit_Array        = 22,     // (nsCSSValue::Array*) a list of values
+  eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
+  eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
+  eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
   eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
   eCSSUnit_Steps        = 24,     // (nsCSSValue::Array*) a list of (integer, enumerated)
   eCSSUnit_Symbols      = 25,     // (nsCSSValue::Array*) a symbols(enumerated, symbols) value
   eCSSUnit_Function     = 26,     // (nsCSSValue::Array*) a function with
                                   //  parameters.  First elem of array is name,
                                   //  an nsCSSKeyword as eCSSUnit_Enumerated,
                                   //  the rest of the values are arguments.
 
@@ -577,18 +577,16 @@ struct nsCSSValuePairList_heap;
 struct nsCSSValueTriplet;
 struct nsCSSValueTriplet_heap;
 class nsCSSValueFloatColor;
 
 class nsCSSValue {
 public:
   struct Array;
   friend struct Array;
-  struct ThreadSafeArray;
-  friend struct ThreadSafeArray;
 
   friend struct mozilla::css::URLValueData;
 
   friend struct mozilla::css::ImageValue;
 
   // for valueless units only (null, auto, inherit, none, all, normal)
   explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
     : mUnit(aUnit)
@@ -676,18 +674,16 @@ public:
     { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
   bool      IsTimeUnit() const  
     { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
   bool      IsCalcUnit() const
     { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
 
   bool      UnitHasStringValue() const
     { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
-  bool      UnitHasThreadSafeArrayValue() const
-    { return eCSSUnit_Counter <= mUnit && mUnit <= eCSSUnit_Counters; }
   bool      UnitHasArrayValue() const
     { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
 
   // Checks for the nsCSSValue being of a particular type of color unit:
   //
   //   - IsIntegerColorUnit returns true for:
   //       eCSSUnit_RGBColor             -- rgb(int,int,int)
   //       eCSSUnit_RGBAColor            -- rgba(int,int,int,float)
@@ -782,22 +778,16 @@ public:
   }
 
   Array* GetArrayValue() const
   {
     MOZ_ASSERT(UnitHasArrayValue(), "not an array value");
     return mValue.mArray;
   }
 
-  ThreadSafeArray* GetThreadSafeArrayValue() const
-  {
-    MOZ_ASSERT(UnitHasThreadSafeArrayValue(), "not a threadsafe array value");
-    return mValue.mThreadSafeArray;
-  }
-
   nsIURI* GetURLValue() const
   {
     MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
                "not a URL value");
     return mUnit == eCSSUnit_URL ?
       mValue.mURL->GetURI() : mValue.mImage->GetURI();
   }
 
@@ -927,17 +917,16 @@ public:
   void SetFloatColorValue(float aComponent1,
                           float aComponent2,
                           float aComponent3,
                           float aAlpha, nsCSSUnit aUnit);
   void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue);
   void SetComplexColorValue(
     already_AddRefed<mozilla::css::ComplexColorValue> aValue);
   void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
-  void SetThreadSafeArrayValue(nsCSSValue::ThreadSafeArray* aArray, nsCSSUnit aUnit);
   void SetURLValue(mozilla::css::URLValue* aURI);
   void SetImageValue(mozilla::css::ImageValue* aImage);
   void SetGradientValue(nsCSSValueGradient* aGradient);
   void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
   void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
   void SetFontFamilyListValue(mozilla::css::FontFamilyListRefCnt* aFontListValue);
   void SetPairValue(const nsCSSValuePair* aPair);
   void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
@@ -1028,17 +1017,16 @@ protected:
     int32_t    mInt;
     float      mFloat;
     // Note: the capacity of the buffer may exceed the length of the string.
     // If we're of a string type, mString is not null.
     nsStringBuffer* MOZ_OWNING_REF mString;
     nscolor    mColor;
     nsIAtom* MOZ_OWNING_REF mAtom;
     Array* MOZ_OWNING_REF mArray;
-    ThreadSafeArray* MOZ_OWNING_REF mThreadSafeArray;
     mozilla::css::URLValue* MOZ_OWNING_REF mURL;
     mozilla::css::ImageValue* MOZ_OWNING_REF mImage;
     mozilla::css::GridTemplateAreasValue* MOZ_OWNING_REF mGridTemplateAreas;
     nsCSSValueGradient* MOZ_OWNING_REF mGradient;
     nsCSSValueTokenStream* MOZ_OWNING_REF mTokenStream;
     nsCSSValuePair_heap* MOZ_OWNING_REF mPair;
     nsCSSRect_heap* MOZ_OWNING_REF mRect;
     nsCSSValueTriplet_heap* MOZ_OWNING_REF mTriplet;
@@ -1048,19 +1036,16 @@ protected:
     nsCSSValuePairList_heap* MOZ_OWNING_REF mPairList;
     nsCSSValuePairList* mPairListDependent;
     nsCSSValueFloatColor* MOZ_OWNING_REF mFloatColor;
     mozilla::css::FontFamilyListRefCnt* MOZ_OWNING_REF mFontFamilyList;
     mozilla::css::ComplexColorValue* MOZ_OWNING_REF mComplexColor;
   } mValue;
 };
 
-// We use this macro to declare equivalent logic for Array and ThreadSafeArray.
-// It would be much nicer to use a superclass, but the dynamically-sized nature
-// of the interesting part of the class makes that tricky.
 #define DECLARE_CSS_ARRAY(className, refcntMacro)                             \
 struct nsCSSValue::className final {                                          \
                                                                               \
   /* return this class with reference count of zero */                        \
   static className* Create(size_t aItemCount) {                               \
     return new (aItemCount) className(aItemCount);                            \
   }                                                                           \
                                                                               \
@@ -1143,17 +1128,16 @@ private:                                
   }                                                                           \
                                                                               \
 private:                                                                      \
   className(const className& aOther) = delete;                                \
   className& operator=(const className& aOther) = delete;                     \
 };
 
 DECLARE_CSS_ARRAY(Array, NS_INLINE_DECL_REFCOUNTING)
-DECLARE_CSS_ARRAY(ThreadSafeArray, NS_INLINE_DECL_THREADSAFE_REFCOUNTING)
 #undef DECLARE_CSS_ARRAY
 
 // Prefer nsCSSValue::Array for lists of fixed size.
 struct nsCSSValueList {
   nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
   ~nsCSSValueList();
 
   nsCSSValueList* Clone() const;  // makes a deep copy. Infallible.
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1310,17 +1310,17 @@ nsComputedDOMStyle::DoGetContent()
         nsAutoString str;
         if (type == eStyleContentType_Counter) {
           str.AppendLiteral("counter(");
         }
         else {
           str.AppendLiteral("counters(");
         }
         // WRITE ME
-        nsCSSValue::ThreadSafeArray* a = data.GetCounters();
+        nsCSSValue::Array* a = data.GetCounters();
 
         nsStyleUtil::AppendEscapedCSSIdent(
           nsDependentString(a->Item(0).GetStringBufferValue()), str);
         int32_t typeItem = 1;
         if (type == eStyleContentType_Counters) {
           typeItem = 2;
           str.AppendLiteral(", ");
           nsStyleUtil::AppendEscapedCSSString(
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9029,17 +9029,17 @@ nsRuleNode::ComputeContentData(void* aSt
           data.SetString(type, buffer.get());
           break;
         }
         case eCSSUnit_Counter:
         case eCSSUnit_Counters: {
           nsStyleContentType type =
             unit == eCSSUnit_Counter ? eStyleContentType_Counter
                                      : eStyleContentType_Counters;
-          data.SetCounters(type, value.GetThreadSafeArrayValue());
+          data.SetCounters(type, value.GetArrayValue());
           break;
         }
         case eCSSUnit_Enumerated:
           switch (value.GetIntValue()) {
             case NS_STYLE_CONTENT_OPEN_QUOTE:
               data.SetKeyword(eStyleContentType_OpenQuote);
               break;
             case NS_STYLE_CONTENT_CLOSE_QUOTE:
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3035,17 +3035,17 @@ public:
 
   char16_t* GetString() const
   {
     MOZ_ASSERT(mType == eStyleContentType_String ||
                mType == eStyleContentType_Attr);
     return mContent.mString;
   }
 
-  nsCSSValue::ThreadSafeArray* GetCounters() const
+  nsCSSValue::Array* GetCounters() const
   {
     MOZ_ASSERT(mType == eStyleContentType_Counter ||
                mType == eStyleContentType_Counters);
     return mContent.mCounters;
   }
 
   nsStyleImageRequest* GetImageRequest() const
   {
@@ -3076,17 +3076,17 @@ public:
                aType == eStyleContentType_Attr);
     MOZ_ASSERT(aString);
     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
                "should only initialize nsStyleContentData once");
     mType = aType;
     mContent.mString = NS_strdup(aString);
   }
 
-  void SetCounters(nsStyleContentType aType, nsCSSValue::ThreadSafeArray* aCounters)
+  void SetCounters(nsStyleContentType aType, nsCSSValue::Array* aCounters)
   {
     MOZ_ASSERT(aType == eStyleContentType_Counter ||
                aType == eStyleContentType_Counters);
     MOZ_ASSERT(aCounters);
     MOZ_ASSERT(aCounters->Count() == 2 || aCounters->Count() == 3);
     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
                "should only initialize nsStyleContentData once");
     mType = aType;
@@ -3109,19 +3109,17 @@ public:
     }
   }
 
 private:
   nsStyleContentType mType;
   union {
     char16_t *mString;
     nsStyleImageRequest* mImage;
-    // NB: We need threadsafe refcounts here to enable inheritance in the
-    // parallel style traversal.
-    nsCSSValue::ThreadSafeArray* mCounters;
+    nsCSSValue::Array* mCounters;
   } mContent;
 };
 
 struct nsStyleCounterData
 {
   nsString  mCounter;
   int32_t   mValue;