Bug 1449103 part 3 - Merge ServoGroupRuleRules into GroupRule. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Wed, 28 Mar 2018 12:25:36 +1100
changeset 773577 9185ddda18a671d3d10e677d9aae621fdd5ce6f7
parent 773576 7eb3b22f42fafcbea63316a35c5b60f331a7ea45
child 773579 990385558c3b8a251d3ecc50b43a10ec97e6c7b8
push id104251
push userxquan@mozilla.com
push dateWed, 28 Mar 2018 02:47:44 +0000
reviewersemilio
bugs1449103
milestone61.0a1
Bug 1449103 part 3 - Merge ServoGroupRuleRules into GroupRule. r?emilio MozReview-Commit-ID: 83rI7gydEUd
layout/style/GroupRule.cpp
layout/style/GroupRule.h
--- a/layout/style/GroupRule.cpp
+++ b/layout/style/GroupRule.cpp
@@ -13,76 +13,30 @@
 
 #include "mozilla/dom/CSSRuleList.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace css {
 
-#define CALL_INNER(inner_, call_)               \
-  ((inner_).is<DummyGroupRuleRules>()           \
-    ? (inner_).as<DummyGroupRuleRules>().call_  \
-    : (inner_).as<ServoGroupRuleRules>().call_)
-
-
-// -------------------------------
-// ServoGroupRuleRules
-//
-
-ServoGroupRuleRules::~ServoGroupRuleRules()
-{
-  if (mRuleList) {
-    mRuleList->DropReference();
-  }
-}
-
-#ifdef DEBUG
-void
-ServoGroupRuleRules::List(FILE* out, int32_t aIndent) const
-{
-  // TODO list something reasonable?
-}
-#endif
-
-size_t
-ServoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
-{
-  // TODO how to implement?
-  return 0;
-}
-
-// -------------------------------
-// GroupRule
-//
-
-GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-  : Rule(aLineNumber, aColumnNumber)
-  , mInner(DummyGroupRuleRules())
-{
-}
-
 GroupRule::GroupRule(already_AddRefed<ServoCssRules> aRules,
                      uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber)
-  , mInner(ServoGroupRuleRules(Move(aRules)))
+  , mRuleList(new ServoCSSRuleList(Move(aRules), nullptr))
 {
-  mInner.as<ServoGroupRuleRules>().SetParentRule(this);
-}
-
-GroupRule::GroupRule(const GroupRule& aCopy)
-  : Rule(aCopy)
-  , mInner(aCopy.mInner)
-{
-  CALL_INNER(mInner, SetParentRule(this));
+  mRuleList->SetParentRule(this);
 }
 
 GroupRule::~GroupRule()
 {
   MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called");
+  if (mRuleList) {
+    mRuleList->DropReference();
+  }
 }
 
 NS_IMPL_ADDREF_INHERITED(GroupRule, Rule)
 NS_IMPL_RELEASE_INHERITED(GroupRule, Rule)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule)
 NS_INTERFACE_MAP_END_INHERITING(Rule)
 
@@ -91,53 +45,59 @@ GroupRule::IsCCLeaf() const
 {
   // Let's not worry for now about sorting out whether we're a leaf or not.
   return false;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule)
-  CALL_INNER(tmp->mInner, SetParentRule(nullptr));
-  // If tmp does not have a stylesheet, neither do its descendants.  In that
-  // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
-  // depth of group rule nesting.  But if tmp _does_ have a stylesheet (which
-  // can happen if it gets unlinked earlier than its owning stylesheet), then we
-  // need to null out the stylesheet pointer on descendants now, before we clear
-  // tmp->mRules.
-  if (tmp->GetStyleSheet()) {
-    CALL_INNER(tmp->mInner, SetStyleSheet(nullptr));
+  if (tmp->mRuleList) {
+    tmp->mRuleList->SetParentRule(nullptr);
+    // If tmp does not have a stylesheet, neither do its descendants.
+    // In that case, don't try to null out their stylesheet, to avoid
+    // O(N^2) behavior in depth of group rule nesting.  But if tmp
+    // _does_ have a stylesheet (which can happen if it gets unlinked
+    // earlier than its owning stylesheet), then we need to null out the
+    // stylesheet pointer on descendants now, before we clear mRuleList.
+    if (tmp->GetStyleSheet()) {
+      tmp->mRuleList->SetStyleSheet(nullptr);
+    }
+    tmp->mRuleList->DropReference();
+    tmp->mRuleList = nullptr;
   }
-  CALL_INNER(tmp->mInner, Clear());
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule)
-  CALL_INNER(tmp->mInner, Traverse(cb));
+  ImplCycleCollectionTraverse(cb, tmp->mRuleList, "mRuleList");
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+#ifdef DEBUG
+void
+GroupRule::List(FILE* out, int32_t aIndent) const
+{
+  // TODO list something reasonable?
+}
+#endif
+
 /* virtual */ void
 GroupRule::SetStyleSheet(StyleSheet* aSheet)
 {
   // Don't set the sheet on the kids if it's already the same as the sheet we
   // already have.  This is needed to avoid O(N^2) behavior in group nesting
   // depth when seting the sheet to null during unlink, if we happen to unlin in
   // order from most nested rule up to least nested rule.
   if (aSheet != GetStyleSheet()) {
-    CALL_INNER(mInner, SetStyleSheet(aSheet));
+    if (mRuleList) {
+      mRuleList->SetStyleSheet(aSheet);
+    }
     Rule::SetStyleSheet(aSheet);
   }
 }
 
