Bug 1221436 patch 4 - Use the same pointer to store the owning rule and the nsHTMLCSSStyleSheet on css::Declaration, since we never need both. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Mon, 09 Nov 2015 15:57:17 +0800
changeset 271739 b09af10d01282ddbc27a59f0417d62357ff69c84
parent 271738 2638966229a846861165805fe550fa332398d895
child 271740 0ffbb9175ac62505f0af2c0365e9325226d7bcc0
push id29650
push usercbook@mozilla.com
push dateMon, 09 Nov 2015 13:56:12 +0000
treeherdermozilla-central@e1ef2be156de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1221436
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 1221436 patch 4 - Use the same pointer to store the owning rule and the nsHTMLCSSStyleSheet on css::Declaration, since we never need both. r=heycam The pointer to nsHTMLCSSStyleSheet was added in patch 1 (which was needed before patch 2), but it was only patch 2 that created the invariant that we'd only have one pointer or the other, and never both. Thus this needs to be done separately, after patch 1.
layout/style/Declaration.cpp
layout/style/Declaration.h
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -40,38 +40,36 @@ ImportantStyleData::List(FILE* out, int3
   }
 
   str.AppendLiteral("! important rule\n");
   fprintf_stderr(out, "%s", str.get());
 }
 #endif
 
 Declaration::Declaration()
-  : mOwningRule(nullptr)
-  , mHTMLCSSStyleSheet(nullptr)
-  , mImmutable(false)
+  : mImmutable(false)
 {
+  mContainer.mRaw = uintptr_t(0);
 }
 
 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),
-    mHTMLCSSStyleSheet(nullptr),
     mImmutable(false)
 {
+  mContainer.mRaw = uintptr_t(0);
 }
 
 Declaration::~Declaration()
 {
 }
 
 NS_INTERFACE_MAP_BEGIN(Declaration)
   if (aIID.Equals(NS_GET_IID(mozilla::css::Declaration))) {
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -311,30 +311,45 @@ public:
     mImportantData = nullptr;
     mVariables = nullptr;
     mImportantVariables = nullptr;
     mOrder.Clear();
     mVariableOrder.Clear();
   }
 
   void SetOwningRule(Rule* aRule) {
-    MOZ_ASSERT(!mOwningRule || !aRule,
+    MOZ_ASSERT(!mContainer.mOwningRule || !aRule,
                "should never overwrite one rule with another");
-    mOwningRule = aRule;
+    mContainer.mOwningRule = aRule;
+  }
+
+  Rule* GetOwningRule() {
+    if (mContainer.mRaw & 0x1) {
+      return nullptr;
+    }
+    return mContainer.mOwningRule;
   }
 
-  Rule* GetOwningRule() { return mOwningRule; }
-
   void SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aHTMLCSSStyleSheet) {
-    MOZ_ASSERT(!mHTMLCSSStyleSheet || !aHTMLCSSStyleSheet,
+    MOZ_ASSERT(!mContainer.mHTMLCSSStyleSheet || !aHTMLCSSStyleSheet,
                "should never overwrite one sheet with another");
-    mHTMLCSSStyleSheet = aHTMLCSSStyleSheet;
+    mContainer.mHTMLCSSStyleSheet = aHTMLCSSStyleSheet;
+    if (aHTMLCSSStyleSheet) {
+      mContainer.mRaw |= uintptr_t(1);
+    }
   }
 
-  nsHTMLCSSStyleSheet* GetHTMLCSSStyleSheet() { return mHTMLCSSStyleSheet; }
+  nsHTMLCSSStyleSheet* GetHTMLCSSStyleSheet() {
+    if (!(mContainer.mRaw & 0x1)) {
+      return nullptr;
+    }
+    auto c = mContainer;
+    c.mRaw &= ~uintptr_t(1);
+    return c.mHTMLCSSStyleSheet;
+  }
 
   ImportantStyleData* GetImportantStyleData() {
     if (HasImportantData()) {
       return &mImportantStyleData;
     }
     return nullptr;
   }
 
@@ -408,22 +423,32 @@ 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;
+  union {
+    // We only ever have one of these since we have an
+    // nsHTMLCSSStyleSheet only for style attributes, and style
+    // attributes never have an owning rule.
+
+    // It's an nsHTMLCSSStyleSheet if the low bit is set.
 
-  // The nsHTMLCSSStyleSheet that is responsible for this declaration.
-  // Only non-null for style attributes.
-  nsHTMLCSSStyleSheet* mHTMLCSSStyleSheet;
+    uintptr_t mRaw;
+
+    // The style rule that owns this declaration.  May be null.
+    Rule* mOwningRule;
+
+    // The nsHTMLCSSStyleSheet that is responsible for this declaration.
+    // Only non-null for style attributes.
+    nsHTMLCSSStyleSheet* mHTMLCSSStyleSheet;
+  } mContainer;
 
   friend class ImportantStyleData;
   ImportantStyleData mImportantStyleData;
 
   // set when declaration put in the rule tree;
   // also by ToString (hence the 'mutable').
   mutable bool mImmutable;
 };