Bug 1296186 part 2 - Make ServoDeclarationBlock refcounted. r?heycam draft
authorXidorn Quan <xidorn+moz@upsuper.org>
Fri, 19 Aug 2016 16:08:25 +1000
changeset 403156 e0e0219478aa1afcaa7a81b048cddd706e9f6571
parent 403155 15ce8b6b435fe1f122d68ea2394eb8bbab7474c3
child 528835 901bc18b1f2c57d38f95f63d738bbfdf10a0549d
push id26836
push userxquan@mozilla.com
push dateFri, 19 Aug 2016 06:15:33 +0000
reviewersheycam
bugs1296186
milestone51.0a1
Bug 1296186 part 2 - Make ServoDeclarationBlock refcounted. r?heycam MozReview-Commit-ID: 2X0JX8HA4ej
dom/base/nsAttrValue.cpp
dom/base/nsAttrValue.h
layout/style/ServoBindingHelpers.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
--- a/dom/base/nsAttrValue.cpp
+++ b/dom/base/nsAttrValue.cpp
@@ -12,17 +12,17 @@
 #include "mozilla/DebugOnly.h"
 #include "mozilla/HashFunctions.h"
 
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "nsIAtom.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/ServoBindings.h"
+#include "mozilla/ServoBindingHelpers.h"
 #include "mozilla/css/Declaration.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "prprf.h"
 #include "nsHTMLCSSStyleSheet.h"
 #include "nsCSSParser.h"
 #include "nsStyledElement.h"
 #include "nsIURI.h"
@@ -458,22 +458,22 @@ nsAttrValue::SetTo(css::Declaration* aVa
   NS_ADDREF(cont->mValue.mGeckoCSSDeclaration = aValue);
   cont->mType = eGeckoCSSDeclaration;
   NS_ADDREF(cont);
   SetMiscAtomOrString(aSerialized);
   MOZ_ASSERT(cont->mValue.mRefCount == 1);
 }
 
 void
-nsAttrValue::SetTo(ServoDeclarationBlock* aValue,
+nsAttrValue::SetTo(already_AddRefed<ServoDeclarationBlock> aValue,
                    const nsAString* aSerialized)
 {
   MiscContainer* cont = EnsureEmptyMiscContainer();
   MOZ_ASSERT(cont->mValue.mRefCount == 0);
-  cont->mValue.mServoCSSDeclaration = aValue;
+  cont->mValue.mServoCSSDeclaration = aValue.take();
   cont->mType = eServoCSSDeclaration;
   NS_ADDREF(cont);
   SetMiscAtomOrString(aSerialized);
   MOZ_ASSERT(cont->mValue.mRefCount == 1);
 }
 
 void
 nsAttrValue::SetTo(css::URLValue* aValue, const nsAString* aSerialized)
@@ -1740,22 +1740,21 @@ nsAttrValue::ParseStyleAttribute(const n
       NS_ADDREF(cont);
       SetPtrValueAndType(cont, eOtherBase);
       return true;
     }
   }
 
   if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) {
     NS_ConvertUTF16toUTF8 value(aString);
-    ServoDeclarationBlock* decl = Servo_ParseStyleAttribute(
+    RefPtr<ServoDeclarationBlock> decl = Servo_ParseStyleAttribute(
         reinterpret_cast<const uint8_t*>(value.get()),
-        value.Length(),
-        sheet);
+        value.Length(), sheet).Consume();
     MOZ_ASSERT(decl);
-    SetTo(decl, &aString);
+    SetTo(decl.forget(), &aString);
   } else {
     css::Loader* cssLoader = ownerDoc->CSSLoader();
     nsCSSParser cssParser(cssLoader);
 
     RefPtr<css::Declaration> declaration =
       cssParser.ParseStyleAttribute(aString, docURI, baseURI,
                                     aElement->NodePrincipal());
     if (!declaration) {
@@ -1857,17 +1856,17 @@ nsAttrValue::ClearMiscContainer()
         case eServoCSSDeclaration:
         {
           MOZ_ASSERT(cont->mValue.mRefCount == 1);
           cont->Release();
           cont->Evict();
           if (cont->mType == eGeckoCSSDeclaration) {
             NS_RELEASE(cont->mValue.mGeckoCSSDeclaration);
           } else {
-            Servo_DropDeclarationBlock(cont->mValue.mServoCSSDeclaration);
+            Servo_DeclarationBlock_Release(cont->mValue.mServoCSSDeclaration);
           }
           break;
         }
         case eURL:
         {
           NS_RELEASE(cont->mValue.mURL);
           break;
         }
--- a/dom/base/nsAttrValue.h
+++ b/dom/base/nsAttrValue.h
@@ -143,17 +143,17 @@ public:
 
   void SetTo(const nsAttrValue& aOther);
   void SetTo(const nsAString& aValue);
   void SetTo(nsIAtom* aValue);
   void SetTo(int16_t aInt);
   void SetTo(int32_t aInt, const nsAString* aSerialized);
   void SetTo(double aValue, const nsAString* aSerialized);
   void SetTo(mozilla::css::Declaration* aValue, const nsAString* aSerialized);
-  void SetTo(ServoDeclarationBlock* aDeclarationBlock,
+  void SetTo(already_AddRefed<ServoDeclarationBlock> aDeclarationBlock,
              const nsAString* aSerialized);
   void SetTo(mozilla::css::URLValue* aValue, const nsAString* aSerialized);
   void SetTo(const nsIntMargin& aValue);
   void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized);
   void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized);
   void SetTo(const nsSVGLength2& aValue, const nsAString* aSerialized);
   void SetTo(const mozilla::SVGLengthList& aValue,
              const nsAString* aSerialized);
--- a/layout/style/ServoBindingHelpers.h
+++ b/layout/style/ServoBindingHelpers.h
@@ -40,11 +40,24 @@ class DefaultDelete<RawServoStyleSet>
 {
 public:
   void operator()(RawServoStyleSet* aPtr) const
   {
     Servo_DropStyleSet(aPtr);
   }
 };
 
+template<>
+struct RefPtrTraits<ServoDeclarationBlock>
+{
+  static void AddRef(ServoDeclarationBlock* aPtr)
+  {
+    Servo_DeclarationBlock_AddRef(aPtr);
+  }
+  static void Release(ServoDeclarationBlock* aPtr)
+  {
+    Servo_DeclarationBlock_Release(aPtr);
+  }
+};
+
 } // namespace mozilla
 
 #endif // mozilla_ServoBindingHelpers_h
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -31,16 +31,17 @@
   type_##Strong::Consume() {            \
     RefPtr<type_> result;               \
     result.swap(mPtr);                  \
     return result.forget();             \
   }
 
 IMPL_STRONG_REF_TYPE_FOR(ServoComputedValues)
 IMPL_STRONG_REF_TYPE_FOR(RawServoStyleSheet)
