Bug 1367904 - Part 2: stylo: Add stylo conversion methods for nsStyleContext; stop using arena; r?bholley draft
authorManish Goregaokar <manishearth@gmail.com>
Sat, 10 Jun 2017 22:27:45 -0700
changeset 593878 7480dfca349e6ad54c3cf6056a7fdacc7777ced4
parent 593877 68128ab531bb99981f2aac69774df8c779fce2d2
child 593879 30d4baccf8b8cb7fdd5c08cbca70cce59493e920
push id63848
push userbmo:manishearth@gmail.com
push dateWed, 14 Jun 2017 08:07:45 +0000
reviewersbholley
bugs1367904
milestone55.0a1
Bug 1367904 - Part 2: stylo: Add stylo conversion methods for nsStyleContext; stop using arena; r?bholley MozReview-Commit-ID: CeIDP7idlmC
layout/style/GeckoStyleContext.cpp
layout/style/GeckoStyleContext.h
layout/style/ServoUtils.h
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleStruct.h
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -15,16 +15,17 @@ using namespace mozilla;
 GeckoStyleContext::GeckoStyleContext(nsStyleContext* aParent,
                                      nsIAtom* aPseudoTag,
                                      CSSPseudoElementType aPseudoType,
                                      already_AddRefed<nsRuleNode> aRuleNode,
                                      bool aSkipParentDisplayBasedStyleFixup)
   : nsStyleContext(aParent, OwningStyleContextSource(Move(aRuleNode)),
                    aPseudoTag, aPseudoType)
 {
+  mBits |= NS_STYLE_CONTEXT_IS_GECKO;
 #ifdef MOZ_STYLO
   mPresContext = mSource.AsGeckoRuleNode()->PresContext();
 #endif
 
   if (aParent) {
 #ifdef DEBUG
     nsRuleNode *r1 = mParent->RuleNode(), *r2 = mSource.AsGeckoRuleNode();
     while (r1->GetParent())
@@ -36,8 +37,18 @@ GeckoStyleContext::GeckoStyleContext(nsS
   } else {
     PresContext()->PresShell()->StyleSet()->RootStyleContextAdded();
   }
 
   mSource.AsGeckoRuleNode()->SetUsedDirectly(); // before ApplyStyleFixups()!
   FinishConstruction();
   ApplyStyleFixups(aSkipParentDisplayBasedStyleFixup);
 }
+
+// Overloaded new operator. Initializes the memory to 0 and relies on an arena
+// (which comes from the presShell) to perform the allocation.
+void*
+GeckoStyleContext::operator new(size_t sz, nsPresContext* aPresContext)
+{
+  // Check the recycle list first.
+  return aPresContext->PresShell()->
+    AllocateByObjectID(eArenaObjectID_nsStyleContext, sz);
+}
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -13,13 +13,15 @@ namespace mozilla {
 
 class GeckoStyleContext final : public nsStyleContext {
 public:
   GeckoStyleContext(nsStyleContext* aParent,
                     nsIAtom* aPseudoTag,
                     CSSPseudoElementType aPseudoType,
                     already_AddRefed<nsRuleNode> aRuleNode,
                     bool aSkipParentDisplayBasedStyleFixup);
+
+  void* operator new(size_t sz, nsPresContext* aPresContext);
 };
 
 }
 
 #endif // mozilla_GeckoStyleContext_h
--- a/layout/style/ServoUtils.h
+++ b/layout/style/ServoUtils.h
@@ -23,32 +23,35 @@ void AssertIsMainThreadOrServoFontMetric
   bool IsGecko() const { return !IsServo(); } \
   bool IsServo() const { return mType == StyleBackendType::Servo; }
 #else
 # define MOZ_DECL_STYLO_CHECK_METHODS \
   bool IsGecko() const { return true; } \
   bool IsServo() const { return false; }
 #endif
 
-/**
- * Macro used in a base class of |geckotype_| and |servotype_|.
- * The class should define |StyleBackendType mType;| itself.
- */
-#define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_)  \
-  MOZ_DECL_STYLO_CHECK_METHODS                          \
+#define MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_)  \
   inline geckotype_* AsGecko();                         \
   inline servotype_* AsServo();                         \
   inline const geckotype_* AsGecko() const;             \
   inline const servotype_* AsServo() const;             \
   inline geckotype_* GetAsGecko();                      \
   inline servotype_* GetAsServo();                      \
   inline const geckotype_* GetAsGecko() const;          \
   inline const servotype_* GetAsServo() const;
 
 /**
+ * Macro used in a base class of |geckotype_| and |servotype_|.
+ * The class should define |StyleBackendType mType;| itself.
+ */
+#define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_)  \
+  MOZ_DECL_STYLO_CHECK_METHODS                          \
+  MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_)
+
+/**
  * Macro used in inline header of class |type_| with its Gecko and Servo
  * subclasses named |geckotype_| and |servotype_| correspondingly for
  * implementing the inline methods defined by MOZ_DECL_STYLO_METHODS.
  */
 #define MOZ_DEFINE_STYLO_METHODS(type_, geckotype_, servotype_) \
   geckotype_* type_::AsGecko() {                                \
     MOZ_ASSERT(IsGecko());                                      \
     return static_cast<geckotype_*>(this);                      \
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 /* the interface (to internal code) for retrieving computed style data */
 
 #include "nsStyleContext.h"
+#include "nsStyleContextInlines.h"
 
 #include "CSSVariableImageTable.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Maybe.h"
 
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSPseudoElements.h"
 #include "nsFontMetrics.h"
@@ -1321,41 +1322,33 @@ void nsStyleContext::List(FILE* out, int
         child->List(out, aIndent + 1, aListDescendants);
         child = child->mNextSibling;
       } while (mEmptyChild != child);
     }
   }
 }
 #endif
 
