Bug 1274443 - Avoid calling ApplyStyleFixups for ServoComputedValues. r=heycam
authorBobby Holley <bobbyholley@gmail.com>
Thu, 19 May 2016 20:50:46 -0700
changeset 298824 0b5d2ad721da892b90faa8e973be30a2dff270c8
parent 298823 7e6513158f1f62005c942feda3ebc8395a6f02bd
child 298825 15df40db9c161ae5702dcfdbde4e6b358db76be8
push id77332
push userbholley@mozilla.com
push dateWed, 25 May 2016 02:04:13 +0000
treeherdermozilla-inbound@15df40db9c16 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1274443
milestone49.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 1274443 - Avoid calling ApplyStyleFixups for ServoComputedValues. r=heycam
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -155,17 +155,20 @@ nsStyleContext::FinishConstruction(bool 
 #endif
 
   mNextSibling = this;
   mPrevSibling = this;
   if (mParent) {
     mParent->AddChild(this);
   }
 
-  ApplyStyleFixups(aSkipParentDisplayBasedStyleFixup);
+  SetStyleBits();
+  if (!mSource.IsServoComputedValues()) {
+    ApplyStyleFixups(aSkipParentDisplayBasedStyleFixup);
+  }
 
   #define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
   NS_ASSERTION(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
                "NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
   #undef eStyleStruct_LastItem
 }
 
 nsStyleContext::~nsStyleContext()
@@ -469,16 +472,19 @@ const void* nsStyleContext::StyleData(ns
 }
 
 // This is an evil evil function, since it forces you to alloc your own separate copy of
 // style data!  Do not use this function unless you absolutely have to!  You should avoid
 // this at all costs! -dwh
 void* 
 nsStyleContext::GetUniqueStyleData(const nsStyleStructID& aSID)
 {
+  MOZ_ASSERT(!mSource.IsServoComputedValues(),
+             "Can't COW-mutate servo values from Gecko!");
+
   // If we already own the struct and no kids could depend on it, then
   // just return it.  (We leak in this case if there are kids -- and this
   // function really shouldn't be called for style contexts that could
   // have kids depending on the data.  ClearStyleData would be OK, but
   // this test for no mChild or mEmptyChild doesn't catch that case.)
   const void *current = StyleData(aSID);
   if (!mChild && !mEmptyChild &&
       !(mBits & nsCachedStyleData::GetBitForSID(aSID)) &&
@@ -647,18 +653,55 @@ ShouldBlockifyChildren(const nsStyleDisp
   auto displayVal = aStyleDisp->mDisplay;
   return NS_STYLE_DISPLAY_FLEX == displayVal ||
     NS_STYLE_DISPLAY_INLINE_FLEX == displayVal ||
     NS_STYLE_DISPLAY_GRID == displayVal ||
     NS_STYLE_DISPLAY_INLINE_GRID == displayVal;
 }
 
 void
+nsStyleContext::SetStyleBits()
+{
+  // XXXbholley: We should get this information directly from the
+  // ServoComputedValues rather than computing it here. This setup for
+  // ServoComputedValues-backed nsStyleContexts is probably not something
+  // we should ship.
+  //
+  // For example, NS_STYLE_IS_TEXT_COMBINED is still set in ApplyStyleFixups,
+  // which isn't called for ServoComputedValues.
+
+  // See if we have any text decorations.
+  // First see if our parent has text decorations.  If our parent does, then we inherit the bit.
+  if (mParent && mParent->HasTextDecorationLines()) {
+    mBits |= NS_STYLE_HAS_TEXT_DECORATION_LINES;
+  } else {
+    // We might have defined a decoration.
+    if (StyleTextReset()->HasTextDecorationLines()) {
+      mBits |= NS_STYLE_HAS_TEXT_DECORATION_LINES;
+    }
+  }
+
+  if ((mParent && mParent->HasPseudoElementData()) || mPseudoTag) {
+    mBits |= 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 == NS_STYLE_DISPLAY_NONE) {
+    mBits |= NS_STYLE_IN_DISPLAY_NONE_SUBTREE;
+  }
+}
+
+void
 nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
 {
+  MOZ_ASSERT(!mSource.IsServoComputedValues(),
+             "Can't do Gecko style fixups on Servo values");
+
 #define GET_UNIQUE_STYLE_DATA(name_) \
   static_cast<nsStyle##name_*>(GetUniqueStyleData(eStyleStruct_##name_))
 
   // Change writing mode of text frame for text-combine-upright. We use
   // style structs of the parent to avoid triggering computation before
   // we change the writing mode.
   // It is safe to look at the parent's style because we are looking at
   // inherited properties, and ::-moz-text never matches any rules.
@@ -670,31 +713,16 @@ nsStyleContext::ApplyStyleFixups(bool aS
     MOZ_ASSERT(!PeekStyleVisibility(), "If StyleVisibility was already "
                "computed, some properties may have been computed "
                "incorrectly based on the old writing mode value");
     nsStyleVisibility* mutableVis = GET_UNIQUE_STYLE_DATA(Visibility);
     mutableVis->mWritingMode = NS_STYLE_WRITING_MODE_HORIZONTAL_TB;
     AddStyleBit(NS_STYLE_IS_TEXT_COMBINED);
   }
 
-  // See if we have any text decorations.
-  // First see if our parent has text decorations.  If our parent does, then we inherit the bit.
-  if (mParent && mParent->HasTextDecorationLines()) {
-    mBits |= NS_STYLE_HAS_TEXT_DECORATION_LINES;
-  } else {
-    // We might have defined a decoration.
-    if (StyleTextReset()->HasTextDecorationLines()) {
-      mBits |= NS_STYLE_HAS_TEXT_DECORATION_LINES;
-    }
-  }
-
-  if ((mParent && mParent->HasPseudoElementData()) || mPseudoTag) {
-    mBits |= NS_STYLE_HAS_PSEUDO_ELEMENT_DATA;
-  }
-
   // CSS 2.1 10.1: Propagate the root element's 'direction' to the ICB.
   // (PageContentFrame/CanvasFrame etc will inherit 'direction')
   if (mPseudoTag == nsCSSAnonBoxes::viewport) {
     nsPresContext* presContext = PresContext();
     mozilla::dom::Element* docElement = presContext->Document()->GetRootElement();
     if (docElement) {
       RefPtr<nsStyleContext> rootStyle =
         presContext->StyleSet()->ResolveStyleFor(docElement, nullptr);
@@ -793,22 +821,18 @@ nsStyleContext::ApplyStyleFixups(bool aS
                      "converted its display value to be block-level...)");
         nsStyleDisplay* mutable_display = GET_UNIQUE_STYLE_DATA(Display);
         disp = mutable_display;
         mutable_display->mDisplay = displayVal;
       }
     }
   }
 
-  // Set the NS_STYLE_IN_DISPLAY_NONE_SUBTREE bit
-  if ((mParent && mParent->IsInDisplayNoneSubtree()) ||
-      disp->mDisplay == NS_STYLE_DISPLAY_NONE) {
-    mBits |= NS_STYLE_IN_DISPLAY_NONE_SUBTREE;
-  }
-
+  // Note: This must come after the blockification above, otherwise we fail
+  // the grid-item-blockifying-001.html reftest.
   if (mParent && ::ShouldSuppressLineBreak(this, disp, mParent,
                                            mParent->StyleDisplay())) {
     mBits |= NS_STYLE_SUPPRESS_LINEBREAK;
     uint8_t displayVal = disp->mDisplay;
     nsRuleNode::EnsureInlineDisplay(displayVal);
     if (displayVal != disp->mDisplay) {
       nsStyleDisplay* mutable_display = GET_UNIQUE_STYLE_DATA(Display);
       disp = mutable_display;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -522,16 +522,17 @@ private:
   void FinishConstruction(bool aSkipParentDisplayBasedStyleFixup);
 
   void AddChild(nsStyleContext* aChild);
   void RemoveChild(nsStyleContext* aChild);
 
   void* GetUniqueStyleData(const nsStyleStructID& aSID);
   void* CreateEmptyStyleData(const nsStyleStructID& aSID);
 
+  void SetStyleBits();
   void ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup);
 
   const void* StyleStructFromServoComputedValues(nsStyleStructID aSID) {
     switch (aSID) {
 #define STYLE_STRUCT(name_, checkdata_cb_)                                    \
       case eStyleStruct_##name_:                                              \
         return Servo_GetStyle##name_(mSource.AsServoComputedValues());
 #include "nsStyleStructList.h"