Bug 1384542: Move GetParent and IsLinkContext to GeckoStyleContext. r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 26 Jul 2017 18:21:35 +0200
changeset 423105 c48b603e7650ccbb0a8ef4ba183749246e5c5b87
parent 423104 c4f81c52c266fb7673fbf2f42a3c469328540baf
child 423106 a3a199efb743a1043d88b7128d01870186c1fa91
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1384542
milestone56.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 1384542: Move GetParent and IsLinkContext to GeckoStyleContext. r=heycam MozReview-Commit-ID: C19yGcphixX
dom/animation/AnimValuesStyleRule.cpp
layout/base/GeckoRestyleManager.cpp
layout/base/RestyleManager.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsPresContext.cpp
layout/generic/nsFrame.cpp
layout/generic/nsTextFrame.cpp
layout/style/GeckoStyleContext.cpp
layout/style/GeckoStyleContext.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleData.cpp
layout/style/nsRuleData.h
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
layout/style/nsStyleContext.h
layout/style/nsStyleContextInlines.h
layout/tables/nsTableColGroupFrame.cpp
layout/xul/nsSplitterFrame.cpp
--- a/dom/animation/AnimValuesStyleRule.cpp
+++ b/dom/animation/AnimValuesStyleRule.cpp
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AnimValuesStyleRule.h"
+#include "mozilla/GeckoStyleContext.h"
 #include "nsRuleData.h"
