Bug 1244068 - Part 2: Add skeleton ServoStyleSet and a StyleSetHandle smart pointer. r=dholbert
authorCameron McCormack <cam@mcc.id.au>
Wed, 24 Feb 2016 18:01:10 +1100
changeset 321687 64552d361e5ebcc40e74f1f7929f5a9b8b61a8f2
parent 321686 9ac2b2c34c7c00f25cf52db499a8e53e9fe50bd6
child 321688 af6b36331895828a387492db7f43d4d106eb4078
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1244068
milestone47.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 1244068 - Part 2: Add skeleton ServoStyleSet and a StyleSetHandle smart pointer. r=dholbert
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/StyleSetHandle.h
layout/style/StyleSetHandleInlines.h
layout/style/moz.build
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoStyleSet.cpp
@@ -0,0 +1,191 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/ServoStyleSet.h"
+
+#include "nsCSSAnonBoxes.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+void
+ServoStyleSet::Init(nsPresContext* aPresContext)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+void
+ServoStyleSet::BeginShutdown()
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+void
+ServoStyleSet::Shutdown()
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+bool
+ServoStyleSet::GetAuthorStyleDisabled() const
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+void
+ServoStyleSet::BeginUpdate()
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::EndUpdate()
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+// resolve a style context
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolveStyleFor(Element* aElement,
+                               nsStyleContext* aParentContext)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolveStyleFor(Element* aElement,
+                               nsStyleContext* aParentContext,
+                               TreeMatchContext& aTreeMatchContext)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
+                                         CSSPseudoElementType aType,
+                                         nsStyleContext* aParentContext,
+                                         Element* aPseudoElement)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+// aFlags is an nsStyleSet flags bitfield
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
+                                        nsStyleContext* aParentContext,
+                                        uint32_t aFlags)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+// manage the set of style sheets in the style set
+nsresult
+ServoStyleSet::AppendStyleSheet(SheetType aType,
+                                CSSStyleSheet* aSheet)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::PrependStyleSheet(SheetType aType,
+                                 CSSStyleSheet* aSheet)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::RemoveStyleSheet(SheetType aType,
+                                CSSStyleSheet* aSheet)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::ReplaceSheets(SheetType aType,
+                             const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
+                                      CSSStyleSheet* aNewSheet,
+                                      CSSStyleSheet* aReferenceSheet)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+int32_t
+ServoStyleSet::SheetCount(SheetType aType) const
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+CSSStyleSheet*
+ServoStyleSet::StyleSheetAt(SheetType aType,
+                            int32_t aIndex) const
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::RemoveDocStyleSheet(CSSStyleSheet* aSheet)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsresult
+ServoStyleSet::AddDocStyleSheet(CSSStyleSheet* aSheet,
+                                nsIDocument* aDocument)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ProbePseudoElementStyle(Element* aParentElement,
+                                       CSSPseudoElementType aType,
+                                       nsStyleContext* aParentContext)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+already_AddRefed<nsStyleContext>
+ServoStyleSet::ProbePseudoElementStyle(Element* aParentElement,
+                                       CSSPseudoElementType aType,
+                                       nsStyleContext* aParentContext,
+                                       TreeMatchContext& aTreeMatchContext,
+                                       Element* aPseudoElement)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsRestyleHint
+ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
+                                      EventStates aStateMask)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
+
+nsRestyleHint
+ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
+                                      CSSPseudoElementType aPseudoType,
+                                     dom::Element* aPseudoElement,
+                                     EventStates aStateMask)
+{
+  MOZ_CRASH("stylo: not implemented");
+}
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoStyleSet.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_ServoStyleSet_h
+#define mozilla_ServoStyleSet_h
+
+#include "mozilla/EventStates.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SheetType.h"
+#include "nsChangeHint.h"
+#include "nsCSSPseudoElements.h"
+#include "nsIAtom.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+class CSSStyleSheet;
+} // namespace mozilla
+class nsStyleContext;
+class nsPresContext;
+struct TreeMatchContext;
+
+namespace mozilla {
+
+/**
+ * The set of style sheets that apply to a document, backed by a Servo
+ * Stylist.  A ServoStyleSet contains ServoStyleSheets.
+ */
+class ServoStyleSet
+{
+public:
+  void Init(nsPresContext* aPresContext);
+  void BeginShutdown();
+  void Shutdown();
+
+  bool GetAuthorStyleDisabled() const;
+  nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
+
+  void BeginUpdate();
+  nsresult EndUpdate();
+
+  // resolve a style context
+  already_AddRefed<nsStyleContext>
+  ResolveStyleFor(dom::Element* aElement,
+                  nsStyleContext* aParentContext);
+
+  already_AddRefed<nsStyleContext>
+  ResolveStyleFor(dom::Element* aElement,
+                  nsStyleContext* aParentContext,
+                  TreeMatchContext& aTreeMatchContext);
+
+  already_AddRefed<nsStyleContext>
+  ResolveStyleForNonElement(nsStyleContext* aParentContext);
+
+  already_AddRefed<nsStyleContext>
+  ResolvePseudoElementStyle(dom::Element* aParentElement,
+                            mozilla::CSSPseudoElementType aType,
+                            nsStyleContext* aParentContext,
+                            dom::Element* aPseudoElement);
+
+  // aFlags is an nsStyleSet flags bitfield
+  already_AddRefed<nsStyleContext>
+  ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
+                           uint32_t aFlags = 0);
+
+  // manage the set of style sheets in the style set
+  nsresult AppendStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+  nsresult PrependStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+  nsresult RemoveStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+  nsresult ReplaceSheets(SheetType aType,
+                         const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets);
+  nsresult InsertStyleSheetBefore(SheetType aType,
+                                  CSSStyleSheet* aNewSheet,
+                                  CSSStyleSheet* aReferenceSheet);
+
+  int32_t SheetCount(SheetType aType) const;
+  CSSStyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
+
+  nsresult RemoveDocStyleSheet(CSSStyleSheet* aSheet);
+  nsresult AddDocStyleSheet(CSSStyleSheet* aSheet, nsIDocument* aDocument);
+
+  // check whether there is ::before/::after style for an element
+  already_AddRefed<nsStyleContext>
+  ProbePseudoElementStyle(dom::Element* aParentElement,
+                          mozilla::CSSPseudoElementType aType,
+                          nsStyleContext* aParentContext);
+
+  already_AddRefed<nsStyleContext>
+  ProbePseudoElementStyle(dom::Element* aParentElement,
+                          mozilla::CSSPseudoElementType aType,
+                          nsStyleContext* aParentContext,
+                          TreeMatchContext& aTreeMatchContext,
+                          dom::Element* aPseudoElement = nullptr);
+
+  // Test if style is dependent on content state
+  nsRestyleHint HasStateDependentStyle(dom::Element* aElement,
+                                       EventStates aStateMask);
+  nsRestyleHint HasStateDependentStyle(dom::Element* aElement,
+                                       mozilla::CSSPseudoElementType aPseudoType,
+                                       dom::Element* aPseudoElement,
+                                       EventStates aStateMask);
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ServoStyleSet_h
new file mode 100644
--- /dev/null
+++ b/layout/style/StyleSetHandle.h
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_StyleSetHandle_h
+#define mozilla_StyleSetHandle_h
+
+#include "mozilla/EventStates.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SheetType.h"
+#include "mozilla/StyleBackendType.h"
+#include "nsChangeHint.h"
+#include "nsCSSPseudoElements.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+class CSSStyleSheet;
+class ServoStyleSet;
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+class nsIAtom;
+class nsIDocument;
+class nsStyleContext;
+class nsStyleSet;
+class nsPresContext;
+struct TreeMatchContext;
+
+namespace mozilla {
+
+#define SERVO_BIT 0x1
+
+/**
+ * Smart pointer class that can hold a pointer to either an nsStyleSet
+ * or a ServoStyleSet.
+ */
+class StyleSetHandle
+{
+public:
+  // We define this Ptr class with a StyleSet API that forwards on to the
+  // wrapped pointer, rather than putting these methods on StyleSetHandle
+  // itself, so that we can have StyleSetHandle behave like a smart pointer and
+  // be dereferenced with operator->.
+  class Ptr
+  {
+  public:
+    friend class ::mozilla::StyleSetHandle;
+
+    bool IsGecko() const { return !IsServo(); }
+    bool IsServo() const
+    {
+      MOZ_ASSERT(mValue, "StyleSetHandle null pointer dereference");
+#ifdef MOZ_STYLO
+      return mValue & SERVO_BIT;
+#else
+      return false;
+#endif
+    }
+
+    StyleBackendType BackendType() const
+    {
+      return IsGecko() ? StyleBackendType::Gecko :
+                         StyleBackendType::Servo;
+    }
+
+    nsStyleSet* AsGecko()
+    {
+      MOZ_ASSERT(IsGecko());
+      return reinterpret_cast<nsStyleSet*>(mValue);
+    }
+
+    ServoStyleSet* AsServo()
+    {
+      MOZ_ASSERT(IsServo());
+      return reinterpret_cast<ServoStyleSet*>(mValue);
+    }
+
+    nsStyleSet* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }
+    ServoStyleSet* GetAsServo() { return IsServo() ? AsServo() : nullptr; }
+
+    const nsStyleSet* AsGecko() const
+    {
+      return const_cast<Ptr*>(this)->AsGecko();
+    }
+
+    const ServoStyleSet* AsServo() const
+    {
+      MOZ_ASSERT(IsServo());
+      return const_cast<Ptr*>(this)->AsServo();
+    }
+
+    const nsStyleSet* GetAsGecko() const { return IsGecko() ? AsGecko() : nullptr; }
+    const ServoStyleSet* GetAsServo() const { return IsServo() ? AsServo() : nullptr; }
+
+    // These inline methods are defined in StyleSetHandleInlines.h.
+    inline void Delete();
+
+    // Style set interface.  These inline methods are defined in
+    // StyleSetHandleInlines.h and just forward to the underlying
+    // nsStyleSet or ServoStyleSet.  See corresponding comments in
+    // nsStyleSet.h for descriptions of these methods.
+
+    inline void Init(nsPresContext* aPresContext);
+    inline void BeginShutdown();
+    inline void Shutdown();
+    inline bool GetAuthorStyleDisabled() const;
+    inline nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
+    inline void BeginUpdate();
+    inline nsresult EndUpdate();
+    inline already_AddRefed<nsStyleContext>
+    ResolveStyleFor(dom::Element* aElement,
+                    nsStyleContext* aParentContext);
+    inline already_AddRefed<nsStyleContext>
+    ResolveStyleFor(dom::Element* aElement,
+                    nsStyleContext* aParentContext,
+                    TreeMatchContext& aTreeMatchContext);
+    inline already_AddRefed<nsStyleContext>
+    ResolveStyleForNonElement(nsStyleContext* aParentContext);
+    inline already_AddRefed<nsStyleContext>
+    ResolvePseudoElementStyle(dom::Element* aParentElement,
+                              mozilla::CSSPseudoElementType aType,
+                              nsStyleContext* aParentContext,
+                              dom::Element* aPseudoElement);
+    inline already_AddRefed<nsStyleContext>
+    ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
+                             uint32_t aFlags = 0);
+    inline nsresult AppendStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+    inline nsresult PrependStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+    inline nsresult RemoveStyleSheet(SheetType aType, CSSStyleSheet* aSheet);
+    inline nsresult ReplaceSheets(SheetType aType,
+                           const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets);
+    inline nsresult InsertStyleSheetBefore(SheetType aType,
+                                    CSSStyleSheet* aNewSheet,
+                                    CSSStyleSheet* aReferenceSheet);
+    inline int32_t SheetCount(SheetType aType) const;
+    inline CSSStyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
+    inline nsresult RemoveDocStyleSheet(CSSStyleSheet* aSheet);
+    inline nsresult AddDocStyleSheet(CSSStyleSheet* aSheet, nsIDocument* aDocument);
+    inline already_AddRefed<nsStyleContext>
+    ProbePseudoElementStyle(dom::Element* aParentElement,
+                            mozilla::CSSPseudoElementType aType,
+                            nsStyleContext* aParentContext);
+    inline already_AddRefed<nsStyleContext>
+    ProbePseudoElementStyle(dom::Element* aParentElement,
+                            mozilla::CSSPseudoElementType aType,
+                            nsStyleContext* aParentContext,
+                            TreeMatchContext& aTreeMatchContext,
+                            dom::Element* aPseudoElement = nullptr);
+    inline nsRestyleHint HasStateDependentStyle(dom::Element* aElement,
+                                                EventStates aStateMask);
+    inline nsRestyleHint HasStateDependentStyle(
+        dom::Element* aElement,
+        mozilla::CSSPseudoElementType aPseudoType,
+        dom::Element* aPseudoElement,
+        EventStates aStateMask);
+
+  private:
+    // Stores a pointer to an nsStyleSet or a ServoStyleSet.  The least
+    // significant bit is 0 for the former, 1 for the latter.  This is
+    // valid as the least significant bit will never be used for a pointer
+    // value on platforms we care about.
+    uintptr_t mValue;
+  };
+
+  StyleSetHandle() { mPtr.mValue = 0; }
+  StyleSetHandle(const StyleSetHandle& aOth) { mPtr.mValue = aOth.mPtr.mValue; }
+  MOZ_IMPLICIT StyleSetHandle(nsStyleSet* aSet) { *this = aSet; }
+  MOZ_IMPLICIT StyleSetHandle(ServoStyleSet* aSet) { *this = aSet; }
+
+  StyleSetHandle& operator=(nsStyleSet* aStyleSet)
+  {
+    MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
+               "least significant bit shouldn't be set; we use it for state");
+    mPtr.mValue = reinterpret_cast<uintptr_t>(aStyleSet);
+    return *this;
+  }
+
+  StyleSetHandle& operator=(ServoStyleSet* aStyleSet)
+  {
+#ifdef MOZ_STYLO
+    MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
+               "least significant bit shouldn't be set; we use it for state");
+    mPtr.mValue =
+      aStyleSet ? (reinterpret_cast<uintptr_t>(aStyleSet) | SERVO_BIT) : 0;
+    return *this;
+#else
+    MOZ_CRASH("should not have a ServoStyleSet object when MOZ_STYLO is "
+              "disabled");
+#endif
+  }
+
+  // Make StyleSetHandle usable in boolean contexts.
+  explicit operator bool() const { return !!mPtr.mValue; }
+  bool operator!() const { return !mPtr.mValue; }
+
+  // Make StyleSetHandle behave like a smart pointer.
+  Ptr* operator->() { return &mPtr; }
+  const Ptr* operator->() const { return &mPtr; }
+
+private:
+  Ptr mPtr;
+};
+
+#undef SERVO_BIT
+
+} // namespace mozilla
+
+#endif // mozilla_StyleSetHandle_h
new file mode 100644
--- /dev/null
+++ b/layout/style/StyleSetHandleInlines.h
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_StyleSetHandleInlines_h
+#define mozilla_StyleSetHandleInlines_h
+
+#include "mozilla/ServoStyleSet.h"
+#include "nsStyleSet.h"
+
+#define FORWARD(method_, args_) \
+  return IsGecko() ? AsGecko()->method_ args_ : AsServo()->method_ args_;
+
+namespace mozilla {
+
+void
+StyleSetHandle::Ptr::Delete()
+{
+  if (mValue) {
+    if (IsGecko()) {
+      delete AsGecko();
+    } else {
+      delete AsServo();
+    }
+  }
+}
+
+void
+StyleSetHandle::Ptr::Init(nsPresContext* aPresContext)
+{
+  FORWARD(Init, (aPresContext));
+}
+
+void
+StyleSetHandle::Ptr::BeginShutdown()
+{
+  FORWARD(BeginShutdown, ());
+}
+
+void
+StyleSetHandle::Ptr::Shutdown()
+{
+  FORWARD(Shutdown, ());
+}
+
+bool
+StyleSetHandle::Ptr::GetAuthorStyleDisabled() const
+{
+  FORWARD(GetAuthorStyleDisabled, ());
+}
+
+nsresult
+StyleSetHandle::Ptr::SetAuthorStyleDisabled(bool aStyleDisabled)
+{
+  FORWARD(SetAuthorStyleDisabled, (aStyleDisabled));
+}
+
+void
+StyleSetHandle::Ptr::BeginUpdate()
+{
+  FORWARD(BeginUpdate, ());
+}
+
+nsresult
+StyleSetHandle::Ptr::EndUpdate()
+{
+  FORWARD(EndUpdate, ());
+}
+
+// resolve a style context
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolveStyleFor(dom::Element* aElement,
+                                     nsStyleContext* aParentContext)
+{
+  FORWARD(ResolveStyleFor, (aElement, aParentContext));
+}
+
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolveStyleFor(dom::Element* aElement,
+                                     nsStyleContext* aParentContext,
+                                     TreeMatchContext& aTreeMatchContext)
+{
+  FORWARD(ResolveStyleFor, (aElement, aParentContext, aTreeMatchContext));
+}
+
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolveStyleForNonElement(nsStyleContext* aParentContext)
+{
+  FORWARD(ResolveStyleForNonElement, (aParentContext));
+}
+
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolvePseudoElementStyle(dom::Element* aParentElement,
+                                               CSSPseudoElementType aType,
+                                               nsStyleContext* aParentContext,
+                                               dom::Element* aPseudoElement)
+{
+  FORWARD(ResolvePseudoElementStyle, (aParentElement, aType, aParentContext,
+                                      aPseudoElement));
+}
+
+// aFlags is an nsStyleSet flags bitfield
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
+                                              nsStyleContext* aParentContext,
+                                              uint32_t aFlags)
+{
+  FORWARD(ResolveAnonymousBoxStyle, (aPseudoTag, aParentContext, aFlags));
+}
+
+// manage the set of style sheets in the style set
+nsresult
+StyleSetHandle::Ptr::AppendStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
+{
+  FORWARD(AppendStyleSheet, (aType, aSheet));
+}
+
+nsresult
+StyleSetHandle::Ptr::PrependStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
+{
+  FORWARD(PrependStyleSheet, (aType, aSheet));
+}
+
+nsresult
+StyleSetHandle::Ptr::RemoveStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
+{
+  FORWARD(RemoveStyleSheet, (aType, aSheet));
+}
+
+nsresult
+StyleSetHandle::Ptr::ReplaceSheets(SheetType aType,
+                       const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
+{
+  FORWARD(ReplaceSheets, (aType, aNewSheets));
+}
+
+nsresult
+StyleSetHandle::Ptr::InsertStyleSheetBefore(SheetType aType,
+                                CSSStyleSheet* aNewSheet,
+                                CSSStyleSheet* aReferenceSheet)
+{
+  FORWARD(InsertStyleSheetBefore, (aType, aNewSheet, aReferenceSheet));
+}
+
+int32_t
+StyleSetHandle::Ptr::SheetCount(SheetType aType) const
+{
+  FORWARD(SheetCount, (aType));
+}
+
+CSSStyleSheet*
+StyleSetHandle::Ptr::StyleSheetAt(SheetType aType, int32_t aIndex) const
+{
+  FORWARD(StyleSheetAt, (aType, aIndex));
+}
+
+nsresult
+StyleSetHandle::Ptr::RemoveDocStyleSheet(CSSStyleSheet* aSheet)
+{
+  FORWARD(RemoveDocStyleSheet, (aSheet));
+}
+
+nsresult
+StyleSetHandle::Ptr::AddDocStyleSheet(CSSStyleSheet* aSheet,
+                                      nsIDocument* aDocument)
+{
+  FORWARD(AddDocStyleSheet, (aSheet, aDocument));
+}
+
+// check whether there is ::before/::after style for an element
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ProbePseudoElementStyle(dom::Element* aParentElement,
+                                             CSSPseudoElementType aType,
+                                             nsStyleContext* aParentContext)
+{
+  FORWARD(ProbePseudoElementStyle, (aParentElement, aType, aParentContext));
+}
+
+already_AddRefed<nsStyleContext>
+StyleSetHandle::Ptr::ProbePseudoElementStyle(dom::Element* aParentElement,
+                                             CSSPseudoElementType aType,
+                                             nsStyleContext* aParentContext,
+                                             TreeMatchContext& aTreeMatchContext,
+                                             dom::Element* aPseudoElement)
+{
+  FORWARD(ProbePseudoElementStyle, (aParentElement, aType, aParentContext,
+                                    aTreeMatchContext, aPseudoElement));
+}
+
+nsRestyleHint
+StyleSetHandle::Ptr::HasStateDependentStyle(dom::Element* aElement,
+                                            EventStates aStateMask)
+{
+  FORWARD(HasStateDependentStyle, (aElement, aStateMask));
+}
+
+nsRestyleHint
+StyleSetHandle::Ptr::HasStateDependentStyle(dom::Element* aElement,
+                                            CSSPseudoElementType aPseudoType,
+                                            dom::Element* aPseudoElement,
+                                            EventStates aStateMask)
+{
+  FORWARD(HasStateDependentStyle, (aElement, aPseudoType, aPseudoElement,
+                                   aStateMask));
+}
+
+} // namespace mozilla
+
+#undef FORWARD
+
+#endif // mozilla_StyleSetHandleInlines_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -83,19 +83,22 @@ EXPORTS.mozilla += [
     'CSSStyleSheet.h',
     'CSSVariableDeclarations.h',
     'CSSVariableResolver.h',
     'CSSVariableValues.h',
     'IncrementalClearCOMRuleArray.h',
     'LayerAnimationInfo.h',
     'RuleNodeCacheConditions.h',
     'RuleProcessorCache.h',
+    'ServoStyleSet.h',
     'SheetType.h',
     'StyleAnimationValue.h',
     'StyleBackendType.h',
+    'StyleSetHandle.h',
+    'StyleSetHandleInlines.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'CSS.h',
     'CSSLexer.h',
     'CSSRuleList.h',
     'CSSValue.h',
     'FontFace.h',
@@ -167,16 +170,17 @@ UNIFIED_SOURCES += [
     'nsStyleCoord.cpp',
     'nsStyleSet.cpp',
     'nsStyleStruct.cpp',
     'nsStyleTransformMatrix.cpp',
     'nsStyleUtil.cpp',
     'nsTransitionManager.cpp',
     'RuleNodeCacheConditions.cpp',
     'RuleProcessorCache.cpp',
+    'ServoStyleSet.cpp',
     'StyleAnimationValue.cpp',
     'StyleRule.cpp',
     'SVGAttrAnimationRuleProcessor.cpp',
 ]
 
 # nsCSSRuleProcessor.cpp needs to be built separately because it uses plarena.h.
 SOURCES += [
     'nsCSSRuleProcessor.cpp',