+IMPL_STRONG_REF_TYPE_FOR(ServoDeclarationBlock)
 
 #undef IMPL_STRONG_REF_TYPE_FOR
 
 uint32_t
 Gecko_ChildrenCount(RawGeckoNode* aNode)
 {
   return aNode->GetChildCount();
 }
@@ -853,47 +854,54 @@ Servo_InitStyleSet()
 
 void
 Servo_DropStyleSet(RawServoStyleSet* set)
 {
   MOZ_CRASH("stylo: shouldn't be calling Servo_DropStyleSet in a "
             "non-MOZ_STYLO build");
 }
 
-ServoDeclarationBlock*
+ServoDeclarationBlockStrong
 Servo_ParseStyleAttribute(const uint8_t* bytes, uint32_t length,
                           nsHTMLCSSStyleSheet* cache)
 {
   MOZ_CRASH("stylo: shouldn't be calling Servo_ParseStyleAttribute in a "
             "non-MOZ_STYLO build");
 }
 
 void
-Servo_DropDeclarationBlock(ServoDeclarationBlock* declarations)
+Servo_DeclarationBlock_AddRef(ServoDeclarationBlockBorrowed declarations)
 {
-  MOZ_CRASH("stylo: shouldn't be calling Servo_DropDeclarationBlock in a "
+  MOZ_CRASH("stylo: shouldn't be calling Servo_DeclarationBlock_AddRef in a "
+            "non-MOZ_STYLO build");
+}
+
+void
+Servo_DeclarationBlock_Release(ServoDeclarationBlockBorrowed declarations)
+{
+  MOZ_CRASH("stylo: shouldn't be calling Servo_DeclarationBlock_Release in a "
             "non-MOZ_STYLO build");
 }
 
 nsHTMLCSSStyleSheet*
-Servo_GetDeclarationBlockCache(ServoDeclarationBlock* declarations)
+Servo_GetDeclarationBlockCache(ServoDeclarationBlockBorrowed declarations)
 {
   MOZ_CRASH("stylo: shouldn't be calling Servo_GetDeclarationBlockCache in a "
             "non-MOZ_STYLO build");
 }
 
 void
-Servo_SetDeclarationBlockImmutable(ServoDeclarationBlock* declarations)
+Servo_SetDeclarationBlockImmutable(ServoDeclarationBlockBorrowed declarations)
 {
   MOZ_CRASH("stylo: shouldn't be calling Servo_SetDeclarationBlockImmutable in a "
             "non-MOZ_STYLO build");
 }
 
 void
-Servo_ClearDeclarationBlockCachePointer(ServoDeclarationBlock* declarations)
+Servo_ClearDeclarationBlockCachePointer(ServoDeclarationBlockBorrowed declarations)
 {
   MOZ_CRASH("stylo: shouldn't be calling Servo_ClearDeclarationBlockCachePointer in a "
             "non-MOZ_STYLO build");
 }
 
 bool
 Servo_CSSSupports(const uint8_t* name, uint32_t name_length,
                   const uint8_t* value, uint32_t value_length)
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -60,16 +60,17 @@ struct ServoDeclarationBlock;
   struct MOZ_MUST_USE_TYPE type_##Strong  \
   {                                       \
     type_* mPtr;                          \
     already_AddRefed<type_> Consume();    \
   };
 
 DECL_REF_TYPE_FOR(ServoComputedValues)
 DECL_REF_TYPE_FOR(RawServoStyleSheet)
+DECL_REF_TYPE_FOR(ServoDeclarationBlock)
 
 #undef DECL_REF_TYPE_FOR
 
 #define NS_DECL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
   void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr);                    \
   void Gecko_Release##name_##ArbitraryThread(class_* aPtr);
 #define NS_IMPL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
   static_assert(class_::HasThreadSafeRefCnt::value,                           \
@@ -140,17 +141,17 @@ nsIAtom* Gecko_GetElementId(RawGeckoElem
 
 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElement)
 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot,
                                               ServoElementSnapshot)
 
 #undef SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS
 
 // Style attributes.
