Bug 1385896: Move nsStyleContext::mParent to GeckoStyleContext. r=heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 31 Jul 2017 16:21:40 +0200
changeset 620466 d533990bd187368ec7647f931fb3ced206433f7e
parent 620465 4ae0f0904df38c8a10eb1d54d2277099cadf99bb
child 620532 82e09163b1b6be886a0cae447d7fa1eea9b7a604
push id72034
push userbmo:emilio+bugs@crisal.io
push dateThu, 03 Aug 2017 12:39:25 +0000
reviewersheycam
bugs1385896, 1368290
milestone57.0a1
Bug 1385896: Move nsStyleContext::mParent to GeckoStyleContext. r=heycam Unfortunately this means that we lose the NS_STYLE_INHERIT_BIT optimization to avoid posting changes if we had not requested the struct. In practice, I'm not sure this optimization matters much, though, and we already compare all the structs anyway. We _could_ keep a weak parent pointer from the text style if needed, given we're going to keep alive the text style at least until the parent style context goes away, so should be safe, but I don't think the extra churn is worth it, to be honest. Happy to do so as part of bug 1368290 if you think it's worth it. MozReview-Commit-ID: ka6tNwf4Ke
layout/style/GeckoStyleContext.cpp
layout/style/GeckoStyleContext.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/ServoStyleContext.cpp
layout/style/ServoStyleContext.h
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleContextInlines.h
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -31,22 +31,23 @@ GeckoStyleContext::Initialize()
 }
 #endif
 
 GeckoStyleContext::GeckoStyleContext(GeckoStyleContext* aParent,
                                      nsIAtom* aPseudoTag,
                                      CSSPseudoElementType aPseudoType,
                                      already_AddRefed<nsRuleNode> aRuleNode,
                                      bool aSkipParentDisplayBasedStyleFixup)
-  : nsStyleContext(aParent, aPseudoTag, aPseudoType)
+  : nsStyleContext(aPseudoTag, aPseudoType)
   , mCachedResetData(nullptr)
   , mRefCnt(0)
   , mChild(nullptr)
   , mEmptyChild(nullptr)
   , mRuleNode(Move(aRuleNode))
