Bug 1367904 - Part 2: stylo: Add stylo conversion methods for nsStyleContext; stop using arena; r?bholley
MozReview-Commit-ID: CeIDP7idlmC
--- 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