-ServoDeclarationBlock* Gecko_GetServoDeclarationBlock(RawGeckoElement* element);
+ServoDeclarationBlockBorrowed Gecko_GetServoDeclarationBlock(RawGeckoElement* element);
 
 // Node data.
 ServoNodeData* Gecko_GetNodeData(RawGeckoNode* node);
 void Gecko_SetNodeData(RawGeckoNode* node, ServoNodeData* data);
 void Servo_DropNodeData(ServoNodeData* data);
 
 // Atoms.
 nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength);
@@ -249,24 +250,26 @@ void Servo_RemoveStyleSheet(RawServoStyl
 void Servo_InsertStyleSheetBefore(RawServoStyleSheetBorrowed sheet,
                                   RawServoStyleSheetBorrowed reference,
                                   RawServoStyleSet* set);
 bool Servo_StyleSheetHasRules(RawServoStyleSheetBorrowed sheet);
 RawServoStyleSet* Servo_InitStyleSet();
 void Servo_DropStyleSet(RawServoStyleSet* set);
 
 // Style attributes.
-ServoDeclarationBlock* Servo_ParseStyleAttribute(const uint8_t* bytes,
-                                                 uint32_t length,
-                                                 nsHTMLCSSStyleSheet* cache);
-void Servo_DropDeclarationBlock(ServoDeclarationBlock* declarations);
+ServoDeclarationBlockStrong Servo_ParseStyleAttribute(
+    const uint8_t* bytes, uint32_t length, nsHTMLCSSStyleSheet* cache);
+void Servo_DeclarationBlock_AddRef(ServoDeclarationBlockBorrowed declarations);
+void Servo_DeclarationBlock_Release(ServoDeclarationBlockBorrowed declarations);
 nsHTMLCSSStyleSheet* Servo_GetDeclarationBlockCache(
-    ServoDeclarationBlock* declarations);
-void Servo_SetDeclarationBlockImmutable(ServoDeclarationBlock* declarations);
-void Servo_ClearDeclarationBlockCachePointer(ServoDeclarationBlock* declarations);
+    ServoDeclarationBlockBorrowed declarations);
+void Servo_SetDeclarationBlockImmutable(
+    ServoDeclarationBlockBorrowed declarations);
+void Servo_ClearDeclarationBlockCachePointer(
+    ServoDeclarationBlockBorrowed declarations);
 
 // CSS supports().
 bool Servo_CSSSupports(const uint8_t* name, uint32_t name_length,
                        const uint8_t* value, uint32_t value_length);
 
 // Computed style data.
 ServoComputedValuesStrong Servo_GetComputedValues(RawGeckoNode* node);
 ServoComputedValuesStrong Servo_GetComputedValuesForAnonymousBox(ServoComputedValuesBorrowed parentStyleOrNull,