Bug 1373018 - Part 9: stylo: Make more things on nsStyleContext inlined; r?bholley draft
authorManish Goregaokar <manishearth@gmail.com>
Sat, 10 Jun 2017 22:27:45 -0700
changeset 595124 07f5c386cc10f148337d3cbe9627c755f8909d38
parent 595123 6e9cce6ce87ab235bfb284dfc75d61f74edc8802
child 595125 3447e52dabfef140b786c3b06f4012f94138ee32
push id64258
push userbmo:manishearth@gmail.com
push dateFri, 16 Jun 2017 03:04:15 +0000
reviewersbholley
bugs1373018
milestone56.0a1
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