Bug 1373018 - Part 9: stylo: Make more things on nsStyleContext inlined; r=bholley
authorManish Goregaokar <manishearth@gmail.com>
Sat, 10 Jun 2017 22:27:45 -0700
changeset 412987 b422d7f837f2be2ec1a21a6d1d69153f26df3505
parent 412986 02462591f243f41dc94a71e4e1b0c30e06016e46
child 412988 3b5bae7326a27d7c128fc45dae0123080d216c36
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1373018
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 1373018 - Part 9: stylo: Make more things on nsStyleContext inlined; r=bholley MozReview-Commit-ID: FYiOtmSK2oC
layout/generic/WritingModes.h
layout/generic/nsIFrame.h
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleContextInlines.h
--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -3,16 +3,17 @@
  * 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/. */
 
 #ifndef WritingModes_h_
 #define WritingModes_h_
 
 #include "nsRect.h"
 #include "nsStyleContext.h"
+#include "nsStyleContextInlines.h"
 #include "nsBidiUtils.h"
 
 // It is the caller's responsibility to operate on logical-coordinate objects
 // with matched writing modes. Failure to do so will be a runtime bug; the
 // compiler can't catch it, but in debug mode, we'll throw an assertion.
 // NOTE that in non-debug builds, a writing mode mismatch error will NOT be
 // detected, yet the results will be nonsense (and may lead to further layout
 // failures). Therefore, it is important to test (and fuzz-test) writing-mode
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -36,16 +36,17 @@
 #include "nsITheme.h"
 #include "nsLayoutUtils.h"
 #include "nsQueryFrame.h"
 #include "nsStringGlue.h"
 #include "nsStyleContext.h"
 #include "nsStyleStruct.h"
 #include "Visibility.h"
 #include "nsChangeHint.h"
+#include "nsStyleContextInlines.h"
 
 #ifdef ACCESSIBILITY
 #include "mozilla/a11y/AccTypes.h"
 #endif
 
 /**
  * New rules of reflow:
  * 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -689,34 +689,16 @@ void nsStyleContext::List(FILE* out, int
 #endif
 
 NonOwningStyleContextSource
 nsStyleContext::StyleSource() const
 {
   MOZ_STYLO_FORWARD(StyleSource, ())
 }
 
-#define STYLE_STRUCT(name_, checkdata_cb_)                      \
-const nsStyle##name_ *                                          \
-nsStyleContext::Style##name_() {                                \
-  return DoGetStyle##name_<true>();                             \
-}                                                               \
-const nsStyle##name_ *                                          \
-nsStyleContext::ThreadsafeStyle##name_() {                      \
-  if (mozilla::ServoStyleSet::IsInServoTraversal()) {           \
-    return Servo_GetStyle##name_(AsServo()->ComputedValues());  \
-  }                                                             \
-  return Style##name_();                                        \
-}                                                               \
-const nsStyle##name_ * nsStyleContext::PeekStyle##name_() {     \
-  return DoGetStyle##name_<false>();                            \
-}
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
-
 // Overridden to prevent the global delete from being called, since the memory
 // came out of an nsIArena instead of the global delete operator's heap.
 void
 nsStyleContext::Destroy()
 {
   if (IsGecko()) {
     // Get the pres context.
     RefPtr<nsPresContext> presContext = PresContext();
@@ -1010,26 +992,8 @@ nsStyleContext::LogStyleContextTree(bool
 /* static */ void
 nsStyleContext::Initialize()
 {
   Preferences::AddBoolVarCache(
       &sExpensiveStyleStructAssertionsEnabled,
       "layout.css.expensive-style-struct-assertions.enabled");
 }
 #endif
-
-nsPresContext*
-nsStyleContext::PresContext() const
-{
-    MOZ_STYLO_FORWARD(PresContext, ())
-}
-
-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;
-  }
-}
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -123,19 +123,19 @@ public:
 
   bool HasSingleReference() const {
     NS_ASSERTION(mRefCnt != 0,
                  "do not call HasSingleReference on a newly created "
                  "nsStyleContext with no references yet");
     return mRefCnt == 1;
   }
 
-  nsPresContext* PresContext() const;
+  inline nsPresContext* PresContext() const;
 