-
-CSSRuleList*
-GroupRule::CssRules()
-{
-  return CALL_INNER(mInner, CssRules(this));
-}
-
 uint32_t
 GroupRule::InsertRule(const nsAString& aRule, uint32_t aIndex, ErrorResult& aRv)
 {
   StyleSheet* sheet = GetStyleSheet();
   if (NS_WARN_IF(!sheet)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return 0;
   }
@@ -176,12 +136,17 @@ GroupRule::DeleteRule(uint32_t aIndex, E
   NS_ASSERTION(count <= INT32_MAX, "Too many style rules!");
 
   nsresult rv = sheet->DeleteRuleFromGroup(this, aIndex);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
-#undef CALL_INNER
+size_t
+GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO how to implement?
+  return 0;
+}
 
 } // namespace css
 } // namespace mozilla
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -11,181 +11,80 @@
 
 #ifndef mozilla_css_GroupRule_h__
 #define mozilla_css_GroupRule_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ServoCSSRuleList.h"
-#include "mozilla/Variant.h"
 #include "mozilla/css/Rule.h"
 #include "nsCycleCollectionParticipant.h"
 
-class nsPresContext;
-class nsMediaQueryResultCacheKey;
-
 namespace mozilla {
 
 class StyleSheet;
 
 namespace dom {
 class CSSRuleList;
 } // namespace dom
 
 namespace css {
 
-class GroupRule;
-class GroupRuleRuleList;
-
-
-struct ServoGroupRuleRules
-{
-  explicit ServoGroupRuleRules(already_AddRefed<ServoCssRules> aRawRules)
-    : mRuleList(new ServoCSSRuleList(Move(aRawRules), nullptr)) {}
-  ServoGroupRuleRules(ServoGroupRuleRules&& aOther)
-    : mRuleList(Move(aOther.mRuleList)) {}
-  ServoGroupRuleRules(const ServoGroupRuleRules& aCopy) {
-    // Do we ever clone Servo rules?
-    MOZ_ASSERT_UNREACHABLE("stylo: Cloning GroupRule not implemented");
-  }
-  ~ServoGroupRuleRules();
-
-  void SetParentRule(GroupRule* aParentRule) {
-    if (mRuleList) {
-      mRuleList->SetParentRule(aParentRule);
-    }
-  }
-  void SetStyleSheet(StyleSheet* aSheet) {
-    if (mRuleList) {
-      mRuleList->SetStyleSheet(aSheet);
-    }
-  }
-
-  void Clear() {
-    if (mRuleList) {
-      mRuleList->DropReference();
-      mRuleList = nullptr;
-    }
-  }
-  void Traverse(nsCycleCollectionTraversalCallback& cb) {
-    ImplCycleCollectionTraverse(cb, mRuleList, "mRuleList");
-  }
-
-#ifdef DEBUG
-  void List(FILE* out, int32_t aIndent) const;
-#endif
-
-  int32_t StyleRuleCount() const { return mRuleList->Length(); }
-  Rule* GetStyleRuleAt(int32_t aIndex) const {
-    return mRuleList->GetRule(aIndex);
-  }
-
-  nsresult DeleteStyleRuleAt(uint32_t aIndex) {
-    return mRuleList->DeleteRule(aIndex);
-  }
-
-  dom::CSSRuleList* CssRules(GroupRule* aParentRule) {
-    return mRuleList;
-  }
-
-  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
-
-  RefPtr<ServoCSSRuleList> mRuleList;
-};
-
-struct DummyGroupRuleRules
-{
-  void SetParentRule(GroupRule* aParentRule) {}
-  void SetStyleSheet(StyleSheet* aSheet) {}
-  void Clear() {}
-  void Traverse(nsCycleCollectionTraversalCallback& cb) {}
-#ifdef DEBUG
-  void List(FILE* out, int32_t aIndex) const {}
-#endif
-  int32_t StyleRuleCount() const { return 0; }
-  Rule* GetStyleRuleAt(int32_t aIndex) const { return nullptr; }
-  nsresult DeleteStyleRuleAt(uint32_t aIndex) { return NS_ERROR_NOT_IMPLEMENTED; }
-  dom::CSSRuleList* CssRules(GroupRule* aParentRule) { return nullptr; }
-  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { return 0; }
-};
-
-#define REDIRECT_TO_INNER(call_)                   \
-  if (mInner.is<DummyGroupRuleRules>()) {          \
-    return mInner.as<DummyGroupRuleRules>().call_; \
-  } else {                                         \
-    return mInner.as<ServoGroupRuleRules>().call_; \
-  }
-
 // inherits from Rule so it can be shared between
 // MediaRule and DocumentRule
 class GroupRule : public Rule
 {
 protected:
-  GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
   GroupRule(already_AddRefed<ServoCssRules> aRules,
             uint32_t aLineNumber, uint32_t aColumnNumber);
-  GroupRule(const GroupRule& aCopy);
+  GroupRule(const GroupRule& aCopy) = delete;
   virtual ~GroupRule();
 public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GroupRule, Rule)
   NS_DECL_ISUPPORTS_INHERITED
   virtual bool IsCCLeaf() const override;
 
 #ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const override {
-    REDIRECT_TO_INNER(List(out, aIndent))
-  }
+  void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual void SetStyleSheet(StyleSheet* aSheet) override;
 
 public:
 
-  int32_t StyleRuleCount() const {
-    REDIRECT_TO_INNER(StyleRuleCount())
-  }
-  Rule* GetStyleRuleAt(uint32_t aIndex) const {
-    REDIRECT_TO_INNER(GetStyleRuleAt(aIndex))
+  int32_t StyleRuleCount() const { return mRuleList->Length(); }
+
+  Rule* GetStyleRuleAt(int32_t aIndex) const {
+    return mRuleList->GetRule(aIndex);
   }
 
-
   /*
-   * The next two methods should never be called unless you have first
-   * called WillDirty() on the parent stylesheet.  After they are
-   * called, DidDirty() needs to be called on the sheet.
+   * The next method should never be called unless you have first called
+   * WillDirty() on the parent stylesheet. After it's called, DidDirty()
+   * needs to be called on the sheet.
    */
   nsresult DeleteStyleRuleAt(uint32_t aIndex) {
-    REDIRECT_TO_INNER(DeleteStyleRuleAt(aIndex));
+    return mRuleList->DeleteRule(aIndex);
   }
 
   // non-virtual -- it is only called by subclasses
-  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
-    REDIRECT_TO_INNER(SizeOfExcludingThis(aMallocSizeOf))
-  }
+  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override = 0;
 
   // WebIDL API
-  dom::CSSRuleList* CssRules();
+  dom::CSSRuleList* CssRules() { return mRuleList; }
   uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
                       ErrorResult& aRv);
   void DeleteRule(uint32_t aIndex, ErrorResult& aRv);
 
-protected:
-
 private:
-  // This only reason for the DummyGroupRuleRules is that ServoKeyframesRule
-  // inherits from CSSKeyframesRules (and thus GroupRule). Once
-  // ServoKeyframesRule can be made to inherit from Rule, the
-  // DummyGroupRuleRules can be removed.
-  Variant<DummyGroupRuleRules, ServoGroupRuleRules> mInner;
+  RefPtr<ServoCSSRuleList> mRuleList;
 };
 
-#undef REDIRECT_TO_INNER
-
 // Implementation of WebIDL CSSConditionRule.
 class ConditionRule : public GroupRule
 {
 protected:
   using GroupRule::GroupRule;
 
 public:
   virtual void GetConditionText(nsAString& aConditionText) = 0;