Bug 1275913 - Use already_addrefed properly when dealing with arcs sent from servo to gecko; r=bholley draft
authorManish Goregaokar <manishsmail@gmail.com>
Tue, 16 Aug 2016 10:38:46 +0530
changeset 401074 ab06acf5269c7bafced067b1d5721d47aa5eafa6
parent 400825 054d4856cea6150a6638e5daf7913713281af97d
child 401075 cd9dc4d37370f74231638a7a4f62dfb611215957
push id26352
push userbmo:manishearth@gmail.com
push dateTue, 16 Aug 2016 06:58:00 +0000
reviewersbholley
bugs1275913
milestone51.0a1
Bug 1275913 - Use already_addrefed properly when dealing with arcs sent from servo to gecko; r=bholley MozReview-Commit-ID: 5FDS8J2Fo1G
layout/base/ServoRestyleManager.cpp
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSheet.cpp
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -71,17 +71,17 @@ ServoRestyleManager::RecreateStyleContex
   if (!primaryFrame && !aContent->IsDirtyForServo()) {
     // This happens when, for example, a display: none child of a
     // HAS_DIRTY_DESCENDANTS content is reached as part of the traversal.
     return;
   }
 
   if (aContent->IsDirtyForServo()) {
     RefPtr<ServoComputedValues> computedValues =
-      dont_AddRef(Servo_GetComputedValues(aContent));
+      Servo_GetComputedValues(aContent).Consume();
     MOZ_ASSERT(computedValues);
 
     // NB: Change hint processing only applies to elements, at least until we
     // support display: contents.
     if (aContent->IsElement()) {
       nsChangeHint changeHint = nsChangeHint(0);
       Element* element = aContent->AsElement();
 
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -21,16 +21,27 @@
 #include "nsStyleStruct.h"
 #include "nsStyleUtil.h"
 #include "nsTArray.h"
 
 #include "mozilla/EventStates.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/dom/Element.h"
 
+#define IMPL_STRONG_REF_TYPE(name, T)           \
+  already_AddRefed<T> name::Consume() {         \
+    RefPtr<T> result = dont_AddRef(mPtr);       \
+    mPtr = nullptr;                             \
+    return result.forget();                     \
+  };
+
+
+IMPL_STRONG_REF_TYPE(ServoComputedValuesStrong, ServoComputedValues);
+IMPL_STRONG_REF_TYPE(RawServoStyleSheetStrong, RawServoStyleSheet);
+
 uint32_t
 Gecko_ChildrenCount(RawGeckoNode* aNode)
 {
   return aNode->GetChildCount();
 }
 
 bool
 Gecko_NodeIsElement(RawGeckoNode* aNode)
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -11,16 +11,22 @@
 #include "mozilla/css/SheetParsingMode.h"
 #include "nsChangeHint.h"
 #include "nsColor.h"
 #include "nsProxyRelease.h"
 #include "nsStyleCoord.h"
 #include "nsStyleStruct.h"
 #include "stdint.h"
 
+#define DEFINE_STRONG_REF_TYPE(name, T)                   \
+  struct MOZ_MUST_USE_TYPE name {                         \
+    T* mPtr;                                              \
+    already_AddRefed<T> Consume();                        \
+  }
+
 /*
  * API for Servo to access Gecko data structures. This file must compile as valid
  * C code in order for the binding generator to parse it.
  *
  * Functions beginning with Gecko_ are implemented in Gecko and invoked from Servo.
  * Functions beginning with Servo_ are implemented in Servo and invoked from Gecko.
  */
 
@@ -40,16 +46,18 @@ using mozilla::FontFamilyType;
 using mozilla::dom::Element;
 using mozilla::ServoElementSnapshot;
 typedef mozilla::dom::Element RawGeckoElement;
 class nsIDocument;
 typedef nsIDocument RawGeckoDocument;
 struct ServoNodeData;
 struct ServoComputedValues;
 struct RawServoStyleSheet;
+DEFINE_STRONG_REF_TYPE(ServoComputedValuesStrong, ServoComputedValues);
+DEFINE_STRONG_REF_TYPE(RawServoStyleSheetStrong, RawServoStyleSheet);
 struct RawServoStyleSet;
 class nsHTMLCSSStyleSheet;
 struct nsStyleList;
 struct nsStyleImage;
 struct nsStyleGradientStop;
 class nsStyleGradient;
 class nsStyleCoord;
 struct nsStyleDisplay;
@@ -216,17 +224,17 @@ void Gecko_ResetStyleCoord(nsStyleUnit* 
 void Gecko_SetStyleCoordCalcValue(nsStyleUnit* unit, nsStyleUnion* value, nsStyleCoord::CalcValue calc);
 
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
 
 // Styleset and Stylesheet management.
 //
 // TODO: Make these return already_AddRefed and UniquePtr when the binding
 // generator is smart enough to handle them.
-RawServoStyleSheet* Servo_StylesheetFromUTF8Bytes(
+RawServoStyleSheetStrong Servo_StylesheetFromUTF8Bytes(
     const uint8_t* bytes, uint32_t length,
     mozilla::css::SheetParsingMode parsing_mode,
     const uint8_t* base_bytes, uint32_t base_length,
     ThreadSafeURIHolder* base,
     ThreadSafeURIHolder* referrer,
     ThreadSafePrincipalHolder* principal);
 void Servo_AddRefStyleSheet(RawServoStyleSheet* sheet);
 void Servo_ReleaseStyleSheet(RawServoStyleSheet* sheet);
@@ -250,26 +258,26 @@ nsHTMLCSSStyleSheet* Servo_GetDeclaratio
 void Servo_SetDeclarationBlockImmutable(ServoDeclarationBlock* declarations);
 void Servo_ClearDeclarationBlockCachePointer(ServoDeclarationBlock* 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.
-ServoComputedValues* Servo_GetComputedValues(RawGeckoNode* node);
-ServoComputedValues* Servo_GetComputedValuesForAnonymousBox(ServoComputedValues* parentStyleOrNull,
+ServoComputedValuesStrong Servo_GetComputedValues(RawGeckoNode* node);
+ServoComputedValuesStrong Servo_GetComputedValuesForAnonymousBox(ServoComputedValues* parentStyleOrNull,
                                                             nsIAtom* pseudoTag,
                                                             RawServoStyleSet* set);
-ServoComputedValues* Servo_GetComputedValuesForPseudoElement(ServoComputedValues* parent_style,
+ServoComputedValuesStrong Servo_GetComputedValuesForPseudoElement(ServoComputedValues* parent_style,
                                                              RawGeckoElement* match_element,
                                                              nsIAtom* pseudo_tag,
                                                              RawServoStyleSet* set,
                                                              bool is_probe);
-ServoComputedValues* Servo_InheritComputedValues(ServoComputedValues* parent_style);
+ServoComputedValuesStrong Servo_InheritComputedValues(ServoComputedValues* parent_style);
 void Servo_AddRefComputedValues(ServoComputedValues*);
 void Servo_ReleaseComputedValues(ServoComputedValues*);
 
 // Initialize Servo components. Should be called exactly once at startup.
 void Servo_Initialize();
 
 // Shut down Servo components. Should be called exactly once at shutdown.
 void Servo_Shutdown();
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -91,17 +91,17 @@ ServoStyleSet::ResolveStyleFor(Element* 
 }
 
 already_AddRefed<nsStyleContext>
 ServoStyleSet::GetContext(nsIContent* aContent,
                           nsStyleContext* aParentContext,
                           nsIAtom* aPseudoTag,
                           CSSPseudoElementType aPseudoType)
 {
-  RefPtr<ServoComputedValues> computedValues = dont_AddRef(Servo_GetComputedValues(aContent));
+  RefPtr<ServoComputedValues> computedValues = Servo_GetComputedValues(aContent).Consume();
   MOZ_ASSERT(computedValues);
   return GetContext(computedValues.forget(), aParentContext, aPseudoTag, aPseudoType);
 }
 
 already_AddRefed<nsStyleContext>
 ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
                           nsStyleContext* aParentContext,
                           nsIAtom* aPseudoTag,
@@ -140,17 +140,17 @@ ServoStyleSet::ResolveStyleForText(nsICo
 
 already_AddRefed<nsStyleContext>
 ServoStyleSet::ResolveStyleForOtherNonElement(nsStyleContext* aParentContext)
 {
   // The parent context can be null if the non-element share a style context
   // with the root of an anonymous subtree.
   ServoComputedValues* parent =
     aParentContext ? aParentContext->StyleSource().AsServoComputedValues() : nullptr;
-  RefPtr<ServoComputedValues> computedValues = dont_AddRef(Servo_InheritComputedValues(parent));
+  RefPtr<ServoComputedValues> computedValues = Servo_InheritComputedValues(parent).Consume();
   MOZ_ASSERT(computedValues);
 
   return GetContext(computedValues.forget(), aParentContext,
                     nsCSSAnonBoxes::mozOtherNonElement,
                     CSSPseudoElementType::AnonBox);
 }
 
 already_AddRefed<nsStyleContext>
@@ -162,19 +162,19 @@ ServoStyleSet::ResolvePseudoElementStyle
   if (aPseudoElement) {
     NS_ERROR("stylo: We don't support CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE yet");
   }
   MOZ_ASSERT(aParentContext);
   MOZ_ASSERT(aType < CSSPseudoElementType::Count);
   nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
 
   RefPtr<ServoComputedValues> computedValues =
-    dont_AddRef(Servo_GetComputedValuesForPseudoElement(
+    Servo_GetComputedValuesForPseudoElement(
       aParentContext->StyleSource().AsServoComputedValues(),
-      aParentElement, pseudoTag, mRawSet.get(), /* is_probe = */ false));
+      aParentElement, pseudoTag, mRawSet.get(), /* is_probe = */ false).Consume();
   MOZ_ASSERT(computedValues);
 
   return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType);
 }
 
 // aFlags is an nsStyleSet flags bitfield
 already_AddRefed<nsStyleContext>
 ServoStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
@@ -186,18 +186,18 @@ ServoStyleSet::ResolveAnonymousBoxStyle(
   MOZ_ASSERT(aFlags == 0 ||
              aFlags == nsStyleSet::eSkipParentDisplayBasedStyleFixup);
   bool skipFixup = aFlags & nsStyleSet::eSkipParentDisplayBasedStyleFixup;
 
   ServoComputedValues* parentStyle =
     aParentContext ? aParentContext->StyleSource().AsServoComputedValues()
                    : nullptr;
   RefPtr<ServoComputedValues> computedValues =
-    dont_AddRef(Servo_GetComputedValuesForAnonymousBox(parentStyle, aPseudoTag,
-                                                       mRawSet.get()));
+    Servo_GetComputedValuesForAnonymousBox(parentStyle, aPseudoTag,
+                                                       mRawSet.get()).Consume();
 #ifdef DEBUG
   if (!computedValues) {
     nsString pseudo;
     aPseudoTag->ToString(pseudo);
     NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
              NS_ConvertUTF16toUTF8(pseudo).get()).get());
     MOZ_CRASH();
   }
@@ -357,19 +357,19 @@ ServoStyleSet::ProbePseudoElementStyle(E
                                        CSSPseudoElementType aType,
                                        nsStyleContext* aParentContext)
 {
   MOZ_ASSERT(aParentContext);
   MOZ_ASSERT(aType < CSSPseudoElementType::Count);
   nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
 
   RefPtr<ServoComputedValues> computedValues =
-    dont_AddRef(Servo_GetComputedValuesForPseudoElement(
+    Servo_GetComputedValuesForPseudoElement(
       aParentContext->StyleSource().AsServoComputedValues(),
-      aParentElement, pseudoTag, mRawSet.get(), /* is_probe = */ true));
+      aParentElement, pseudoTag, mRawSet.get(), /* is_probe = */ true).Consume();
 
   if (!computedValues) {
     return nullptr;
   }
 
   // For :before and :after pseudo-elements, having display: none or no
   // 'content' property is equivalent to not having the pseudo-element
   // at all.
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -81,21 +81,21 @@ ServoStyleSheet::ParseSheet(const nsAStr
   RefPtr<ThreadSafeURIHolder> referrer = new ThreadSafeURIHolder(aSheetURI);
   RefPtr<ThreadSafePrincipalHolder> principal =
     new ThreadSafePrincipalHolder(aSheetPrincipal);
 
   nsCString baseString;
   aBaseURI->GetSpec(baseString);
 
   NS_ConvertUTF16toUTF8 input(aInput);
-  mSheet = already_AddRefed<RawServoStyleSheet>(Servo_StylesheetFromUTF8Bytes(
+  mSheet = Servo_StylesheetFromUTF8Bytes(
       reinterpret_cast<const uint8_t*>(input.get()), input.Length(),
       mParsingMode,
       reinterpret_cast<const uint8_t*>(baseString.get()), baseString.Length(),
-      base, referrer, principal));
+      base, referrer, principal).Consume();
 }
 
 void
 ServoStyleSheet::DropSheet()
 {
   mSheet = nullptr;
 }