-  mozilla::GeckoStyleContext* GetParent() 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>(
@@ -188,20 +188,17 @@ public:
 
   // Is the only link whose visitedness is allowed to influence the
   // style of the node this style context is for (which is that element
   // or its nearest ancestor that is a link) visited?
   bool RelevantLinkVisited() const
     { return !!(mBits & NS_STYLE_RELEVANT_LINK_VISITED); }
 
   // Is this a style context for a link?
-  bool IsLinkContext() const {
-    return
-      GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
-  }
+  inline bool IsLinkContext() const;
 
   // Is this style context the GetStyleIfVisited() for some other style
   // context?
   bool IsStyleIfVisited() const
     { return !!(mBits & NS_STYLE_IS_STYLE_IF_VISITED); }
 
   // Tells this style context that it should return true from
   // IsStyleIfVisited.
@@ -279,42 +276,42 @@ public:
   /**
    * Define typesafe getter functions for each style struct by
    * preprocessing the list of style structs.  These functions are the
    * preferred way to get style data.  The macro creates functions like:
    *   const nsStyleBorder* StyleBorder();
    *   const nsStyleColor* StyleColor();
    */
   #define STYLE_STRUCT(name_, checkdata_cb_) \
-    const nsStyle##name_ * Style##name_() MOZ_NONNULL_RETURN;
+    inline const nsStyle##name_ * Style##name_() MOZ_NONNULL_RETURN;
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT
 
   /**
    * Equivalent to StyleFoo(), except that we skip the cache write during the
    * servo traversal. This can cause incorrect behavior if used improperly,
    * since we won't record that layout potentially depends on the values in
    * this style struct. Use with care.
    */
 
   #define STYLE_STRUCT(name_, checkdata_cb_) \
-    const nsStyle##name_ * ThreadsafeStyle##name_();
+    inline const nsStyle##name_ * ThreadsafeStyle##name_();
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT
 
 
   /**
    * PeekStyle* is like Style* but doesn't trigger style
    * computation if the data is not cached on either the style context
    * or the rule node.
    *
    * Perhaps this shouldn't be a public nsStyleContext API.
    */
   #define STYLE_STRUCT(name_, checkdata_cb_)  \
-    const nsStyle##name_ * PeekStyle##name_();
+    inline const nsStyle##name_ * PeekStyle##name_();
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT
 
   /**
    * Compute the style changes needed during restyling when this style
    * context is being replaced by aNewContext.  (This is nonsymmetric since
    * we optimize by skipping comparison for styles that have never been
    * requested.)
@@ -371,20 +368,17 @@ public:
    * be used based on aLinkIsVisited with the A component of aColors[0].
    */
   static nscolor CombineVisitedColors(nscolor *aColors,
                                       bool aLinkIsVisited);
 
   /**
    * Start the background image loads for this style context.
    */
-  void StartBackgroundImageLoads() {
-    // Just get our background struct; that should do the trick
-    StyleBackground();
-  }
+  inline void StartBackgroundImageLoads();
 
   /**
    * 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.
    */
@@ -508,115 +502,21 @@ protected:
   AutoCheckDependency checkNesting_(this, sid_)
 #else
 #define AUTO_CHECK_DEPENDENCY(sid_)
 #endif
 
   // Helper functions for GetStyle* and PeekStyle*
   #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_)                  \
     template<bool aComputeData>                                         \
-    const nsStyle##name_ * DoGetStyle##name_() {                        \
-      if (IsGecko()) {                                                  \
-        const nsStyle##name_ * cachedData =                             \
-          static_cast<nsStyle##name_*>(                                 \
-            mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]);  \
-        if (cachedData) /* Have it cached already, yay */               \
-          return cachedData;                                            \
-        if (!aComputeData) {                                            \
-          /* We always cache inherited structs on the context when we */\
-          /* compute them. */                                           \
-          return nullptr;                                               \
-        }                                                               \
-        /* Have the rulenode deal */                                    \
-        AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_);                    \
-        const nsStyle##name_ * newData =                                \
-          StyleSource().AsGeckoRuleNode()->                             \
-            GetStyle##name_<aComputeData>(this->AsGecko(), mBits);      \
-        /* always cache inherited data on the style context; the rule */\
-        /* node set the bit in mBits for us if needed. */               \
-        mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] =      \
-          const_cast<nsStyle##name_ *>(newData);                        \
-        return newData;                                                 \
-      }                                                                 \
-      /**                                                               \
-       * 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_GetStyle##name_(StyleSource().AsServoComputedValues());   \
-      /* 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 Servo-backed StyleContextSource owns the struct */       \
-        AddStyleBit(NS_STYLE_INHERIT_BIT(name_));                       \
-      }                                                                 \
-      return data;                                                      \
-    }
-
+    const nsStyle##name_ * DoGetStyle##name_();
   #define STYLE_STRUCT_RESET(name_, checkdata_cb_)                      \
     template<bool aComputeData>                                         \