-// Overloaded new operator. Initializes the memory to 0 and relies on an arena
-// (which comes from the presShell) to perform the allocation.
-void*
-nsStyleContext::operator new(size_t sz, nsPresContext* aPresContext)
-{
-  // Check the recycle list first.
-  return aPresContext->PresShell()->
-    AllocateByObjectID(eArenaObjectID_nsStyleContext, sz);
-}
-
 // 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()
 {
-  // Get the pres context.
-  RefPtr<nsPresContext> presContext = PresContext();
-
-  // Call our destructor.
-  this->~nsStyleContext();
-
-  // Don't let the memory be freed, since it will be recycled
-  // instead. Don't call the global operator delete.
-  presContext->PresShell()->
-    FreeByObjectID(eArenaObjectID_nsStyleContext, this);
+  if (IsGecko()) {
+    // Get the pres context.
+    RefPtr<nsPresContext> presContext = PresContext();
+    // Call our destructor.
+    this->AsGecko()->~GeckoStyleContext();
+    // Don't let the memory be freed, since it will be recycled
+    // instead. Don't call the global operator delete.
+    presContext->PresShell()->
+      FreeByObjectID(eArenaObjectID_nsStyleContext, this);
+    } else {
+      delete static_cast<ServoStyleContext*>(this);
+    }
 }
 
 already_AddRefed<nsStyleContext>
 NS_NewStyleContext(nsStyleContext* aParentContext,
                    nsIAtom* aPseudoTag,
                    CSSPseudoElementType aPseudoType,
                    nsRuleNode* aRuleNode,
                    bool aSkipParentDisplayBasedStyleFixup)
