Bug 978833 patch 4 - Add pointer back from css::Declaration to css::Rule. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Thu, 05 Nov 2015 16:44:08 +0800
changeset 307303 4d51af920be6db324ef06f980bc7ba7520f7ea55
parent 307302 d04634d822423fcde66c7dc5a120de9e5e2be167
child 307304 3b535acc6b79600f26f60aaf6ab724573fb46c88
push id1040
push userraliiev@mozilla.com
push dateMon, 29 Feb 2016 17:11:22 +0000
treeherdermozilla-release@8c3167321162 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs978833
milestone45.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 978833 patch 4 - Add pointer back from css::Declaration to css::Rule. r=heycam This is used in patch 12, in nsStyleSet::AssertNoCSSRules and in inDOMUtils::GetCSSStyleRules.
layout/style/Declaration.cpp
layout/style/Declaration.h
layout/style/StyleRule.cpp
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -15,32 +15,34 @@
 #include "nsPrintfCString.h"
 #include "gfxFontConstants.h"
 #include "nsStyleUtil.h"
 
 namespace mozilla {
 namespace css {
 
 Declaration::Declaration()
-  : mImmutable(false)
+  : mOwningRule(nullptr)
+  , mImmutable(false)
 {
 }
 
 Declaration::Declaration(const Declaration& aCopy)
   : mOrder(aCopy.mOrder),
     mVariableOrder(aCopy.mVariableOrder),
     mData(aCopy.mData ? aCopy.mData->Clone() : nullptr),
     mImportantData(aCopy.mImportantData ?
                      aCopy.mImportantData->Clone() : nullptr),
     mVariables(aCopy.mVariables ?
         new CSSVariableDeclarations(*aCopy.mVariables) :
         nullptr),
     mImportantVariables(aCopy.mImportantVariables ?
         new CSSVariableDeclarations(*aCopy.mImportantVariables) :
         nullptr),
+    mOwningRule(nullptr),
     mImmutable(false)
 {
 }
 
 Declaration::~Declaration()
 {
 }
 
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -31,16 +31,18 @@
 // feec07b8-3fe6-491e-90d5-cc93f853e048
 #define NS_CSS_DECLARATION_IMPL_CID \
 { 0xfeec07b8, 0x3fe6, 0x491e, \
   { 0x90, 0xd5, 0xcc, 0x93, 0xf8, 0x53, 0xe0, 0x48 } }
 
 namespace mozilla {
 namespace css {
 
+class Rule;
+
 // Declaration objects have unusual lifetime rules.  Every declaration
 // begins life in an invalid state which ends when InitializeEmpty or
 // CompressFrom is called upon it.  After that, it can be attached to
 // exactly one style rule, and will be destroyed when that style rule
 // is destroyed.  A declaration becomes immutable when its style rule's
 // |RuleMatched| method is called; after that, it must be copied before
 // it can be modified, which is taken care of by |EnsureMutable|.
 
@@ -275,16 +277,24 @@ public:
     mData = nullptr;
     mImportantData = nullptr;
     mVariables = nullptr;
     mImportantVariables = nullptr;
     mOrder.Clear();
     mVariableOrder.Clear();
   }
 
+  void SetOwningRule(Rule* aRule) {
+    MOZ_ASSERT(!mOwningRule || !aRule,
+               "should never overwrite one rule with another");
+    mOwningRule = aRule;
+  }
+
+  Rule* GetOwningRule() { return mOwningRule; }
+
 private:
   Declaration& operator=(const Declaration& aCopy) = delete;
   bool operator==(const Declaration& aCopy) const = delete;
 
   void GetValue(nsCSSProperty aProperty, nsAString& aValue,
                 nsCSSValue::Serialization aValueSerialization) const;
 
   static void AppendImportanceToString(bool aIsImportant, nsAString& aString);
@@ -350,16 +360,19 @@ private:
   nsAutoPtr<nsCSSCompressedDataBlock> mImportantData;
 
   // may be null
   nsAutoPtr<CSSVariableDeclarations> mVariables;
 
   // may be null
   nsAutoPtr<CSSVariableDeclarations> mImportantVariables;
 
+  // The style rule that owns this declaration.  May be null.
+  Rule* mOwningRule;
+
   // set by style rules when |RuleMatched| is called;
   // also by ToString (hence the 'mutable').
   mutable bool mImmutable;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Declaration, NS_CSS_DECLARATION_IMPL_CID)
 
 } // namespace css
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -1415,24 +1415,27 @@ StyleRule::StyleRule(nsCSSSelectorList* 
                      Declaration* aDeclaration,
                      uint32_t aLineNumber,
                      uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber),
     mSelector(aSelector),
     mDeclaration(aDeclaration)
 {
   NS_PRECONDITION(aDeclaration, "must have a declaration");
+
+  mDeclaration->SetOwningRule(this);
 }
 
 // for |Clone|
 StyleRule::StyleRule(const StyleRule& aCopy)
   : Rule(aCopy),
     mSelector(aCopy.mSelector ? aCopy.mSelector->Clone() : nullptr),
     mDeclaration(new Declaration(*aCopy.mDeclaration))
 {
+  mDeclaration->SetOwningRule(this);
   // rest is constructed lazily on existing data
 }
 
 // for |SetCSSDeclaration|
 StyleRule::StyleRule(StyleRule& aCopy,
                      Declaration* aDeclaration)
   : Rule(aCopy),
     mSelector(aCopy.mSelector),
@@ -1447,25 +1450,32 @@ StyleRule::StyleRule(StyleRule& aCopy,
 
   // We are probably replacing the old declaration with |aDeclaration|
   // instead of taking ownership of the old declaration; only null out
   // aCopy.mDeclaration if we are taking ownership.
   if (mDeclaration == aCopy.mDeclaration) {
     // This should only ever happen if the declaration was modifiable.
     mDeclaration->AssertMutable();
     aCopy.mDeclaration = nullptr;
+    mDeclaration->SetOwningRule(nullptr);
   }
+
+  mDeclaration->SetOwningRule(this);
 }
 
 StyleRule::~StyleRule()
 {
   delete mSelector;
   if (mDOMRule) {
     mDOMRule->DOMDeclaration()->DropReference();
   }
+
+  if (mDeclaration) {
+    mDeclaration->SetOwningRule(nullptr);
+  }
 }
 
 // QueryInterface implementation for StyleRule
 NS_INTERFACE_MAP_BEGIN(StyleRule)
   if (aIID.Equals(NS_GET_IID(mozilla::css::StyleRule))) {
     *aInstancePtr = this;
     NS_ADDREF_THIS();
     return NS_OK;
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -2023,20 +2023,22 @@ nsCSSKeyframeStyleDeclaration::GetParent
 //
 
 nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy)
   // copy everything except our reference count and mDOMDeclaration
   : Rule(aCopy)
   , mKeys(aCopy.mKeys)
   , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
 {
+  mDeclaration->SetOwningRule(this);
 }
 
 nsCSSKeyframeRule::~nsCSSKeyframeRule()
 {
+  mDeclaration->SetOwningRule(nullptr);
   if (mDOMDeclaration) {
     mDOMDeclaration->DropReference();
   }
 }
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSKeyframeRule::Clone() const
 {
@@ -2221,17 +2223,19 @@ nsCSSKeyframeRule::ChangeDeclaration(css
 {
   // Our caller already did a BeginUpdate/EndUpdate, but with
   // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in
   // PresShell::EndUpdate.
   nsIDocument* doc = GetDocument();
   MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
 
   if (aDeclaration != mDeclaration) {
+    mDeclaration->SetOwningRule(nullptr);
     mDeclaration = aDeclaration;
+    mDeclaration->SetOwningRule(this);
   }
 
   CSSStyleSheet* sheet = GetStyleSheet();
   if (sheet) {
     sheet->SetModifiedByChildRule();
 
     if (doc) {
       doc->StyleRuleChanged(sheet, this, this);
@@ -2581,20 +2585,22 @@ nsCSSPageStyleDeclaration::GetParentObje
 // nsCSSPageRule
 //
 
 nsCSSPageRule::nsCSSPageRule(const nsCSSPageRule& aCopy)
   // copy everything except our reference count and mDOMDeclaration
   : Rule(aCopy)
   , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
 {
+  mDeclaration->SetOwningRule(this);
 }
 
 nsCSSPageRule::~nsCSSPageRule()
 {
+  mDeclaration->SetOwningRule(nullptr);
   if (mDOMDeclaration) {
     mDOMDeclaration->DropReference();
   }
 }
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSPageRule::Clone() const
 {
@@ -2723,17 +2729,19 @@ nsCSSPageRule::GetStyle(nsIDOMCSSStyleDe
   return NS_OK;
 }
 
 void
 nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
 {
   mImportantRule = nullptr;
   if (aDeclaration != mDeclaration) {
+    mDeclaration->SetOwningRule(nullptr);
     mDeclaration = aDeclaration;
+    mDeclaration->SetOwningRule(this);
   }
 
   CSSStyleSheet* sheet = GetStyleSheet();
   if (sheet) {
     sheet->SetModifiedByChildRule();
   }
 }
 
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -391,16 +391,17 @@ public:
   // WARNING: Steals the contents of aKeys
   nsCSSKeyframeRule(InfallibleTArray<float>& aKeys,
                     mozilla::css::Declaration* aDeclaration,
                     uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::Rule(aLineNumber, aColumnNumber)
     , mDeclaration(aDeclaration)
   {
     mKeys.SwapElements(aKeys);
+    mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSKeyframeRule, nsIStyleRule)
 
@@ -522,16 +523,17 @@ class nsCSSPageRule final : public mozil
 {
 public:
   nsCSSPageRule(mozilla::css::Declaration* aDeclaration,
                 uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::Rule(aLineNumber, aColumnNumber)
     , mDeclaration(aDeclaration)
     , mImportantRule(nullptr)
   {
+    mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSPageRule, nsIDOMCSSPageRule)