-    const nsStyle##name_ * DoGetStyle##name_() {                        \
-      if (IsGecko()) {                                                  \
-        if (mCachedResetData) {                                         \
-          const nsStyle##name_ * cachedData =                           \
-            static_cast<nsStyle##name_*>(                               \
-              mCachedResetData->mStyleStructs[eStyleStruct_##name_]);   \
-          if (cachedData) /* Have it cached already, yay */             \
-            return cachedData;                                          \
-        }                                                               \
-        /* Have the rulenode deal */                                    \
-        AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_);                    \
-        return StyleSource().AsGeckoRuleNode()->                        \
-          GetStyle##name_<aComputeData>(this->AsGecko());               \
-      }                                                                 \
-      const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
-      if (!aComputeData && needToCompute) {                             \
-        return nullptr;                                                 \
-      }                                                                 \
-      const nsStyle##name_* data =                                      \
-        Servo_GetStyle##name_(StyleSource().AsServoComputedValues());   \
-      /* perform any remaining main thread work on the struct */        \
-      if (needToCompute) {                                              \
-        const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext());  \
-        /* the Servo-backed StyleContextSource owns the struct */       \
-        AddStyleBit(NS_STYLE_INHERIT_BIT(name_));                       \
-      }                                                                 \
-      return data;                                                      \
-    }
+    const nsStyle##name_ * DoGetStyle##name_();
+
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT_RESET
   #undef STYLE_STRUCT_INHERITED
 
 #ifdef DEBUG
   void AssertStructsNotUsedElsewhere(nsStyleContext* aDestroyingContext,
                                      int32_t aLevels) const;
 #endif
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -14,20 +14,176 @@
 #ifndef nsStyleContextInlines_h
 #define nsStyleContextInlines_h
 
 #include "nsStyleContext.h"
 #include "mozilla/ServoStyleContext.h"
 #include "mozilla/GeckoStyleContext.h"
 #include "mozilla/ServoUtils.h"
 
-using namespace mozilla;
-
-MOZ_DEFINE_STYLO_METHODS(nsStyleContext, GeckoStyleContext, ServoStyleContext);
+MOZ_DEFINE_STYLO_METHODS(nsStyleContext,
+                         mozilla::GeckoStyleContext,
+                         mozilla::ServoStyleContext);
 
 nsRuleNode*
 nsStyleContext::RuleNode()
 {
     MOZ_RELEASE_ASSERT(IsGecko());
     return AsGecko()->RuleNode();
 }
 
+#define STYLE_STRUCT(name_, checkdata_cb_)                      \
+const nsStyle##name_ *                                          \
+nsStyleContext::Style##name_() {                                \
+  return DoGetStyle##name_<true>();                             \
+}                                                               \
+const nsStyle##name_ *                                          \
+nsStyleContext::ThreadsafeStyle##name_() {                      \
+  if (mozilla::ServoStyleSet::IsInServoTraversal()) {           \
+    return Servo_GetStyle##name_(AsServo()->ComputedValues());  \
+  }                                                             \
+  return Style##name_();                                        \
+}                                                               \
+const nsStyle##name_ * nsStyleContext::PeekStyle##name_() {     \
+  return DoGetStyle##name_<false>();                            \
+}
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT
+
+// Helper functions for GetStyle* and PeekStyle*
+#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_)                \
+template<bool aComputeData>                                         \
+const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() {        \
+  if (IsGecko()) {                                                  \
+    const nsStyle##name_ * cachedData =                             \
+      static_cast<nsStyle##name_*>(                                 \
+        mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]);  \
+    if (cachedData) /* Have it cached already, yay */               \
+      return cachedData;                                            \
+    if (!aComputeData) {                                            \
+      /* We always cache inherited structs on the context when we */\
+      /* compute them. */                                           \
+      return nullptr;                                               \
+    }                                                               \
+    /* Have the rulenode deal */                                    \
+    AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_);                    \
+    const nsStyle##name_ * newData =                                \
+      StyleSource().AsGeckoRuleNode()->                             \
+        GetStyle##name_<aComputeData>(this->AsGecko(), mBits);      \
+    /* always cache inherited data on the style context; the rule */\
+    /* node set the bit in mBits for us if needed. */               \
+    mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] =      \
+      const_cast<nsStyle##name_ *>(newData);                        \
+    return newData;                                                 \
+  }                                                                 \
+  /**                                                               \
+   * 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_GetStyle##name_(StyleSource().AsServoComputedValues());   \
+  /* 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 Servo-backed StyleContextSource 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 (IsGecko()) {                                                  \
+    if (mCachedResetData) {                                         \
+      const nsStyle##name_ * cachedData =                           \
+        static_cast<nsStyle##name_*>(                               \
+          mCachedResetData->mStyleStructs[eStyleStruct_##name_]);   \
+      if (cachedData) /* Have it cached already, yay */             \
+        return cachedData;                                          \
+    }                                                               \
+    /* Have the rulenode deal */                                    \
+    AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_);                    \
+    return StyleSource().AsGeckoRuleNode()->                        \
+      GetStyle##name_<aComputeData>(this->AsGecko());               \
+  }                                                                 \
+  const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
+  if (!aComputeData && needToCompute) {                             \
+    return nullptr;                                                 \
+  }                                                                 \
+  const nsStyle##name_* data =                                      \
+    Servo_GetStyle##name_(StyleSource().AsServoComputedValues());   \
+  /* perform any remaining main thread work on the struct */        \
+  if (needToCompute) {                                              \
+    const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext());  \
+    /* the Servo-backed StyleContextSource owns the struct */       \
+    AddStyleBit(NS_STYLE_INHERIT_BIT(name_));                       \
+  }                                                                 \
+  return data;                                                      \
+}
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT_RESET
+#undef STYLE_STRUCT_INHERITED
+
+
+nsPresContext*
+nsStyleContext::PresContext() const
+{
+    MOZ_STYLO_FORWARD(PresContext, ())
+}
+
+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