@@ -1371,17 +1364,17 @@ NS_NewStyleContext(nsStyleContext* aPare
 already_AddRefed<nsStyleContext>
 NS_NewStyleContext(nsStyleContext* aParentContext,
                    nsPresContext* aPresContext,
                    nsIAtom* aPseudoTag,
                    CSSPseudoElementType aPseudoType,
                    already_AddRefed<ServoComputedValues> aComputedValues)
 {
   RefPtr<nsStyleContext> context =
-    new (aPresContext)
+    new
     ServoStyleContext(aParentContext, aPresContext, aPseudoTag, aPseudoType,
                    Move(aComputedValues));
   return context.forget();
 }
 
 nsIPresShell*
 nsStyleContext::Arena()
 {
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -6,26 +6,29 @@
 /* the interface (to internal code) for retrieving computed style data */
 
 #ifndef _nsStyleContext_h_
 #define _nsStyleContext_h_
 
 #include "mozilla/Assertions.h"
 #include "mozilla/RestyleLogging.h"
 #include "mozilla/ServoStyleSet.h"
+#include "mozilla/ServoUtils.h"
 #include "mozilla/StyleContextSource.h"
 #include "mozilla/StyleComplexColor.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsStyleSet.h"
 
 class nsIAtom;
 class nsPresContext;
 
 namespace mozilla {
 enum class CSSPseudoElementType : uint8_t;
+class GeckoStyleContext;
+class ServoStyleContext;
 } // namespace mozilla
 
 extern "C" {
 #define STYLE_STRUCT(name_, checkdata_cb_)     \
   struct nsStyle##name_;                       \
   const nsStyle##name_* Servo_GetStyle##name_( \
     ServoComputedValuesBorrowedOrNull computed_values);
 #include "nsStyleStructList.h"
@@ -50,16 +53,25 @@ extern "C" {
  *  1. the |nsIFrame|s that are using the style context and
  *  2. any *child* style contexts (this might be the reverse of
  *     expectation, but it makes sense in this case)
  */
 
 class nsStyleContext
 {
 public:
+#ifdef MOZ_STYLO
+  bool IsGecko() const { return !IsServo(); }
+  bool IsServo() const { return (mBits & NS_STYLE_CONTEXT_IS_GECKO) == 0; }
+#else
+  bool IsGecko() const { return true; }
+  bool IsServo() const { return false; }
+#endif
+  MOZ_DECL_STYLO_CONVERT_METHODS(mozilla::GeckoStyleContext, mozilla::ServoStyleContext);
+
   void Destroy();
 
   // These two methods are for use by ArenaRefPtr.
   static mozilla::ArenaObjectID ArenaObjectID()
   {
     return mozilla::eArenaObjectID_nsStyleContext;
   }
   nsIPresShell* Arena();
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -88,18 +88,20 @@ class ImageTracker;
 // See nsStyleContext::IsInDisplayNoneSubtree
 #define NS_STYLE_IN_DISPLAY_NONE_SUBTREE   0x100000000
 // See nsStyleContext::FindChildWithRules
 #define NS_STYLE_INELIGIBLE_FOR_SHARING    0x200000000
 // See nsStyleContext::HasChildThatUsesResetStyle
 #define NS_STYLE_HAS_CHILD_THAT_USES_RESET_STYLE 0x400000000
 // See nsStyleContext::IsTextCombined
 #define NS_STYLE_IS_TEXT_COMBINED          0x800000000
+// Whether a style context is a Gecko or Servo context
+#define NS_STYLE_CONTEXT_IS_GECKO          0x1000000000
 // See nsStyleContext::GetPseudoEnum
-#define NS_STYLE_CONTEXT_TYPE_SHIFT        36
+#define NS_STYLE_CONTEXT_TYPE_SHIFT        37
 
 // Additional bits for nsRuleNode's mDependentBits:
 #define NS_RULE_NODE_IS_ANIMATION_RULE      0x01000000
 // Free bit                                 0x02000000
 #define NS_RULE_NODE_USED_DIRECTLY          0x04000000
 #define NS_RULE_NODE_IS_IMPORTANT           0x08000000
 #define NS_RULE_NODE_LEVEL_MASK             0xf0000000
 #define NS_RULE_NODE_LEVEL_SHIFT            28