+  , mParent(aParent)
 #ifdef DEBUG
   , mComputingStruct(nsStyleStructID_None)
 #endif
 {
   mBits |= NS_STYLE_CONTEXT_IS_GECKO;
 
   if (aParent) {
 #ifdef DEBUG
@@ -626,25 +627,31 @@ ShouldSuppressLineBreak(const nsStyleCon
       // non-anonymous frame outside, we should also check them.
       aDisplay->mDisplay == mozilla::StyleDisplay::RubyBase ||
       aDisplay->mDisplay == mozilla::StyleDisplay::RubyText) {
     return true;
   }
   return false;
 }
 
-// FIXME(emilio): Why in GeckoStyleContext.cpp?
 void
-nsStyleContext::SetStyleBits()
+GeckoStyleContext::FinishConstruction()
 {
-  // Here we set up various style bits for both the Gecko and Servo paths.
-  // _Only_ change the bits here.  For fixups of the computed values, you can
-  // add to ApplyStyleFixups in Gecko and StyleAdjuster as part of Servo's
-  // cascade.
+  MOZ_ASSERT(RuleNode());
+
+  if (mParent) {
+    mParent->AddChild(this);
+  }
 
+  SetStyleBits();
+}
+
+void
+GeckoStyleContext::SetStyleBits()
+{
   if ((mParent && mParent->HasPseudoElementData()) || IsPseudoElement()) {
     AddStyleBit(NS_STYLE_HAS_PSEUDO_ELEMENT_DATA);
   }
 
   // Set the NS_STYLE_IN_DISPLAY_NONE_SUBTREE bit
   const nsStyleDisplay* disp = StyleDisplay();
   if ((mParent && mParent->IsInDisplayNoneSubtree()) ||
       disp->mDisplay == mozilla::StyleDisplay::None) {
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -32,19 +32,17 @@ public:
 
   nsPresContext* PresContext() const {
     return RuleNode()->PresContext();
   }
 
   void AddChild(GeckoStyleContext* aChild);
   void RemoveChild(GeckoStyleContext* aChild);
 
-  GeckoStyleContext* GetParent() const {
-    return mParent ? mParent->AsGecko() : nullptr;
-  }
+  GeckoStyleContext* GetParent() const { return mParent; }
 
   bool IsLinkContext() const {
     return GetStyleIfVisited() &&
            GetStyleIfVisited()->GetParent() == GetParent();
   }
 
   /**
    * Moves this style context to a new parent.
@@ -242,29 +240,33 @@ public:
   void AssertStructsNotUsedElsewhere(GeckoStyleContext* aDestroyingContext,
                                      int32_t aLevels) const;
 #endif
 
 private:
   // Helper for ClearCachedInheritedStyleDataOnDescendants.
   void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
   void Destroy();
+  void SetStyleBits();
+  void FinishConstruction();
 
   // Children are kept in two circularly-linked lists.  The list anchor
   // is not part of the list (null for empty), and we point to the first
   // child.
   // mEmptyChild for children whose rule node is the root rule node, and
   // mChild for other children.  The order of children is not
   // meaningful.
   GeckoStyleContext* mChild;
   GeckoStyleContext* mEmptyChild;
   GeckoStyleContext* mPrevSibling;
   GeckoStyleContext* mNextSibling;
   RefPtr<nsRuleNode> mRuleNode;
 
+  RefPtr<GeckoStyleContext> mParent;
+
   // Style to be used instead for the R, G, and B components of color,
   // background-color, and border-*-color if the nearest ancestor link
   // element is visited (see RelevantLinkVisited()).
   RefPtr<GeckoStyleContext> mStyleIfVisited;
 
 #ifdef DEBUG
 public:
   struct AutoCheckDependency {
@@ -281,17 +283,16 @@ public:
                  "Undeclared dependency, see generate-stylestructlist.py");
       aContext->mComputingStruct = aInnerSID;
     }
 
     ~AutoCheckDependency()
     {
       mStyleContext->mComputingStruct = mOuterSID;
     }
-
   };
 
 private:
   // Used to check for undeclared dependencies.
   // See AUTO_CHECK_DEPENDENCY in nsStyleContextInlines.h.
   nsStyleStructID         mComputingStruct;
 
 #define AUTO_CHECK_DEPENDENCY(gecko_, sid_) \
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -211,23 +211,19 @@ void
 Gecko_ServoStyleContext_Init(
     ServoStyleContext* aContext,
     const ServoStyleContext* aParentContext,
     RawGeckoPresContextBorrowed aPresContext,
     const ServoComputedData* aValues,
     mozilla::CSSPseudoElementType aPseudoType,
     nsIAtom* aPseudoTag)
 {
-  // because it is within an Arc it is unsafe for the Rust side to ever
-  // carry around a mutable non opaque reference to the context, so we
-  // cast it here.
-  auto parent = const_cast<ServoStyleContext*>(aParentContext);
-  auto presContext = const_cast<nsPresContext*>(aPresContext);
+  auto* presContext = const_cast<nsPresContext*>(aPresContext);
   new (KnownNotNull, aContext) ServoStyleContext(
-      parent, presContext, aPseudoTag, aPseudoType,
+      presContext, aPseudoTag, aPseudoType,
       ServoComputedDataForgotten(aValues));
 }
 
 ServoComputedData::ServoComputedData(
     const ServoComputedDataForgotten aValue)
 {
   PodAssign(this, aValue.mPtr);
 }
@@ -2657,22 +2653,16 @@ Gecko_CopyConstruct_nsStyle##name(nsStyl
                                                                               \
 void                                                                          \
 Gecko_Destroy_nsStyle##name(nsStyle##name* ptr)                               \
 {                                                                             \
   ptr->~nsStyle##name();                                                      \
 }
 
 void
-Gecko_Construct_nsStyleVariables(nsStyleVariables* ptr)
-{
-  new (ptr) nsStyleVariables();
-}
-
-void
 Gecko_RegisterProfilerThread(const char* name)
 {
   char stackTop;
   profiler_register_thread(name, &stackTop);
 }
 
 void
 Gecko_UnregisterProfilerThread()
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -650,18 +650,16 @@ int32_t Gecko_RegisterNamespace(nsIAtom*
     nsStyle##name* ptr,                                                        \
     RawGeckoPresContextBorrowed pres_context);                                 \
   void Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr,                   \
                                          const nsStyle##name* other);          \
   void Gecko_Destroy_nsStyle##name(nsStyle##name* ptr);
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
 
-void Gecko_Construct_nsStyleVariables(nsStyleVariables* ptr);
-
 void Gecko_RegisterProfilerThread(const char* name);
 void Gecko_UnregisterProfilerThread();
 
 bool Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed,
                                            const nsACString* aPattern,
                                            mozilla::css::URLMatchingFunction aURLMatchingFunction);
 
 // Allocator hinting.
--- a/layout/style/ServoStyleContext.cpp
+++ b/layout/style/ServoStyleContext.cpp
@@ -11,25 +11,24 @@
 #include "nsCSSRuleProcessor.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 
 #include "mozilla/ServoBindings.h"
 
 namespace mozilla {
 
 ServoStyleContext::ServoStyleContext(
-    nsStyleContext* aParent,
     nsPresContext* aPresContext,
     nsIAtom* aPseudoTag,
     CSSPseudoElementType aPseudoType,
     ServoComputedDataForgotten aComputedValues)
-  : nsStyleContext(aParent, aPseudoTag, aPseudoType)
+  : nsStyleContext(aPseudoTag, aPseudoType)
   , mPresContext(aPresContext)
   , mSource(aComputedValues)
 {
   AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
-  FinishConstruction();
+  MOZ_ASSERT(ComputedData());
 
   // No need to call ApplyStyleFixups here, since fixups are handled by Servo when
   // producing the ServoComputedData.
 }
 
 } // namespace mozilla
--- a/layout/style/ServoStyleContext.h
+++ b/layout/style/ServoStyleContext.h
@@ -13,18 +13,17 @@ namespace mozilla {
 
 namespace dom {
 class Element;
 } // namespace dom
 
 class ServoStyleContext final : public nsStyleContext
 {
 public:
-  ServoStyleContext(nsStyleContext* aParent,
-                    nsPresContext* aPresContext,
+  ServoStyleContext(nsPresContext* aPresContext,
                     nsIAtom* aPseudoTag,
                     CSSPseudoElementType aPseudoType,
                     ServoComputedDataForgotten aComputedValues);
 
   nsPresContext* PresContext() const { return mPresContext; }
   const ServoComputedData* ComputedData() const { return &mSource; }
 
   void AddRef() { Servo_StyleContext_AddRef(this); }
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -73,73 +73,41 @@ const uint32_t nsStyleContext::sDependen
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
 #undef STYLE_STRUCT_DEP
 #undef STYLE_STRUCT_END
 };
 
 #endif
 
-nsStyleContext::nsStyleContext(nsStyleContext* aParent,
-                               nsIAtom* aPseudoTag,
+nsStyleContext::nsStyleContext(nsIAtom* aPseudoTag,
                                CSSPseudoElementType aPseudoType)
-  : mParent(aParent)
-  , mPseudoTag(aPseudoTag)
+  : mPseudoTag(aPseudoTag)
   , mBits(((uint64_t)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT)
 #ifdef DEBUG
   , mFrameRefCnt(0)
 #endif
-{}
-
-void
-nsStyleContext::AddChild(nsStyleContext* aChild)
-{
-  if (auto gecko = GetAsGecko())
-    gecko->AddChild(aChild->AsGecko());
-}
-
-void
-nsStyleContext::RemoveChild(nsStyleContext* aChild)
-{
-  if (auto gecko = GetAsGecko())
-    gecko->RemoveChild(aChild->AsGecko());
-}
-
-void
-nsStyleContext::FinishConstruction()
 {
   // This check has to be done "backward", because if it were written the
   // more natural way it wouldn't fail even when it needed to.
   static_assert((UINT64_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >=
                  static_cast<CSSPseudoElementTypeBase>(
                    CSSPseudoElementType::MAX),
                 "pseudo element bits no longer fit in a uint64_t");
 
+#define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
+  static_assert(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
+                "NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
+#undef eStyleStruct_LastItem
+
 #ifdef DEBUG
-  if (auto servo = GetAsServo()) {
-    MOZ_ASSERT(servo->ComputedData());
-  } else {
-    MOZ_ASSERT(RuleNode());
-  }
-
   static_assert(MOZ_ARRAY_LENGTH(nsStyleContext::sDependencyTable)
                   == nsStyleStructID_Length,
                 "Number of items in dependency table doesn't match IDs");
 #endif
-
-  if (mParent) {
-    mParent->AddChild(this);
-  }
-
-  SetStyleBits();
-
-  #define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
-  static_assert(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
-                "NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
-  #undef eStyleStruct_LastItem
 }
 
 nsChangeHint
 nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
                                     uint32_t* aEqualStructs,
                                     uint32_t* aSamePointerStructs,
                                     uint32_t aRelevantStructs)
 {
@@ -151,16 +119,17 @@ nsStyleContext::CalcStyleDifference(nsSt
   MOZ_ASSERT(aRelevantStructs == kAllResolvedStructs || IsServo(),
              "aRelevantStructs must be kAllResolvedStructs for Gecko contexts");
 
   if (aRelevantStructs == kAllResolvedStructs) {
     aRelevantStructs = mBits & NS_STYLE_INHERIT_MASK;
   }
 
   *aEqualStructs = 0;
+  *aSamePointerStructs = 0;
 
   nsChangeHint hint = nsChangeHint(0);
   NS_ENSURE_TRUE(aNewContext, hint);
   // We must always ensure that we populate the structs on the new style
   // context that are filled in on the old context, so that if we get
   // two style changes in succession, the second of which causes a real
   // style change, the PeekStyleData doesn't return null (implying that
   // nobody ever looked at that struct's data).  In other words, we
@@ -177,17 +146,20 @@ nsStyleContext::CalcStyleDifference(nsSt
 
     // FIXME(heycam): We should just do the comparison in
     // nsStyleVariables::CalcDifference, returning NeutralChange if there are
     // any Variables differences.
     const nsStyleVariables* thisVariables = PeekStyleVariables();
     if (thisVariables) {
       structsFound |= NS_STYLE_INHERIT_BIT(Variables);
       const nsStyleVariables* otherVariables = aNewContext->StyleVariables();
-      if (thisVariables->mVariables == otherVariables->mVariables) {
+      if (thisVariables == otherVariables) {
+        *aSamePointerStructs |= NS_STYLE_INHERIT_BIT(Variables);
+        *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
+      } else if (thisVariables->mVariables == otherVariables->mVariables) {
         *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
       }
     } else {
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
     }
   } else {
     if (Servo_ComputedValues_EqualCustomProperties(
           AsServo()->ComputedData(),
@@ -196,59 +168,49 @@ nsStyleContext::CalcStyleDifference(nsSt
     }
   }
 
   DebugOnly<int> styleStructCount = 1;  // count Variables already
 
   // Servo's optimization to stop the cascade when there are no style changes
   // that children need to be recascade for relies on comparing all of the
   // structs, not just those that are returned from PeekStyleData, although
-  // if PeekStyleData does return null we still don't want to accumulate
-  // any change hints for those structs.
-  bool checkUnrequestedServoStructs = IsServo();
-
+  // if PeekStyleData does return null we could avoid to accumulate any change
+  // hints for those structs.
+  //
+  // FIXME(emilio): Reintroduce that optimization either for all kind of structs
+  // after bug 1368290 with a weak parent pointer from text, or just for reset
+  // structs.
+  //
   // For Gecko structs, we just defer to PeekStyleXXX.  But for Servo structs,
   // we need to use the aRelevantStructs bitfield passed in to determine
   // whether to return a struct or not, since this->mBits might not yet
   // be correct (due to not calling ResolveSameStructsAs on it yet).
 #define PEEK(struct_)                                                         \
   (IsGecko()                                                                  \
    ? PeekStyle##struct_()                                                     \
-   : ((aRelevantStructs & NS_STYLE_INHERIT_BIT(struct_))                      \
-      ? AsServo()->ComputedData()->GetStyle##struct_()                      \
-      : nullptr))
+   : AsServo()->ComputedData()->GetStyle##struct_())                          \
 
 #define EXPAND(...) __VA_ARGS__
 #define DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, extra_args_)                  \
   PR_BEGIN_MACRO                                                              \
     const nsStyle##struct_* this##struct_ = PEEK(struct_);                    \
-    bool unrequestedStruct;                                                   \
     if (this##struct_) {                                                      \
-      unrequestedStruct = false;                                              \
       structsFound |= NS_STYLE_INHERIT_BIT(struct_);                          \
-    } else if (checkUnrequestedServoStructs) {                                \
-      this##struct_ =                                                         \
-        AsServo()->ComputedData()->GetStyle##struct_();                     \
-      unrequestedStruct = true;                                               \
-    } else {                                                                  \
-      unrequestedStruct = false;                                              \
-    }                                                                         \
-    if (this##struct_) {                                                      \
+                                                                              \
       const nsStyle##struct_* other##struct_ =                                \
         aNewContext->ThreadsafeStyle##struct_();                              \
       if (this##struct_ == other##struct_) {                                  \
         /* The very same struct, so we know that there will be no */          \
         /* differences.                                           */          \
         *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                      \
       } else {                                                                \
         nsChangeHint difference =                                             \
           this##struct_->CalcDifference(*other##struct_ EXPAND extra_args_);  \
-        if (!unrequestedStruct) {                                             \
-          hint |= difference;                                                 \
-        }                                                                     \
+        hint |= difference;                                                   \
         if (!difference) {                                                    \
           *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                    \
         }                                                                     \
       }                                                                       \
     } else {                                                                  \
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                        \
     }                                                                         \
     styleStructCount++;                                                       \
@@ -286,43 +248,47 @@ nsStyleContext::CalcStyleDifference(nsSt
 #undef DO_STRUCT_DIFFERENCE
 #undef DO_STRUCT_DIFFERENCE_WITH_ARGS
 #undef EXPAND
 
   MOZ_ASSERT(styleStructCount == nsStyleStructID_Length,
              "missing a call to DO_STRUCT_DIFFERENCE");
 
 #ifdef DEBUG
+  #define STYLE_STRUCT_LIST_IGNORE_VARIABLES
   #define STYLE_STRUCT(name_, callback_)                                      \
     MOZ_ASSERT(!!(structsFound & NS_STYLE_INHERIT_BIT(name_)) ==              \
                (PEEK(name_) != nullptr),                                      \
                "PeekStyleData results must not change in the middle of "      \
                "difference calculation.");
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT
+  #undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
 #endif
 
   // We check for struct pointer equality here rather than as part of the
   // DO_STRUCT_DIFFERENCE calls, since those calls can result in structs
   // we previously examined and found to be null on this style context
   // getting computed by later DO_STRUCT_DIFFERENCE calls (which can
   // happen when the nsRuleNode::ComputeXXXData method looks up another
   // struct.)  This is important for callers in RestyleManager that
   // need to know the equality or not of the final set of cached struct
   // pointers.
   *aSamePointerStructs = 0;
 
+#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
 #define STYLE_STRUCT(name_, callback_)                                        \
   {                                                                           \
     const nsStyle##name_* data = PEEK(name_);                                 \
     if (!data || data == aNewContext->ThreadsafeStyle##name_()) {             \
       *aSamePointerStructs |= NS_STYLE_INHERIT_BIT(name_);                    \
     }                                                                         \
   }
 #include "nsStyleStructList.h"
+#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
 #undef STYLE_STRUCT
 
   // Note that we do not check whether this->RelevantLinkVisited() !=
   // aNewContext->RelevantLinkVisited(); we don't need to since
   // nsCSSFrameConstructor::DoContentStateChanged always adds
   // nsChangeHint_RepaintFrame for NS_EVENT_STATE_VISITED changes (and
   // needs to, since HasStateDependentStyle probably doesn't work right
   // for NS_EVENT_STATE_VISITED).  Hopefully this doesn't actually
@@ -331,18 +297,18 @@ nsStyleContext::CalcStyleDifference(nsSt
   // the page to measure.
   // However, we do need to compute the larger of the changes that can
   // happen depending on whether the link is visited or unvisited, since
   // doing only the one that's currently appropriate would expose which
   // links are in history to easy performance measurement.  Therefore,
   // here, we add nsChangeHint_RepaintFrame hints (the maximum for
   // things that can depend on :visited) for the properties on which we
   // call GetVisitedDependentColor.
-  nsStyleContext *thisVis = GetStyleIfVisited(),
-                *otherVis = aNewContext->GetStyleIfVisited();
+  nsStyleContext* thisVis = GetStyleIfVisited();
+  nsStyleContext* otherVis = aNewContext->GetStyleIfVisited();
   if (!thisVis != !otherVis) {
     // One style context has a style-if-visited and the other doesn't.
     // Presume a difference.
     hint |= nsChangeHint_RepaintFrame;
   } else if (thisVis && !NS_IsHintSubset(nsChangeHint_RepaintFrame, hint)) {
     // Both style contexts have a style-if-visited.
     bool change = false;
 
@@ -430,17 +396,17 @@ void nsStyleContext::List(FILE* out, int
   nsAutoCString str;
   // Indent
   int32_t ix;
   for (ix = aIndent; --ix >= 0; ) {
     str.AppendLiteral("  ");
   }
   str.Append(nsPrintfCString("%p(%d) parent=%p ",
                              (void*)this, IsGecko() ? AsGecko()->mRefCnt : 0,
-                             (void *)mParent));
+                             IsGecko() ? AsGecko()->GetParent() : nullptr));
   if (mPseudoTag) {
     nsAutoString  buffer;
     mPseudoTag->ToString(buffer);
     AppendUTF16toUTF8(buffer, str);
     str.Append(' ');
   }
 
   if (IsServo()) {
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -64,19 +64,16 @@ public:
 
   // These two methods are for use by ArenaRefPtr.
   static mozilla::ArenaObjectID ArenaObjectID()
   {
     return mozilla::eArenaObjectID_GeckoStyleContext;
   }
   nsIPresShell* Arena();
 
-  void AddChild(nsStyleContext* aChild);
-  void RemoveChild(nsStyleContext* aChild);
-
   inline void AddRef();
   inline void Release();
 
 #ifdef DEBUG
   void FrameAddRef() {
     ++mFrameRefCnt;
   }
 
@@ -305,39 +302,31 @@ public:
   static bool LookupStruct(const nsACString& aName, nsStyleStructID& aResult);
 #endif
 
 protected:
   // protected destructor to discourage deletion outside of Release()
   ~nsStyleContext() {}
 
   // Delegated Helper constructor.
-  nsStyleContext(nsStyleContext* aParent,
-                 nsIAtom* aPseudoTag,
+  nsStyleContext(nsIAtom* aPseudoTag,
                  mozilla::CSSPseudoElementType aPseudoType);
 
-  // Helper post-contruct hook.
-  void FinishConstruction();
-
-  void SetStyleBits();
-
   // Helper functions for GetStyle* and PeekStyle*
   #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_)                  \
     template<bool aComputeData>                                         \
     const nsStyle##name_ * DoGetStyle##name_();
   #define STYLE_STRUCT_RESET(name_, checkdata_cb_)                      \
     template<bool aComputeData>                                         \
     const nsStyle##name_ * DoGetStyle##name_();
 
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT_RESET
   #undef STYLE_STRUCT_INHERITED
 
-  RefPtr<nsStyleContext> mParent;
-
   // If this style context is for a pseudo-element or anonymous box,
   // the relevant atom.
   nsCOMPtr<nsIAtom> mPseudoTag;
 
   // mBits stores a number of things:
   //  - It records (using the style struct bits) which structs are
   //    inherited from the parent context or owned by the rule node (i.e.,
   //    not owned by the style context).
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -91,85 +91,54 @@ const nsStyle##name_ * nsStyleContext::D
         GetStyle##name_<aComputeData>(gecko, mBits);                \
     /* always cache inherited data on the style context; the rule */\
     /* node set the bit in mBits for us if needed. */               \
     gecko->mCachedInheritedData                                     \
       .mStyleStructs[eStyleStruct_##name_] =                        \
       const_cast<nsStyle##name_ *>(newData);                        \
     return newData;                                                 \
   }                                                                 \
-  auto servo = AsServo();                                           \
-  /**                                                               \
-   * Also (conservatively) set the owning bit in the parent style   \
-   * context if we're a text node.                                  \
-   *                                                                \
-   * This causes the parent element's style context to cache any    \
-   * inherited structs we request for a text node, which means we   \
-   * don't have to compute change hints for the text node, as       \
-   * handling the change on the parent element is sufficient.       \
-   *                                                                \
-   * Note, however, that we still need to request the style struct  \
-   * of the text node itself, since we may run some fixups on it,   \
-   * like for text-combine.                                         \
-   *                                                                \
-   * This model is sound because for the fixed-up values to change, \
-   * other properties on the parent need to change too, and we'll   \
-   * handle those change hints correctly.                           \
-   *                                                                \
-   * TODO(emilio): Perhaps we should remove those fixups and handle \
-   * those in layout instead. Those fixups are kind of expensive    \
-   * for style sharing, and computed style of text nodes is not     \
-   * observable. If we do that, we could assert here that the       \
-   * inherited structs of both are the same.                        \
-   */                                                               \
-  if (mPseudoTag == nsCSSAnonBoxes::mozText && aComputeData) {      \
-    MOZ_ASSERT(mParent);                                            \
-    mParent->AddStyleBit(NS_STYLE_INHERIT_BIT(name_));              \
-  }                                                                 \
-                                                                    \
   const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
   if (!aComputeData && needToCompute) {                             \
     return nullptr;                                                 \
   }                                                                 \
                                                                     \
-  const nsStyle##name_* data =                                      \
-    servo->ComputedData()->GetStyle##name_();                       \
+  const nsStyle##name_* data = ComputedData()->GetStyle##name_();   \
+                                                                    \
   /* perform any remaining main thread work on the struct */        \
   if (needToCompute) {                                              \
     MOZ_ASSERT(NS_IsMainThread());                                  \
     MOZ_ASSERT(!mozilla::ServoStyleSet::IsInServoTraversal());      \
     const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext());  \
     /* the ServoStyleContext owns the struct */                     \
     AddStyleBit(NS_STYLE_INHERIT_BIT(name_));                       \
   }                                                                 \
   return data;                                                      \
 }
 
 #define STYLE_STRUCT_RESET(name_, checkdata_cb_)                              \
 template<bool aComputeData>                                                   \
 const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() {                  \
-  if (auto gecko = GetAsGecko()) {                                            \
+  if (auto* gecko = GetAsGecko()) {                                           \
     if (gecko->mCachedResetData) {                                            \
       const nsStyle##name_ * cachedData =                                     \
         static_cast<nsStyle##name_*>(                                         \
           gecko->mCachedResetData->mStyleStructs[eStyleStruct_##name_]);      \
       if (cachedData) /* Have it cached already, yay */                       \
         return cachedData;                                                    \
     }                                                                         \
     /* Have the rulenode deal */                                              \
     AUTO_CHECK_DEPENDENCY(gecko, eStyleStruct_##name_);                       \
     return gecko->RuleNode()->GetStyle##name_<aComputeData>(gecko);           \
   }                                                                           \
-  auto servo = AsServo();                                                     \
   const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));          \
   if (!aComputeData && needToCompute) {                                       \
     return nullptr;                                                           \
   }                                                                           \
-  const nsStyle##name_* data =                                                \
-    servo->ComputedData()->GetStyle##name_();                                 \
+  const nsStyle##name_* data = ComputedData()->GetStyle##name_();             \
   /* perform any remaining main thread work on the struct */                  \
   if (needToCompute) {                                                        \
     const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext());            \
     /* the ServoStyleContext owns the struct */                               \
     AddStyleBit(NS_STYLE_INHERIT_BIT(name_));                                 \
   }                                                                           \
   return data;                                                                \
 }