-#include "mozilla/GeckoStyleContext.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
 
 void
 AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
 {
-  GeckoStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
+  GeckoStyleContext* contextParent = aRuleData->mStyleContext->GetParent();
   if (contextParent && contextParent->HasPseudoElementData()) {
     // Don't apply transitions or animations to things inside of
     // pseudo-elements.
     // FIXME (Bug 522599): Add tests for this.
 
     // Prevent structs from being cached on the rule node since we're inside
     // a pseudo-element, as we could determine cacheability differently
     // when walking the rule tree for a style context that is not inside
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -136,17 +136,17 @@ GetNextBlockInInlineSibling(nsIFrame* aF
  * Since this is used when deciding to copy the new style context, it
  * takes as an argument the old style context to check if the style is
  * the same.  When it is used in other contexts (i.e., where the next
  * continuation would already have the new style context), the current
  * style context should be passed.
  */
 static nsIFrame*
 GetNextContinuationWithSameStyle(nsIFrame* aFrame,
-                                 nsStyleContext* aOldStyleContext,
+                                 GeckoStyleContext* aOldStyleContext,
                                  bool* aHaveMoreContinuations = nullptr)
 {
   // See GetPrevContinuationWithSameStyle about {ib} splits.
 
   nsIFrame* nextContinuation = aFrame->GetNextContinuation();
   if (!nextContinuation &&
       (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
     // We're the last continuation, so we have to hop back to the first
@@ -161,17 +161,17 @@ GetNextContinuationWithSameStyle(nsIFram
 
   if (!nextContinuation) {
     return nullptr;
   }
 
   NS_ASSERTION(nextContinuation->GetContent() == aFrame->GetContent(),
                "unexpected content mismatch");
 
-  nsStyleContext* nextStyle = nextContinuation->StyleContext();
+  GeckoStyleContext* nextStyle = nextContinuation->StyleContext()->AsGecko();
   if (nextStyle != aOldStyleContext) {
     NS_ASSERTION(aOldStyleContext->GetPseudo() != nextStyle->GetPseudo() ||
                  aOldStyleContext->GetParent() != nextStyle->GetParent(),
                  "continuations should have the same style context");
     nextContinuation = nullptr;
     if (aHaveMoreContinuations) {
       *aHaveMoreContinuations = true;
     }
@@ -917,18 +917,18 @@ GetPrevContinuationWithPossiblySameStyle
 static nsIFrame*
 GetPrevContinuationWithSameStyle(nsIFrame* aFrame)
 {
   nsIFrame* prevContinuation = GetPrevContinuationWithPossiblySameStyle(aFrame);
   if (!prevContinuation) {
     return nullptr;
   }
 
-  nsStyleContext* prevStyle = prevContinuation->StyleContext();
-  nsStyleContext* selfStyle = aFrame->StyleContext();
+  GeckoStyleContext* prevStyle = prevContinuation->StyleContext()->AsGecko();
+  GeckoStyleContext* selfStyle = aFrame->StyleContext()->AsGecko();
   if (prevStyle != selfStyle) {
     NS_ASSERTION(prevStyle->GetPseudo() != selfStyle->GetPseudo() ||
                  prevStyle->GetParent() != selfStyle->GetParent(),
                  "continuations should have the same style context");
     prevContinuation = nullptr;
   }
   return prevContinuation;
 }
@@ -976,18 +976,18 @@ GeckoRestyleManager::ReparentStyleContex
     // same style context is valid before the reresolution.  (We need
     // to check the pseudo-type and style context parent because of
     // :first-letter and :first-line, where we create styled and
     // unstyled letter/line frames distinguished by pseudo-type, and
     // then need to distinguish their descendants based on having
     // different parents.)
     nsIFrame* nextContinuation = aFrame->GetNextContinuation();
     if (nextContinuation) {
-      nsStyleContext* nextContinuationContext =
-        nextContinuation->StyleContext();
+      GeckoStyleContext* nextContinuationContext =
+        nextContinuation->StyleContext()->AsGecko();
       NS_ASSERTION(oldContext == nextContinuationContext ||
                    oldContext->GetPseudo() !=
                      nextContinuationContext->GetPseudo() ||
                    oldContext->GetParent() !=
                      nextContinuationContext->GetParent(),
                    "continuations should have the same style context");
     }
   }
@@ -1453,17 +1453,17 @@ ElementRestyler::ConditionallyRestyleCon
   MOZ_ASSERT(aFrame->GetContent()->IsElement());
   MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
 
   if (aFrame->GetContent()->HasFlag(mRestyleTracker.RootBit())) {
     aRestyleRoot = aFrame->GetContent()->AsElement();
   }
 
   for (nsIFrame* f = aFrame; f;
-       f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+       f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
     nsIFrame::ChildListIterator lists(f);
     for (; !lists.IsDone(); lists.Next()) {
       for (nsIFrame* child : lists.CurrentList()) {
         // Out-of-flows are reached through their placeholders.  Continuations
         // and block-in-inline splits are reached through those chains.
         if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
             !GetPrevContinuationWithSameStyle(child)) {
           // only do frames that are in flow
@@ -1733,17 +1733,17 @@ ElementRestyler::MoveStyleContextsForChi
   nsTArray<GeckoStyleContext*> contextsToMove;
 
   MOZ_ASSERT(!MustReframeForBeforePseudo(),
              "shouldn't need to reframe ::before as we would have had "
              "eRestyle_Subtree and wouldn't get in here");
 
   DebugOnly<nsIFrame*> lastContinuation;
   for (nsIFrame* f = mFrame; f;
-       f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+       f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
     lastContinuation = f;
     if (!MoveStyleContextsForContentChildren(f, aOldContext, contextsToMove)) {
       return false;
     }
   }
 
   MOZ_ASSERT(!MustReframeForAfterPseudo(lastContinuation),
              "shouldn't need to reframe ::after as we would have had "
@@ -2996,17 +2996,17 @@ ElementRestyler::RestyleChildren(nsResty
   // kids would use mFrame->StyleContext(), which is out of date if
   // mHintsHandledBySelf has a ReconstructFrame hint; doing this could
   // trigger assertions about mismatched rule trees.
   nsIFrame* lastContinuation;
   if (!(mHintsHandledBySelf & nsChangeHint_ReconstructFrame)) {
     InitializeAccessibilityNotifications(mFrame->StyleContext());
 
     for (nsIFrame* f = mFrame; f;
-         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+         f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
       lastContinuation = f;
       RestyleContentChildren(f, aChildRestyleHint);
     }
 
     SendAccessibilityNotifications();
   }
 
   // Check whether we might need to create a new ::after frame.
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -528,21 +528,21 @@ DumpContext(nsIFrame* aFrame, nsStyleCon
       fputs(NS_LossyConvertUTF16toASCII(buffer).get(), stdout);
       fputs(" ", stdout);
     }
     fputs("{}\n", stdout);
   }
 }
 
 static void
-VerifySameTree(nsStyleContext* aContext1, nsStyleContext* aContext2)
+VerifySameTree(GeckoStyleContext* aContext1, GeckoStyleContext* aContext2)
 {
-  nsStyleContext* top1 = aContext1;
-  nsStyleContext* top2 = aContext2;
-  nsStyleContext* parent;
+  GeckoStyleContext* top1 = aContext1;
+  GeckoStyleContext* top2 = aContext2;
+  GeckoStyleContext* parent;
   for (;;) {
     parent = top1->GetParent();
     if (!parent)
       break;
     top1 = parent;
   }
   for (;;) {
     parent = top2->GetParent();
@@ -550,32 +550,33 @@ VerifySameTree(nsStyleContext* aContext1
       break;
     top2 = parent;
   }
   NS_ASSERTION(top1 == top2,
                "Style contexts are not in the same style context tree");
 }
 
 static void
-VerifyContextParent(nsIFrame* aFrame, nsStyleContext* aContext,
-                    nsStyleContext* aParentContext)
+VerifyContextParent(nsIFrame* aFrame, GeckoStyleContext* aContext,
+                    GeckoStyleContext* aParentContext)
 {
   // get the contexts not provided
   if (!aContext) {
-    aContext = aFrame->StyleContext();
+    aContext = aFrame->StyleContext()->AsGecko();
   }
 
   if (!aParentContext) {
     nsIFrame* providerFrame;
-    aParentContext = aFrame->GetParentStyleContext(&providerFrame);
+    nsStyleContext* parent = aFrame->GetParentStyleContext(&providerFrame);
+    aParentContext = parent ? parent->AsGecko() : nullptr;
     // aParentContext could still be null
   }
 
   NS_ASSERTION(aContext, "Failure to get required contexts");
-  nsStyleContext* actualParentContext = aContext->GetParent();
+  GeckoStyleContext* actualParentContext = aContext->GetParent();
 
   if (aParentContext) {
     if (aParentContext != actualParentContext) {
       DumpContext(aFrame, aContext);
       if (aContext == aParentContext) {
         NS_ERROR("Using parent's style context");
       } else {
         NS_ERROR("Wrong parent style context");
@@ -593,17 +594,17 @@ VerifyContextParent(nsIFrame* aFrame, ns
       NS_ERROR("Have parent context and shouldn't");
       DumpContext(aFrame, aContext);
       fputs("Has parent context: ", stdout);
       DumpContext(nullptr, actualParentContext);
       fputs("Should be null\n\n", stdout);
     }
   }
 
-  nsStyleContext* childStyleIfVisited = aContext->GetStyleIfVisited();
+  GeckoStyleContext* childStyleIfVisited = aContext->GetStyleIfVisited();
   // Either childStyleIfVisited has aContext->GetParent()->GetStyleIfVisited()
   // as the parent or it has a different rulenode from aContext _and_ has
   // aContext->GetParent() as the parent.
   if (childStyleIfVisited &&
       !((childStyleIfVisited->RuleNode() != aContext->RuleNode() &&
          childStyleIfVisited->GetParent() == aContext->GetParent()) ||
         childStyleIfVisited->GetParent() ==
           aContext->GetParent()->GetStyleIfVisited())) {
@@ -611,17 +612,17 @@ VerifyContextParent(nsIFrame* aFrame, ns
     DumpContext(aFrame, aContext);
     fputs("\n", stdout);
   }
 }
 
 static void
 VerifyStyleTree(nsIFrame* aFrame)
 {
-  nsStyleContext* context = aFrame->StyleContext();
+  GeckoStyleContext* context = aFrame->StyleContext()->AsGecko();
   VerifyContextParent(aFrame, context, nullptr);
 
   nsIFrame::ChildListIterator lists(aFrame);
   for (; !lists.IsDone(); lists.Next()) {
     for (nsIFrame* child : lists.CurrentList()) {
       if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
         // only do frames that are in flow
         if (child->IsPlaceholderFrame()) {
@@ -645,17 +646,17 @@ VerifyStyleTree(nsIFrame* aFrame)
     }
   }
 
   // do additional contexts
   int32_t contextIndex = 0;
   for (nsStyleContext* extraContext;
        (extraContext = aFrame->GetAdditionalStyleContext(contextIndex));
        ++contextIndex) {
-    VerifyContextParent(aFrame, extraContext, context);
+    VerifyContextParent(aFrame, extraContext->AsGecko(), context);
   }
 }
 
 void
 RestyleManager::DebugVerifyStyleTree(nsIFrame* aFrame)
 {
   if (IsServo()) {
     // XXXheycam For now, we know that we don't use the same inheritance
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -5880,17 +5880,17 @@ nsCSSFrameConstructor::AddFrameConstruct
 
       if (newPendingBinding->mBinding) {
         pendingBinding = newPendingBinding;
         // aState takes over owning newPendingBinding
         aState.AddPendingBinding(newPendingBinding.forget());
       }
 
       if (resolveStyle) {
-        if (aContent->IsStyledByServo()) {
+        if (styleContext->IsServo()) {
           Element* element = aContent->AsElement();
           ServoStyleSet* styleSet = mPresShell->StyleSet()->AsServo();
 
           // XXX: We should have a better way to restyle ourselves.
           ServoRestyleManager::ClearServoDataFromSubtree(element);
           styleSet->StyleNewSubtree(element);
 
           // Servo's should_traverse_children() in traversal.rs skips
@@ -5900,17 +5900,18 @@ nsCSSFrameConstructor::AddFrameConstruct
 
           // Because of LazyComputeBehavior::Assert we never create a style
           // context here, so it's fine to pass a null parent.
           styleContext =
             styleSet->ResolveStyleFor(element, nullptr,
                                       LazyComputeBehavior::Assert);
         } else {
           styleContext =
-            ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
+            ResolveStyleContext(styleContext->AsGecko()->GetParent(),
+                                aContent, &aState);
         }
 
         display = styleContext->StyleDisplay();
         aStyleContext = styleContext;
       }
 
       aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
     } else if (display->mBinding.ForceGet()) {
@@ -9642,17 +9643,17 @@ nsCSSFrameConstructor::MaybeRecreateFram
     if (!oldContext) {
       return nullptr;
     }
     oldDisplay = StyleDisplay::Contents;
   }
 
   // The parent has a frame, so try resolving a new context.
   RefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
-    ResolveStyleFor(aElement, oldContext->GetParent(),
+    ResolveStyleFor(aElement, oldContext->AsGecko()->GetParent(),
                     LazyComputeBehavior::Assert);
 
   if (oldDisplay == StyleDisplay::None) {
     ChangeUndisplayedContent(aElement, newContext);
   } else {
     ChangeDisplayContents(aElement, newContext);
   }
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2257,19 +2257,19 @@ nsPresContext::UpdateIsChrome()
   mIsChrome = mContainer &&
               nsIDocShellTreeItem::typeChrome == mContainer->ItemType();
 }
 
 bool
 nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
                                        uint32_t aRuleTypeMask) const
 {
-  if (mShell->StyleSet()->IsGecko()) {
+  if (auto* geckoStyleContext = aFrame->StyleContext()->GetAsGecko()) {
     return
-      nsRuleNode::HasAuthorSpecifiedRules(aFrame->StyleContext(),
+      nsRuleNode::HasAuthorSpecifiedRules(geckoStyleContext,
                                           aRuleTypeMask,
                                           UseDocumentColors());
   }
   Element* elem = aFrame->GetContent()->AsElement();
 
   MOZ_ASSERT(elem->GetPseudoElementType() ==
              aFrame->StyleContext()->GetPseudoType());
   MOZ_ASSERT(elem->HasServoData());
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7196,24 +7196,24 @@ nsIFrame::ListGeneric(nsACString& aTo, c
   aTo += nsPrintfCString(" [sc=%p", static_cast<void*>(mStyleContext));
   if (mStyleContext) {
     nsIAtom* pseudoTag = mStyleContext->GetPseudo();
     if (pseudoTag) {
       nsAutoString atomString;
       pseudoTag->ToString(atomString);
       aTo += nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
     }
-    if (mStyleContext->IsGecko()) {
-      if (!mStyleContext->GetParent() ||
-          (GetParent() && GetParent()->StyleContext() != mStyleContext->GetParent())) {
-        aTo += nsPrintfCString("^%p", mStyleContext->GetParent());
-        if (mStyleContext->GetParent()) {
-          aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent());
-          if (mStyleContext->GetParent()->GetParent()) {
-            aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent()->GetParent());
+    if (auto* geckoContext = mStyleContext->GetAsGecko()) {
+      if (!geckoContext->GetParent() ||
+          (GetParent() && GetParent()->StyleContext() != geckoContext->GetParent())) {
+        aTo += nsPrintfCString("^%p", geckoContext->GetParent());
+        if (geckoContext->GetParent()) {
+          aTo += nsPrintfCString("^%p", geckoContext->GetParent()->GetParent());
+          if (geckoContext->GetParent()->GetParent()) {
+            aTo += nsPrintfCString("^%p", geckoContext->GetParent()->GetParent()->GetParent());
           }
         }
       }
     }
   }
   aTo += "]";
 }
 
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4091,31 +4091,40 @@ nsTextPaintStyle::InitSelectionColorsAnd
   mInitSelectionColorsAndShadow = true;
 
   nsIFrame* nonGeneratedAncestor = nsLayoutUtils::GetNonGeneratedAncestor(mFrame);
   Element* selectionElement =
     FindElementAncestorForMozSelection(nonGeneratedAncestor->GetContent());
 
   if (selectionElement &&
       selectionStatus == nsISelectionController::SELECTION_ON) {
-    RefPtr<nsStyleContext> sc = nullptr;
-    sc = mPresContext->StyleSet()->
-      ProbePseudoElementStyle(selectionElement,
-                              CSSPseudoElementType::mozSelection,
-                              mFrame->StyleContext());
+    RefPtr<nsStyleContext> sc =
+      mPresContext->StyleSet()->
+        ProbePseudoElementStyle(selectionElement,
+                                CSSPseudoElementType::mozSelection,
+                                mFrame->StyleContext());
     // Use -moz-selection pseudo class.
     if (sc) {
       mSelectionBGColor =
         sc->GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
       mSelectionTextColor =
         sc->GetVisitedDependentColor(&nsStyleText::mWebkitTextFillColor);
-      mHasSelectionShadow =
-        nsRuleNode::HasAuthorSpecifiedRules(sc,
-                                            NS_AUTHOR_SPECIFIED_TEXT_SHADOW,
-                                            true);
+      if (auto* geckoStyleContext = sc->GetAsGecko()) {
+        mHasSelectionShadow =
+          nsRuleNode::HasAuthorSpecifiedRules(geckoStyleContext,
+                                              NS_AUTHOR_SPECIFIED_TEXT_SHADOW,
+                                              true);
+      } else {
+        NS_WARNING("stylo: Need a way to get HasAuthorSpecifiedRules from a "
+                   "raw style context");
+        // Or at least an element and a pseudo-style, which is probably a bit
+        // more doable, since we know that, at least when not in the presence of
+        // first-line / first-letter, we're inheriting from selectionElement.
+        mHasSelectionShadow = true;
+      }
       if (mHasSelectionShadow) {
         mSelectionShadow = sc->StyleText()->mTextShadow;
       }
       return true;
     }
   }
 
   nscolor selectionBGColor =
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -771,17 +771,17 @@ GeckoStyleContext::ApplyStyleFixups(bool
 
   // CSS Inline Layout Level 3 - 3.5 Sizing Initial Letters:
   // For an N-line drop initial in a Western script, the cap-height of the
   // letter needs to be (N – 1) times the line-height, plus the cap-height
   // of the surrounding text.
   if (mPseudoTag == nsCSSPseudoElements::firstLetter) {
     const nsStyleTextReset* textReset = StyleTextReset();
     if (textReset->mInitialLetterSize != 0.0f) {
-      nsStyleContext* containerSC = mParent;
+      GeckoStyleContext* containerSC = GetParent();
       const nsStyleDisplay* containerDisp = containerSC->StyleDisplay();
       while (containerDisp->mDisplay == mozilla::StyleDisplay::Contents) {
         if (!containerSC->GetParent()) {
           break;
         }
         containerSC = containerSC->GetParent();
         containerDisp = containerSC->StyleDisplay();
       }
@@ -933,17 +933,17 @@ GeckoStyleContext::ApplyStyleFixups(bool
   // Any block-level element directly contained by elements with ruby display
   // values are converted to their inline-level equivalents.
   if (!aSkipParentDisplayBasedStyleFixup && mParent) {
     // Skip display:contents ancestors to reach the potential container.
     // (If there are only display:contents ancestors between this node and
     // a flex/grid container ancestor, then this node is a flex/grid item, since
     // its parent *in the frame tree* will be the flex/grid container. So we treat
     // it like a flex/grid item here.)
-    nsStyleContext* containerContext = mParent;
+    GeckoStyleContext* containerContext = GetParent();
     const nsStyleDisplay* containerDisp = containerContext->StyleDisplay();
     while (containerDisp->mDisplay == mozilla::StyleDisplay::Contents) {
       if (!containerContext->GetParent()) {
         break;
       }
       containerContext = containerContext->GetParent();
       containerDisp = containerContext->StyleDisplay();
     }
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -32,16 +32,25 @@ public:
 
   nsPresContext* PresContext() const {
     return RuleNode()->PresContext();
   }
 
   void AddChild(GeckoStyleContext* aChild);
   void RemoveChild(GeckoStyleContext* aChild);
 
+  GeckoStyleContext* GetParent() const {
+    return mParent ? mParent->AsGecko() : nullptr;
+  }
+
+  bool IsLinkContext() const {
+    return GetStyleIfVisited() &&
+           GetStyleIfVisited()->GetParent() == GetParent();
+  }
+
   /**
    * Moves this style context to a new parent.
    *
    * This function violates style context tree immutability, and
    * is a very low-level function and should only be used after verifying
    * many conditions that make it safe to call.
    */
   void MoveTo(GeckoStyleContext* aNewParent);
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -563,18 +563,18 @@ MustReresolveStyle(const nsStyleContext*
   if (aContext->HasPseudoElementData()) {
     if (!aContext->GetPseudo() ||
         aContext->IsServo()) {
       // TODO(emilio): When ::first-line is supported in Servo, we may want to
       // fix this to avoid re-resolving pseudo-element styles.
       return true;
     }
 
-    return aContext->GetParent() &&
-           aContext->GetParent()->HasPseudoElementData();
+    return aContext->AsGecko()->GetParent() &&
+           aContext->HasPseudoElementData();
   }
 
   return false;
 }
 
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
                                              nsIAtom* aPseudo,
@@ -890,17 +890,17 @@ nsComputedDOMStyle::UpdateCurrentStyleSo
 #ifdef DEBUG
     if (mStyleContext && mStyleContext->IsGecko()) {
       // We want to check that going through this path because of
       // HasPseudoElementData is rare, because it slows us down a good
       // bit.  So check that we're really inside something associated
       // with a pseudo-element that contains elements.  (We also allow
       // the element to be NAC, just in case some chrome JS calls
       // getComputedStyle on a NAC-implemented pseudo.)
-      nsStyleContext* topWithPseudoElementData = mStyleContext;
+      GeckoStyleContext* topWithPseudoElementData = mStyleContext->AsGecko();
       while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) {
         topWithPseudoElementData = topWithPseudoElementData->GetParent();
       }
       CSSPseudoElementType pseudo = topWithPseudoElementData->GetPseudoType();
       nsIAtom* pseudoAtom = nsCSSPseudoElements::GetPseudoAtom(pseudo);
       nsAutoString assertMsg(
         NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
       assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String()));
--- a/layout/style/nsRuleData.cpp
+++ b/layout/style/nsRuleData.cpp
@@ -26,17 +26,17 @@ nsRuleData::GetPoisonOffset()
   uintptr_t framePoisonValue = mozPoisonValue();
   return size_t(framePoisonValue - uintptr_t(mValueStorage)) /
          sizeof(nsCSSValue);
 }
 
 nsRuleData::nsRuleData(uint32_t aSIDs,
                        nsCSSValue* aValueStorage,
                        nsPresContext* aContext,
-                       nsStyleContext* aStyleContext)
+                       GeckoStyleContext* aStyleContext)
   : GenericSpecifiedValues(StyleBackendType::Gecko, aContext, aSIDs)
   , mStyleContext(aStyleContext)
   , mValueStorage(aValueStorage)
 {
 #ifndef MOZ_VALGRIND
   size_t framePoisonOffset = GetPoisonOffset();
   for (size_t i = 0; i < nsStyleStructID_Length; ++i) {
     mValueOffsets[i] = framePoisonOffset;
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -16,27 +16,30 @@
 #include "mozilla/RuleNodeCacheConditions.h"
 #include "mozilla/SheetType.h"
 #include "nsAutoPtr.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsStyleStructFwd.h"
 
 class nsPresContext;
-class nsStyleContext;
 struct nsRuleData;
 
+namespace mozilla {
+class GeckoStyleContext;
+} // namespace mozilla
+
 typedef void (*nsPostResolveFunc)(void* aStyleStruct, nsRuleData* aData);
 
 struct nsRuleData final : mozilla::GenericSpecifiedValues
 {
   mozilla::RuleNodeCacheConditions mConditions;
   bool mIsImportantRule;
   mozilla::SheetType mLevel;
-  nsStyleContext* const mStyleContext;
+  mozilla::GeckoStyleContext* const mStyleContext;
 
   // We store nsCSSValues needed to compute the data for one or more
   // style structs (specified by the bitfield mSIDs).  These are stored
   // in a single array allocation (which our caller allocates; see
   // AutoCSSValueArray)   The offset of each property |prop| in
   // mValueStorage is the sum of
   // mValueOffsets[nsCSSProps::kSIDTable[prop]] and
   // nsCSSProps::PropertyIndexInStruct(prop).  The only place we gather
@@ -47,17 +50,17 @@ struct nsRuleData final : mozilla::Gener
   nsCSSValue* const mValueStorage; // our user owns this array
   size_t mValueOffsets[nsStyleStructID_Length];
 
   nsAutoPtr<mozilla::CSSVariableDeclarations> mVariables;
 
   nsRuleData(uint32_t aSIDs,
              nsCSSValue* aValueStorage,
              nsPresContext* aContext,
-             nsStyleContext* aStyleContext);
+             mozilla::GeckoStyleContext* aStyleContext);
 
 #ifdef DEBUG
   ~nsRuleData();
 #else
   ~nsRuleData() {}
 #endif
 
   /**
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -624,30 +624,31 @@ static nscoord CalcLengthWith(const nsCS
         // the root element, in which case aFontSize is already the
         // value we want.
         if (aFontSize == -1) {
           // XXX Should this be styleFont->mSize instead to avoid taking
           // minfontsize prefs into account?
           aFontSize = styleFont->mFont.size;
         }
         rootFontSize = aFontSize;
-      } else if (aStyleContext && !aStyleContext->GetParent()) {
+      // FIXME(emilio, bug 1384656): We can reach this from servo right now...
+      } else if (aStyleContext && !aStyleContext->AsGecko()->GetParent()) {
         // This is the root element (XXX we don't really know this, but
         // nsRuleNode::SetFont makes the same assumption!), so we should
         // use StyleFont on this context to get the root element's
         // font size.
         rootFontSize = styleFont->mFont.size;
       } else {
         // This is not the root element or we are calculating something other
         // than font size, so rem is relative to the root element's font size.
         // Find the root style context by walking up the style context tree.
         // NOTE: We should not call ResolveStyleFor() against the root element
         // to obtain the root style here because it may lead to reentrant call
         // of nsStyleSet::GetContext().
-        nsStyleContext* rootStyle = aStyleContext;
+        GeckoStyleContext* rootStyle = aStyleContext->AsGecko();
         while (rootStyle->GetParent()) {
           rootStyle = rootStyle->GetParent();
         }
         const nsStyleFont *rootStyleFont = rootStyle->StyleFont();
         rootFontSize = rootStyleFont->mFont.size;
       }
 
       return ScaleCoordRound(aValue, float(rootFontSize));
@@ -1105,17 +1106,17 @@ SetPairCoords(const nsCSSValue& aValue,
                        aPresContext, aConditions);
   mozilla::DebugOnly<bool> cY = SetCoord(valY, aCoordY, aParentY, aMask,
                        aStyleContext, aPresContext, aConditions);
   MOZ_ASSERT(cX == cY, "changed one but not the other");
   return cX;
 }
 
 static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
-                       nsPresContext* aPresContext, nsStyleContext *aContext,
+                       nsPresContext* aPresContext, nsStyleContext* aContext,
                        nscolor& aResult, RuleNodeCacheConditions& aConditions)
 {
   bool    result = false;
   nsCSSUnit unit = aValue.GetUnit();
 
   if (aValue.IsNumericColorUnit()) {
     aResult = aValue.GetColorValue();
     result = true;
@@ -10503,28 +10504,21 @@ nsRuleNode::GetDiscretelyAnimatedCSSValu
     }
     if (rule->GetDiscretelyAnimatedCSSValue(aProperty, aValue)) {
       return;
     }
   }
 }
 
 /* static */ bool
-nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
+nsRuleNode::HasAuthorSpecifiedRules(GeckoStyleContext* aStyleContext,
                                     uint32_t ruleTypeMask,
                                     bool aAuthorColorsAllowed)
 {
-#ifdef MOZ_STYLO
-  if (aStyleContext->IsServo()) {
-    NS_WARNING("stylo: nsRuleNode::HasAuthorSpecifiedRules not implemented");
-    return true;
-  }
-#endif
-
-  RefPtr<GeckoStyleContext> styleContext = aStyleContext->AsGecko();
+  RefPtr<GeckoStyleContext> styleContext = aStyleContext;
 
   uint32_t inheritBits = 0;
   if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND)
     inheritBits |= NS_STYLE_INHERIT_BIT(Background);
 
   if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BORDER)
     inheritBits |= NS_STYLE_INHERIT_BIT(Border);
 
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -27,18 +27,18 @@ class nsFontMetrics;
 class nsIStyleRule;
 class nsStyleCoord;
 struct nsCSSRect;
 struct nsCSSValueList;
 struct nsCSSValuePairList;
 struct nsRuleData;
 
 namespace mozilla {
-  class GeckoStyleContext;
-}
+class GeckoStyleContext;
+} // namespace mozilla
 
 struct nsInheritedStyleData
 {
   mozilla::RangedArray<void*,
                        nsStyleStructID_Inherited_Start,
                        nsStyleStructID_Inherited_Count> mStyleStructs;
 
   void* operator new(size_t sz, nsPresContext* aContext) {
@@ -987,17 +987,17 @@ public:
   }
 
   #include "nsStyleStructList.h"
 
   #undef STYLE_STRUCT_RESET
   #undef STYLE_STRUCT_INHERITED
 
   static bool
-    HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
+    HasAuthorSpecifiedRules(mozilla::GeckoStyleContext* aStyleContext,
                             uint32_t ruleTypeMask,
                             bool aAuthorColorsAllowed);
 
   /**
    * Fill in to aPropertiesOverridden all of the properties in aProperties
    * that, for this rule node, have a declaration that is higher than the
    * animation level in the CSS Cascade.
    */
@@ -1005,17 +1005,23 @@ public:
   ComputePropertiesOverridingAnimation(
                               const nsTArray<nsCSSPropertyID>& aProperties,
                               mozilla::GeckoStyleContext* aStyleContext,
                               nsCSSPropertyIDSet& aPropertiesOverridden);
 
   // Expose this so media queries can use it
   static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext,
                                            const nsCSSValue& aValue);
+
   // Expose this so nsTransformFunctions can use it.
+  //
+  // FIXME(emilio): This can enter here with a Servo style context, which will
+  // mostly be fine except for our handling of rem units, I think.
+  //
+  // Ditto in SpecifiedCalcToComputedCalc.
   static nscoord CalcLength(const nsCSSValue& aValue,
                             nsStyleContext* aStyleContext,
                             nsPresContext* aPresContext,
                             mozilla::RuleNodeCacheConditions& aConditions);
 
   struct ComputedCalc {
     nscoord mLength;
     float mPercent;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -86,22 +86,16 @@ public:
 
   uint32_t FrameRefCnt() const {
     return mFrameRefCnt;
   }
 #endif
 
   inline nsPresContext* PresContext() const;
 
-  inline mozilla::GeckoStyleContext* GetParent() const;
-
-  nsStyleContext* GetParentAllowServo() const {
-    return mParent;
-  }
-
   nsIAtom* GetPseudo() const { return mPseudoTag; }
   mozilla::CSSPseudoElementType GetPseudoType() const {
     return static_cast<mozilla::CSSPseudoElementType>(
              mBits >> NS_STYLE_CONTEXT_TYPE_SHIFT);
   }
 
   bool IsAnonBox() const {
     return
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -186,34 +186,16 @@ nsStyleContext::PresContext() const
 
 
 nsStyleContext*
 nsStyleContext::GetStyleIfVisited() const
 {
   MOZ_STYLO_FORWARD(GetStyleIfVisited, ())
 }
 
-mozilla::GeckoStyleContext*
-nsStyleContext::GetParent() const
-{
-  MOZ_ASSERT(IsGecko(),
-             "This should be used only in Gecko-backed style system!");
-  if (mParent) {
-    return mParent->AsGecko();
-  } else {
-    return nullptr;
-  }
-}
-
-bool
-nsStyleContext::IsLinkContext() const
-{
-  return GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
-}
-
 void
 nsStyleContext::StartBackgroundImageLoads()
 {
   // Just get our background struct; that should do the trick
   StyleBackground();
 }
 
 #endif // nsStyleContextInlines_h
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -294,17 +294,17 @@ nsTableColGroupFrame::RemoveFrame(ChildL
       nsTableColFrame* col = colFrame->GetNextCol();
       nsTableColFrame* nextCol;
       while (col && col->GetColType() == eColAnonymousCol) {
 #ifdef DEBUG
         nsIFrame* providerFrame;
         nsStyleContext* psc = colFrame->GetParentStyleContext(&providerFrame);
         if (psc->IsGecko()) {
           // This check code is useful only in Gecko-backed style system.
-          if (static_cast<nsStyleContext*>(colFrame->StyleContext()->GetParent()) == psc) {
+          if (colFrame->StyleContext()->AsGecko()->GetParent() == psc->AsGecko()) {
             NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
                          col->GetContent() == colFrame->GetContent(),
                          "How did that happen??");
           }
           // else colFrame is being removed because of a frame
           // reconstruct on it, and its style context is still the old
           // one, so we can't assert anything about how it compares to
           // col's style context.
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -280,21 +280,26 @@ nsSplitterFrame::Init(nsIContent*       
   // XXXbz this is pretty messed up, since this can change whether we should
   // have a frame at all.  This really needs a better solution.
   if (aParent && aParent->IsXULBoxFrame()) {
     if (!aParent->IsXULHorizontal()) {
       if (!nsContentUtils::HasNonEmptyAttr(aContent, kNameSpaceID_None,
                                            nsGkAtoms::orient)) {
         aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                           NS_LITERAL_STRING("vertical"), false);
-        GeckoStyleContext* parentStyleContext = StyleContext()->GetParent();
-        RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
-          ResolveStyleFor(aContent->AsElement(), parentStyleContext,
-                          LazyComputeBehavior::Allow);
-        SetStyleContextWithoutNotification(newContext);
+        if (StyleContext()->IsGecko()) {
+          // FIXME(emilio): Even if we did this in Servo, this just won't
+          // work, and we'd need a specific "really re-resolve the style" API...
+          GeckoStyleContext* parentStyleContext =
+            StyleContext()->AsGecko()->GetParent();
+          RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
+            ResolveStyleFor(aContent->AsElement(), parentStyleContext,
+                            LazyComputeBehavior::Allow);
+          SetStyleContextWithoutNotification(newContext);
+        }
       }
     }
   }
 
   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
 
   mInner->mState = nsSplitterFrameInner::Open;
   mInner->AddListener();