Bug 1334330 - Part 11: stylo: Use ServoUtils abstraction for GenericSpecifiedValues to remove virtual dispatch overhead in nostylo mode; r=bz,emilio
authorManish Goregaokar <manishearth@gmail.com>
Thu, 26 Jan 2017 16:51:01 -0800
changeset 388167 530f32f163161128bb62f0ae9f545d7dac1018fb
parent 388166 34aca5948e5c7a7f93ab903dee3b86b02444a019
child 388168 a03d002ecc4dc0dccabcf93277984834cf19434f
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, emilio
bugs1334330
milestone54.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 1334330 - Part 11: stylo: Use ServoUtils abstraction for GenericSpecifiedValues to remove virtual dispatch overhead in nostylo mode; r=bz,emilio MozReview-Commit-ID: 8yGWs2uOjES
dom/base/nsMappedAttributeElement.cpp
dom/base/nsMappedAttributeElement.h
dom/html/HTMLBRElement.cpp
dom/html/HTMLBodyElement.cpp
dom/html/HTMLContentElement.cpp
dom/html/HTMLFontElement.cpp
dom/html/HTMLHeadingElement.cpp
dom/html/HTMLIFrameElement.cpp
dom/html/HTMLImageElement.cpp
dom/html/HTMLInputElement.cpp
dom/html/HTMLLIElement.cpp
dom/html/HTMLOptionsCollection.cpp
dom/html/HTMLParagraphElement.cpp
dom/html/HTMLPreElement.cpp
dom/html/HTMLSelectElement.cpp
dom/html/HTMLSharedElement.cpp
dom/html/HTMLSharedListElement.cpp
dom/html/HTMLSpanElement.cpp
dom/html/HTMLTableCaptionElement.cpp
dom/html/HTMLTableCellElement.cpp
dom/html/HTMLTableColElement.cpp
dom/html/HTMLTableElement.cpp
dom/html/HTMLTableRowElement.cpp
dom/html/HTMLTableSectionElement.cpp
dom/html/HTMLTemplateElement.cpp
dom/html/HTMLTextAreaElement.cpp
dom/html/nsGenericHTMLElement.cpp
dom/html/nsGenericHTMLElement.h
dom/mathml/nsMathMLElement.cpp
dom/mathml/nsMathMLElement.h
layout/style/GenericSpecifiedValues.h
layout/style/GenericSpecifiedValuesInlines.h
layout/style/moz.build
layout/style/nsRuleData.cpp
layout/style/nsRuleData.h
--- a/dom/base/nsMappedAttributeElement.cpp
+++ b/dom/base/nsMappedAttributeElement.cpp
@@ -32,11 +32,11 @@ nsMappedAttributeElement::SetMappedAttri
 nsMapRuleToAttributesFunc
 nsMappedAttributeElement::GetAttributeMappingFunction() const
 {
   return &MapNoAttributesInto;
 }
 
 void
 nsMappedAttributeElement::MapNoAttributesInto(const nsMappedAttributes* aAttributes,
-                                              GenericSpecifiedValues* aGenericData)
+                                              mozilla::GenericSpecifiedValues* aGenericData)
 {
 }
--- a/dom/base/nsMappedAttributeElement.h
+++ b/dom/base/nsMappedAttributeElement.h
@@ -15,34 +15,34 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/GenericSpecifiedValues.h"
 #include "nsStyledElement.h"
 
 class nsMappedAttributes;
 struct nsRuleData;
 
 typedef void (*nsMapRuleToAttributesFunc)(const nsMappedAttributes* aAttributes, 
-                                          GenericSpecifiedValues* aData);
+                                          mozilla::GenericSpecifiedValues* aData);
 
 typedef nsStyledElement nsMappedAttributeElementBase;
 
 class nsMappedAttributeElement : public nsMappedAttributeElementBase
 {
 
 protected:
 
   explicit nsMappedAttributeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsMappedAttributeElementBase(aNodeInfo)
   {}
 
 public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   static void MapNoAttributesInto(const nsMappedAttributes* aAttributes, 
-                                  GenericSpecifiedValues* aGenericData);
+                                  mozilla::GenericSpecifiedValues* aGenericData);
 
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
   virtual bool SetMappedAttribute(nsIDocument* aDocument,
                                     nsIAtom* aName,
                                     nsAttrValue& aValue,
                                     nsresult* aRetval) override;
 };
 
--- a/dom/html/HTMLBRElement.cpp
+++ b/dom/html/HTMLBRElement.cpp
@@ -1,21 +1,20 @@
 /* -*- 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/dom/HTMLBRElement.h"
 #include "mozilla/dom/HTMLBRElementBinding.h"
-
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(BR)
 
 namespace mozilla {
 namespace dom {
 
 HTMLBRElement::HTMLBRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
--- a/dom/html/HTMLBodyElement.cpp
+++ b/dom/html/HTMLBodyElement.cpp
@@ -1,26 +1,26 @@
 /* -*- 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 "HTMLBodyElement.h"
 #include "mozilla/dom/HTMLBodyElementBinding.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsIEditor.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 #include "nsIDocShell.h"
 #include "nsRuleWalker.h"
 #include "nsGlobalWindow.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Body)
 
 namespace mozilla {
 namespace dom {
--- a/dom/html/HTMLContentElement.cpp
+++ b/dom/html/HTMLContentElement.cpp
@@ -5,21 +5,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLContentElement.h"
 #include "mozilla/dom/HTMLContentElementBinding.h"
 #include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/NodeListBinding.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/css/StyleRule.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIAtom.h"
 #include "nsCSSRuleProcessor.h"
-#include "nsRuleData.h"
 #include "nsRuleProcessorData.h"
 #include "nsRuleWalker.h"
 #include "nsCSSParser.h"
 #include "nsDocument.h"
 
 // Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Content) to add check for web components
 // being enabled.
 nsGenericHTMLElement*
--- a/dom/html/HTMLFontElement.cpp
+++ b/dom/html/HTMLFontElement.cpp
@@ -1,19 +1,19 @@
 /* -*- 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 "HTMLFontElement.h"
 #include "mozilla/dom/HTMLFontElementBinding.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 #include "nsContentUtils.h"
 #include "nsCSSParser.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/html/HTMLHeadingElement.cpp
+++ b/dom/html/HTMLHeadingElement.cpp
@@ -2,20 +2,20 @@
 /* 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/dom/HTMLHeadingElement.h"
 #include "mozilla/dom/HTMLHeadingElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 #include "mozAutoDocUpdate.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Heading)
 
 namespace mozilla {
 namespace dom {
 
 HTMLHeadingElement::~HTMLHeadingElement()
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -1,20 +1,20 @@
 /* -*- 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/dom/HTMLIFrameElement.h"
 #include "mozilla/dom/HTMLIFrameElementBinding.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
 #include "nsError.h"
-#include "nsRuleData.h"
 #include "nsStyleConsts.h"
 #include "nsContentUtils.h"
 #include "nsSandboxFlags.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
 
 namespace mozilla {
 namespace dom {
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -36,21 +36,20 @@
 
 #include "imgIContainer.h"
 #include "imgILoader.h"
 #include "imgINotificationObserver.h"
 #include "imgRequestProxy.h"
 
 #include "nsILoadGroup.h"
 
-#include "nsRuleData.h"
-
 #include "nsIDOMHTMLMapElement.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/net/ReferrerPolicy.h"
 
 #include "nsLayoutUtils.h"
 
 using namespace mozilla::net;
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Image)
 
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -64,21 +64,21 @@
 #include "nsUnicharUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsVariant.h"
 
 #include "nsIDOMMutationEvent.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 
-#include "nsRuleData.h"
 #include <algorithm>
 
 // input type=radio
 #include "nsIRadioGroupContainer.h"
 
 // input type=file
 #include "mozilla/dom/FileSystemEntry.h"
 #include "mozilla/dom/FileSystem.h"
--- a/dom/html/HTMLLIElement.cpp
+++ b/dom/html/HTMLLIElement.cpp
@@ -2,21 +2,21 @@
 /* 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/dom/HTMLLIElement.h"
 #include "mozilla/dom/HTMLLIElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(LI)
 
 namespace mozilla {
 namespace dom {
 
 HTMLLIElement::~HTMLLIElement()
 {
--- a/dom/html/HTMLOptionsCollection.cpp
+++ b/dom/html/HTMLOptionsCollection.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLOptionsCollection.h"
 
 #include "HTMLOptGroupElement.h"
 #include "mozAutoDocUpdate.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/dom/HTMLFormSubmission.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLOptionsCollectionBinding.h"
 #include "mozilla/dom/HTMLSelectElement.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIComboboxControlFrame.h"
--- a/dom/html/HTMLParagraphElement.cpp
+++ b/dom/html/HTMLParagraphElement.cpp
@@ -2,19 +2,19 @@
 /* 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/dom/HTMLParagraphElement.h"
 #include "mozilla/dom/HTMLParagraphElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Paragraph)
 
 namespace mozilla {
 namespace dom {
 
 HTMLParagraphElement::~HTMLParagraphElement()
--- a/dom/html/HTMLPreElement.cpp
+++ b/dom/html/HTMLPreElement.cpp
@@ -2,21 +2,21 @@
 /* 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/dom/HTMLPreElement.h"
 #include "mozilla/dom/HTMLPreElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Pre)
 
 namespace mozilla {
 namespace dom {
 
 HTMLPreElement::~HTMLPreElement()
 {
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -12,32 +12,32 @@
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLFormSubmission.h"
 #include "mozilla/dom/HTMLOptGroupElement.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLSelectElementBinding.h"
 #include "mozilla/dom/UnionTypes.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentList.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIDocument.h"
 #include "nsIFormControlFrame.h"
 #include "nsIForm.h"
 #include "nsIFormProcessor.h"
 #include "nsIFrame.h"
 #include "nsIListControlFrame.h"
 #include "nsISelectControlFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsMappedAttributes.h"
 #include "nsPresState.h"
-#include "nsRuleData.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleConsts.h"
 #include "nsTextNode.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Select)
 
 namespace mozilla {
 namespace dom {
--- a/dom/html/HTMLSharedElement.cpp
+++ b/dom/html/HTMLSharedElement.cpp
@@ -7,19 +7,19 @@
 #include "mozilla/dom/HTMLSharedElement.h"
 #include "mozilla/dom/HTMLBaseElementBinding.h"
 #include "mozilla/dom/HTMLDirectoryElementBinding.h"
 #include "mozilla/dom/HTMLHeadElementBinding.h"
 #include "mozilla/dom/HTMLHtmlElementBinding.h"
 #include "mozilla/dom/HTMLParamElementBinding.h"
 #include "mozilla/dom/HTMLQuoteElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsStyleConsts.h"
-#include "nsRuleData.h"
 #include "nsMappedAttributes.h"
 #include "nsContentUtils.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIURI.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
 
 namespace mozilla {
--- a/dom/html/HTMLSharedListElement.cpp
+++ b/dom/html/HTMLSharedListElement.cpp
@@ -4,22 +4,22 @@
  * 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/dom/HTMLSharedListElement.h"
 #include "mozilla/dom/HTMLDListElementBinding.h"
 #include "mozilla/dom/HTMLOListElementBinding.h"
 #include "mozilla/dom/HTMLUListElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(SharedList)
 
 namespace mozilla {
 namespace dom {
 
 HTMLSharedListElement::~HTMLSharedListElement()
 {
--- a/dom/html/HTMLSpanElement.cpp
+++ b/dom/html/HTMLSpanElement.cpp
@@ -2,20 +2,20 @@
 /* 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/dom/HTMLSpanElement.h"
 #include "mozilla/dom/HTMLSpanElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIAtom.h"
-#include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Span)
 
 namespace mozilla {
 namespace dom {
 
 HTMLSpanElement::~HTMLSpanElement()
 {
--- a/dom/html/HTMLTableCaptionElement.cpp
+++ b/dom/html/HTMLTableCaptionElement.cpp
@@ -1,18 +1,19 @@
 /* -*- 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/dom/HTMLTableCaptionElement.h"
+
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
 #include "nsMappedAttributes.h"
-#include "nsRuleData.h"
 #include "mozilla/dom/HTMLTableCaptionElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableCaption)
 
 namespace mozilla {
 namespace dom {
 
 HTMLTableCaptionElement::~HTMLTableCaptionElement()
--- a/dom/html/HTMLTableCellElement.cpp
+++ b/dom/html/HTMLTableCellElement.cpp
@@ -2,19 +2,19 @@
 /* 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/dom/HTMLTableCellElement.h"
 #include "mozilla/dom/HTMLTableElement.h"
 #include "mozilla/dom/HTMLTableRowElement.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
-#include "nsRuleData.h"
 #include "nsRuleWalker.h"
 #include "celldata.h"
 #include "mozilla/dom/HTMLTableCellElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableCell)
 
 namespace mozilla {
 namespace dom {
--- a/dom/html/HTMLTableColElement.cpp
+++ b/dom/html/HTMLTableColElement.cpp
@@ -1,19 +1,19 @@
 /* -*- 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/dom/HTMLTableColElement.h"
+#include "mozilla/dom/HTMLTableColElementBinding.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
-#include "nsRuleData.h"
-#include "mozilla/dom/HTMLTableColElementBinding.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableCol)
 
 namespace mozilla {
 namespace dom {
 
 // use the same protection as ancient code did 
 // http://lxr.mozilla.org/classic/source/lib/layout/laytable.c#46
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -1,17 +1,17 @@
 /* -*- 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/dom/HTMLTableElement.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsAttrValueInlines.h"
-#include "nsRuleData.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsMappedAttributes.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
 #include "mozilla/dom/HTMLTableElementBinding.h"
 #include "nsContentUtils.h"
 #include "jsfriendapi.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -1,19 +1,19 @@
 /* -*- 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/dom/HTMLTableRowElement.h"
 #include "mozilla/dom/HTMLTableElement.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
-#include "nsRuleData.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLTableRowElementBinding.h"
 #include "nsContentList.h"
 #include "nsContentUtils.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableRow)
 
 namespace mozilla {
--- a/dom/html/HTMLTableSectionElement.cpp
+++ b/dom/html/HTMLTableSectionElement.cpp
@@ -1,18 +1,18 @@
 /* -*- 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/dom/HTMLTableSectionElement.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
-#include "nsRuleData.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLTableSectionElementBinding.h"
 #include "nsContentUtils.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(TableSection)
 
 namespace mozilla {
 namespace dom {
--- a/dom/html/HTMLTemplateElement.cpp
+++ b/dom/html/HTMLTemplateElement.cpp
@@ -2,20 +2,20 @@
 /* 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/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/HTMLTemplateElementBinding.h"
 
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIAtom.h"
-#include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Template)
 
 namespace mozilla {
 namespace dom {
 
 HTMLTemplateElement::HTMLTemplateElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -8,16 +8,17 @@
 
 #include "mozAutoDocUpdate.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/HTMLFormSubmission.h"
 #include "mozilla/dom/HTMLTextAreaElementBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/MouseEvents.h"
 #include "nsAttrValueInlines.h"
 #include "nsContentCID.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsFocusManager.h"
 #include "nsIComponentManager.h"
 #include "nsIConstraintValidation.h"
@@ -32,17 +33,16 @@
 #include "nsITextControlFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsLinebreakConverter.h"
 #include "nsMappedAttributes.h"
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 #include "nsPresState.h"
 #include "nsReadableUtils.h"
-#include "nsRuleData.h"
 #include "nsStyleConsts.h"
 #include "nsTextEditorState.h"
 #include "nsIController.h"
 
 static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
 
 #define NS_NO_CONTENT_DISPATCH (1 << 0)
 
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Likely.h"
 
 #include "nscore.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
@@ -44,17 +45,16 @@
 #include "nsIWidget.h"
 #include "nsRange.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsNameSpaceManager.h"
 #include "nsError.h"
 #include "nsScriptLoader.h"
-#include "nsRuleData.h"
 #include "nsIPrincipal.h"
 #include "nsContainerFrame.h"
 #include "nsStyleUtil.h"
 
 #include "nsPresState.h"
 #include "nsILayoutHistoryState.h"
 
 #include "nsHTMLParts.h"
@@ -1525,17 +1525,17 @@ nsGenericHTMLElement::MapBackgroundInto(
   nsPresContext* presContext = aData->PresContext();
 
   if (!aData->PropertyIsSet(eCSSProperty_background_image) &&
       presContext->UseDocumentColors()) {
     // background
     nsAttrValue* value =
       const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
     if (value) {
-      nsRuleData* aRuleData = aData->AsRuleData();
+      nsRuleData* aRuleData = aData->AsGecko();
       // Gecko-specific code
       // Gecko caches the image on the attr directly, but we need not
       // do the same thing for Servo.
       if (aRuleData) {
         nsCSSValue* backImage = aRuleData->ValueForBackgroundImage();
         // If the value is an image, or it is a URL and we attempted a load,
         // put it in the style tree.
         if (value->Type() == nsAttrValue::eURL) {
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -649,26 +649,26 @@ public:
    * called by subclasses' attribute mapping functions.  Currently handles
    * dir, lang and hidden, could handle others.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapCommonAttributesInto(const nsMappedAttributes* aAttributes, 
-                                      GenericSpecifiedValues* aGenericData);
+                                      mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Same as MapCommonAttributesInto except that it does not handle hidden.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapCommonAttributesIntoExceptHidden(const nsMappedAttributes* aAttributes,
-                                                  GenericSpecifiedValues* aGenericData);
+                                                  mozilla::GenericSpecifiedValues* aGenericData);
 
   static const MappedAttributeEntry sCommonAttributeMap[];
   static const MappedAttributeEntry sImageMarginSizeAttributeMap[];
   static const MappedAttributeEntry sImageBorderAttributeMap[];
   static const MappedAttributeEntry sImageAlignAttributeMap[];
   static const MappedAttributeEntry sDivAlignAttributeMap[];
   static const MappedAttributeEntry sBackgroundAttributeMap[];
   static const MappedAttributeEntry sBackgroundColorAttributeMap[];
@@ -676,126 +676,126 @@ public:
   /**
    * Helper to map the align attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapImageAlignAttributeInto(const nsMappedAttributes* aAttributes,
-                                         GenericSpecifiedValues* aGenericData);
+                                         mozilla::GenericSpecifiedValues* aGenericData);
 
   /**
    * Helper to map the align attribute into a style struct for things
    * like <div>, <h1>, etc.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapDivAlignAttributeInto(const nsMappedAttributes* aAttributes,
-                                    GenericSpecifiedValues* aGenericData);
+                                       mozilla::GenericSpecifiedValues* aGenericData);
 
   /**
    * Helper to map the valign attribute into a style struct for things
    * like <col>, <tr>, <section>, etc.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapVAlignAttributeInto(const nsMappedAttributes* aAttributes,
-                                    GenericSpecifiedValues* aGenericData);
+                                     mozilla::GenericSpecifiedValues* aGenericData);
 
   /**
    * Helper to map the image border attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapImageBorderAttributeInto(const nsMappedAttributes* aAttributes,
-                                          GenericSpecifiedValues* aGenericData);
+                                          mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the image margin attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapImageMarginAttributeInto(const nsMappedAttributes* aAttributes,
-                                          GenericSpecifiedValues* aGenericData);
+                                          mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the image position attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
-                                         GenericSpecifiedValues* aGenericData);
+                                         mozilla::GenericSpecifiedValues* aGenericData);
 
   /**
    * Helper to map `width` attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapWidthAttributeInto(const nsMappedAttributes* aAttributes,
-                                    GenericSpecifiedValues* aGenericData);
+                                    mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map `height` attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapHeightAttributeInto(const nsMappedAttributes* aAttributes,
-                                     GenericSpecifiedValues* aGenericData);
+                                     mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the background attribute
    * into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapBackgroundInto(const nsMappedAttributes* aAttributes,
-                                GenericSpecifiedValues* aGenericData);
+                                mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the bgcolor attribute
    * into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapBGColorInto(const nsMappedAttributes* aAttributes,
-                             GenericSpecifiedValues* aGenericData);
+                             mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the background attributes (currently background and bgcolor)
    * into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapBackgroundAttributesInto(const nsMappedAttributes* aAttributes,
-                                          GenericSpecifiedValues* aGenericData);
+                                          mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the scrolling attribute on FRAME and IFRAME
    * into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
-                                        GenericSpecifiedValues* aGenericData);
+                                        mozilla::GenericSpecifiedValues* aGenericData);
   /**
    * Get the presentation context for this content node.
    * @return the presentation context
    */
   enum PresContextFor
   {
     eForComposedDoc,
     eForUncomposedDoc
--- a/dom/mathml/nsMathMLElement.cpp
+++ b/dom/mathml/nsMathMLElement.cpp
@@ -21,16 +21,17 @@
 #include "nsPresContext.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIScriptError.h"
 #include "nsContentUtils.h"
 #include "nsIURI.h"
 
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/dom/ElementBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // nsISupports methods:
 
@@ -484,17 +485,17 @@ nsMathMLElement::ParseNumericValue(const
   aCSSValue.SetFloatValue(floatValue, cssUnit);
   return true;
 }
 
 void
 nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
                                          GenericSpecifiedValues* aGenericData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
+  nsRuleData* aData = aGenericData->AsGecko();
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
     // scriptsizemultiplier
     //
     // "Specifies the multiplier to be used to adjust font size due to changes
     // in scriptlevel.
     //
     // values: number
     // default: 0.71
--- a/dom/mathml/nsMathMLElement.h
+++ b/dom/mathml/nsMathMLElement.h
@@ -67,17 +67,17 @@ public:
                                    uint32_t        aFlags);
 
   static bool ParseNumericValue(const nsString& aString,
                                 nsCSSValue&     aCSSValue,
                                 uint32_t        aFlags,
                                 nsIDocument*    aDocument);
 
   static void MapMathMLAttributesInto(const nsMappedAttributes* aAttributes, 
-                                      GenericSpecifiedValues* aGenericData);
+                                      mozilla::GenericSpecifiedValues* aGenericData);
   
   virtual nsresult GetEventTargetParent(
                      mozilla::EventChainPreVisitor& aVisitor) override;
   virtual nsresult PostHandleEvent(
                      mozilla::EventChainPostVisitor& aVisitor) override;
   nsresult Clone(mozilla::dom::NodeInfo*, nsINode**) const override;
   virtual mozilla::EventStates IntrinsicState() const override;
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
--- a/layout/style/GenericSpecifiedValues.h
+++ b/layout/style/GenericSpecifiedValues.h
@@ -8,43 +8,55 @@
  * Generic representation of a container of specified CSS values, which
  * could potentially be Servo- or Gecko- format. Used to make attribute mapping
  * code generic over style backends.
  */
 
 #ifndef mozilla_GenericSpecifiedValues_h
 #define mozilla_GenericSpecifiedValues_h
 
+#include "mozilla/ServoUtils.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsPresContext.h"
 
 struct nsRuleData;
-
+namespace mozilla {
 // This provides a common interface for attribute mappers (MapAttributesIntoRule)
 // to use regardless of the style backend. If the style backend is Gecko,
 // this will contain an nsRuleData. If it is Servo, it will be a PropertyDeclarationBlock.
 class GenericSpecifiedValues {
+protected:
+    explicit GenericSpecifiedValues(StyleBackendType aType, nsPresContext* aPresContext,
+                                    uint32_t aSIDs)
+        : mType(aType), mPresContext(aPresContext), mSIDs(aSIDs) {}
+
 public:
+    MOZ_DECL_STYLO_METHODS(nsRuleData, nsRuleData)
+
     // Check if we already contain a certain longhand
-    virtual bool PropertyIsSet(nsCSSPropertyID aId) = 0;
+    inline bool PropertyIsSet(nsCSSPropertyID aId);
     // Check if we are able to hold longhands from a given
     // style struct. Pass the result of NS_STYLE_INHERIT_BIT to this
     // function. Can accept multiple inherit bits or'd together.
-    virtual bool ShouldComputeStyleStruct(uint64_t aInheritBits) = 0;
+    inline bool ShouldComputeStyleStruct(uint64_t aInheritBits) {
+        return aInheritBits & mSIDs;
+    }
 
-    virtual nsPresContext* PresContext() = 0;
+    inline nsPresContext* PresContext() {
+        return mPresContext;
+    }
 
     // Set a property to an identifier (string)
-    virtual void SetIdentStringValue(nsCSSPropertyID aId, const nsString& aValue) = 0;
-    virtual void SetIdentStringValueIfUnset(nsCSSPropertyID aId, const nsString& aValue) = 0;
+    inline void SetIdentStringValue(nsCSSPropertyID aId, const nsString& aValue);
+    inline void SetIdentStringValueIfUnset(nsCSSPropertyID aId, const nsString& aValue);
 
     // Set a property to a keyword (usually NS_STYLE_* or StyleFoo::*)
-    virtual void SetKeywordValue(nsCSSPropertyID aId, int32_t aValue) = 0;
-    virtual void SetKeywordValueIfUnset(nsCSSPropertyID aId, int32_t aValue) = 0;
+    inline void SetKeywordValue(nsCSSPropertyID aId, int32_t aValue);
+    inline void SetKeywordValueIfUnset(nsCSSPropertyID aId, int32_t aValue);
 
     template<typename T,
              typename = typename std::enable_if<std::is_enum<T>::value>::type>
     void SetKeywordValue(nsCSSPropertyID aId, T aValue) {
         static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
                       "aValue must be an enum that fits within 32 bits");
         SetKeywordValue(aId, static_cast<int32_t>(aValue));
     }
@@ -52,38 +64,42 @@ public:
              typename = typename std::enable_if<std::is_enum<T>::value>::type>
     void SetKeywordValueIfUnset(nsCSSPropertyID aId, T aValue) {
         static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
                       "aValue must be an enum that fits within 32 bits");
         SetKeywordValueIfUnset(aId, static_cast<int32_t>(aValue));
     }
 
     // Set a property to an integer value
-    virtual void SetIntValue(nsCSSPropertyID aId, int32_t aValue) = 0;
+    inline void SetIntValue(nsCSSPropertyID aId, int32_t aValue);
     // Set a property to a pixel value
-    virtual void SetPixelValue(nsCSSPropertyID aId, float aValue) = 0;
-    virtual void SetPixelValueIfUnset(nsCSSPropertyID aId, float aValue) = 0;
+    inline void SetPixelValue(nsCSSPropertyID aId, float aValue);
+    inline void SetPixelValueIfUnset(nsCSSPropertyID aId, float aValue);
 
     // Set a property to a percent value
-    virtual void SetPercentValue(nsCSSPropertyID aId, float aValue) = 0;
-    virtual void SetPercentValueIfUnset(nsCSSPropertyID aId, float aValue) = 0;
+    inline void SetPercentValue(nsCSSPropertyID aId, float aValue);
+    inline void SetPercentValueIfUnset(nsCSSPropertyID aId, float aValue);
 
     // Set a property to `auto`
-    virtual void SetAutoValue(nsCSSPropertyID aId) = 0;
-    virtual void SetAutoValueIfUnset(nsCSSPropertyID aId) = 0;
+    inline void SetAutoValue(nsCSSPropertyID aId);
+    inline void SetAutoValueIfUnset(nsCSSPropertyID aId);
 
     // Set a property to `currentcolor`
-    virtual void SetCurrentColor(nsCSSPropertyID aId) = 0;
-    virtual void SetCurrentColorIfUnset(nsCSSPropertyID aId) = 0;
+    inline void SetCurrentColor(nsCSSPropertyID aId);
+    inline void SetCurrentColorIfUnset(nsCSSPropertyID aId);
 
     // Set a property to an RGBA nscolor value
-    virtual void SetColorValue(nsCSSPropertyID aId, nscolor aValue) = 0;
-    virtual void SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue) = 0;
+    inline void SetColorValue(nsCSSPropertyID aId, nscolor aValue);
+    inline void SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue);
 
     // Set font-family to a string
-    virtual void SetFontFamily(const nsString& aValue) = 0;
+    inline void SetFontFamily(const nsString& aValue);
     // Add a quirks-mode override to the decoration color of elements nested in <a>
-    virtual void SetTextDecorationColorOverride() = 0;
+    inline void SetTextDecorationColorOverride();
 
-    virtual nsRuleData* AsRuleData() = 0;
+    const mozilla::StyleBackendType mType;
+    nsPresContext* const mPresContext;
+    const uint32_t mSIDs;
 };
 
+} // namespace mozilla
+
 #endif // mozilla_GenericSpecifiedValues_h
new file mode 100644
--- /dev/null
+++ b/layout/style/GenericSpecifiedValuesInlines.h
@@ -0,0 +1,162 @@
+/* -*- 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/. */
+
+/*
+ * Inlined methods for GenericSpecifiedValues. Will just redirect to
+ * nsRuleData methods when compiled without stylo, but will do
+ * virtual dispatch (by checking which kind of container it is)
+ * in stylo mode.
+ */
+
+#ifndef mozilla_GenericSpecifiedValuesInlines_h
+#define mozilla_GenericSpecifiedValuesInlines_h
+
+#include "nsRuleData.h"
+#include "mozilla/GenericSpecifiedValues.h"
+
+namespace mozilla {
+
+MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues, nsRuleData, nsRuleData)
+
+bool
+GenericSpecifiedValues::PropertyIsSet(nsCSSPropertyID aId)
+{
+  MOZ_STYLO_FORWARD(PropertyIsSet, (aId))
+}
+
+void
+GenericSpecifiedValues::SetIdentStringValue(nsCSSPropertyID aId, const nsString& aValue)
+{
+  MOZ_STYLO_FORWARD(SetIdentStringValue, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetIdentStringValueIfUnset(nsCSSPropertyID aId, const nsString& aValue)
+{
+  MOZ_STYLO_FORWARD(SetIdentStringValueIfUnset, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetKeywordValue(nsCSSPropertyID aId, int32_t aValue)
+{
+  // there are some static asserts in MOZ_STYLO_FORWARD which
+  // won't work with the overloaded SetKeywordValue function,
+  // so we copy its expansion and use SetIntValue for decltype
+  // instead
+  static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::SetIntValue),
+                 decltype(&MOZ_STYLO_GECKO_TYPE::SetKeywordValue)>
+        ::value, "Gecko subclass should define its own SetKeywordValue");
+  static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::SetIntValue),
+                 decltype(&MOZ_STYLO_SERVO_TYPE::SetKeywordValue)>
+        ::value, "Servo subclass should define its own SetKeywordValue");
+
+  if (IsServo()) {
+    return AsServo()->SetKeywordValue(aId, aValue);
+  }
+  return AsGecko()->SetKeywordValue(aId, aValue);
+}
+
+void
+GenericSpecifiedValues::SetKeywordValueIfUnset(nsCSSPropertyID aId, int32_t aValue)
+{
+  // there are some static asserts in MOZ_STYLO_FORWARD which
+  // won't work with the overloaded SetKeywordValue function,
+  // so we copy its expansion and use SetIntValue for decltype
+  // instead
+  static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::SetIntValue),
+                 decltype(&MOZ_STYLO_GECKO_TYPE::SetKeywordValueIfUnset)>
+        ::value, "Gecko subclass should define its own SetKeywordValueIfUnset");
+  static_assert(!mozilla::IsSame<decltype(&MOZ_STYLO_THIS_TYPE::SetIntValue),
+                 decltype(&MOZ_STYLO_SERVO_TYPE::SetKeywordValueIfUnset)>
+        ::value, "Servo subclass should define its own SetKeywordValueIfUnset");
+
+  if (IsServo()) {
+    return AsServo()->SetKeywordValueIfUnset(aId, aValue);
+  }
+  return AsGecko()->SetKeywordValueIfUnset(aId, aValue);
+}
+
+void
+GenericSpecifiedValues::SetIntValue(nsCSSPropertyID aId, int32_t aValue)
+{
+  MOZ_STYLO_FORWARD(SetIntValue, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetPixelValue(nsCSSPropertyID aId, float aValue)
+{
+  MOZ_STYLO_FORWARD(SetPixelValue, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetPixelValueIfUnset(nsCSSPropertyID aId, float aValue)
+{
+  MOZ_STYLO_FORWARD(SetPixelValueIfUnset, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetPercentValue(nsCSSPropertyID aId, float aValue)
+{
+  MOZ_STYLO_FORWARD(SetPercentValue, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetPercentValueIfUnset(nsCSSPropertyID aId, float aValue)
+{
+  MOZ_STYLO_FORWARD(SetPercentValueIfUnset, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetAutoValue(nsCSSPropertyID aId)
+{
+  MOZ_STYLO_FORWARD(SetAutoValue, (aId))
+}
+
+void
+GenericSpecifiedValues::SetAutoValueIfUnset(nsCSSPropertyID aId)
+{
+  MOZ_STYLO_FORWARD(SetAutoValueIfUnset, (aId))
+}
+
+void
+GenericSpecifiedValues::SetCurrentColor(nsCSSPropertyID aId)
+{
+  MOZ_STYLO_FORWARD(SetCurrentColor, (aId))
+}
+
+void
+GenericSpecifiedValues::SetCurrentColorIfUnset(nsCSSPropertyID aId)
+{
+  MOZ_STYLO_FORWARD(SetCurrentColorIfUnset, (aId))
+}
+
+void
+GenericSpecifiedValues::SetColorValue(nsCSSPropertyID aId, nscolor aValue)
+{
+  MOZ_STYLO_FORWARD(SetColorValue, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue)
+{
+  MOZ_STYLO_FORWARD(SetColorValueIfUnset, (aId, aValue))
+}
+
+void
+GenericSpecifiedValues::SetFontFamily(const nsString& aValue)
+{
+  MOZ_STYLO_FORWARD(SetFontFamily, (aValue))
+}
+
+void
+GenericSpecifiedValues::SetTextDecorationColorOverride()
+{
+  MOZ_STYLO_FORWARD(SetTextDecorationColorOverride, ())
+}
+
+} // namespace mozilla
+
+#endif // mozilla_GenericSpecifiedValuesInlines_h
\ No newline at end of file
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -82,16 +82,17 @@ EXPORTS.mozilla += [
     'CSSStyleSheet.h',
     'CSSVariableDeclarations.h',
     'CSSVariableResolver.h',
     'CSSVariableValues.h',
     'DeclarationBlock.h',
     'DeclarationBlockInlines.h',
     'DocumentStyleRootIterator.h',
     'GenericSpecifiedValues.h',
+    'GenericSpecifiedValuesInlines.h',
     'HandleRefPtr.h',
     'IncrementalClearCOMRuleArray.h',
     'LayerAnimationInfo.h',
     'PreloadedStyleSheet.h',
     'RuleNodeCacheConditions.h',
     'RuleProcessorCache.h',
     'ServoArcTypeList.h',
     'ServoBindingList.h',
--- a/layout/style/nsRuleData.cpp
+++ b/layout/style/nsRuleData.cpp
@@ -23,18 +23,17 @@ nsRuleData::GetPoisonOffset()
                 "expect size_t to be unsigned");
   uintptr_t framePoisonValue = mozPoisonValue();
   return size_t(framePoisonValue - uintptr_t(mValueStorage)) /
          sizeof(nsCSSValue);
 }
 
 nsRuleData::nsRuleData(uint32_t aSIDs, nsCSSValue* aValueStorage,
                        nsPresContext* aContext, nsStyleContext* aStyleContext)
-  : mSIDs(aSIDs),
-    mPresContext(aContext),
+  : GenericSpecifiedValues(StyleBackendType::Gecko, aContext, aSIDs),
     mStyleContext(aStyleContext),
     mValueStorage(aValueStorage)
 {
 #ifndef MOZ_VALGRIND
   size_t framePoisonOffset = GetPoisonOffset();
   for (size_t i = 0; i < nsStyleStructID_Length; ++i) {
     mValueOffsets[i] = framePoisonOffset;
   }
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -21,23 +21,21 @@
 #include "nsStyleStructFwd.h"
 
 class nsPresContext;
 class nsStyleContext;
 struct nsRuleData;
 
 typedef void (*nsPostResolveFunc)(void* aStyleStruct, nsRuleData* aData);
 
-struct nsRuleData final: GenericSpecifiedValues
+struct nsRuleData final: mozilla::GenericSpecifiedValues
 {
-  const uint32_t mSIDs;
   mozilla::RuleNodeCacheConditions mConditions;
   bool mIsImportantRule;
   mozilla::SheetType mLevel;
-  nsPresContext* const mPresContext;
   nsStyleContext* const mStyleContext;
 
   // We store nsCSSValues needed to compute the data for one or more
   // style structs (specified by the bitfield mSIDs).  These are stored
   // in a single array allocation (which our caller allocates; see
   // AutoCSSValueArray)   The offset of each property |prop| in
   // mValueStorage is the sum of
   // mValueOffsets[nsCSSProps::kSIDTable[prop]] and
@@ -117,118 +115,110 @@ struct nsRuleData final: GenericSpecifie
     }
   #define CSS_PROP_LIST_EXCLUDE_LOGICAL
   #include "nsCSSPropList.h"
   #undef CSS_PROP_LIST_EXCLUDE_LOGICAL
   #undef CSS_PROP
   #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
   // GenericSpecifiedValues overrides
-  bool PropertyIsSet(nsCSSPropertyID aId) override {
+  bool PropertyIsSet(nsCSSPropertyID aId) {
     return ValueFor(aId)->GetUnit() != eCSSUnit_Null;
   }
 
-  bool ShouldComputeStyleStruct(uint64_t aInheritBits) override {
-    return mSIDs & aInheritBits;
-  }
-
-  nsPresContext* PresContext() override {
-    return mPresContext;
-  }
-
   void SetIdentStringValue(nsCSSPropertyID aId,
-                           const nsString& aValue) override {
+                           const nsString& aValue) {
     ValueFor(aId)->SetStringValue(aValue, eCSSUnit_Ident);
   }
 
   void SetIdentStringValueIfUnset(nsCSSPropertyID aId,
-                                const nsString& aValue) override {
+                                const nsString& aValue) {
     if (!PropertyIsSet(aId)) {
       SetIdentStringValue(aId, aValue);
     }
   }
 
   void SetKeywordValue(nsCSSPropertyID aId,
-                       int32_t aValue) override {
+                       int32_t aValue) {
     ValueFor(aId)->SetIntValue(aValue, eCSSUnit_Enumerated);
   }
 
   void SetKeywordValueIfUnset(nsCSSPropertyID aId,
-                              int32_t aValue) override {
+                              int32_t aValue) {
     if (!PropertyIsSet(aId)) {
       SetKeywordValue(aId, aValue);
     }
   }
 
 
   void SetIntValue(nsCSSPropertyID aId,
-                   int32_t aValue) override {
+                   int32_t aValue) {
     ValueFor(aId)->SetIntValue(aValue, eCSSUnit_Integer);
   }
 
   void SetPixelValue(nsCSSPropertyID aId,
-                     float aValue) override {
+                     float aValue) {
     ValueFor(aId)->SetFloatValue(aValue, eCSSUnit_Pixel);
   }
 
   void SetPixelValueIfUnset(nsCSSPropertyID aId,
-                            float aValue) override {
+                            float aValue) {
     if (!PropertyIsSet(aId)) {
       SetPixelValue(aId, aValue);
     }
   }
 
   void SetPercentValue(nsCSSPropertyID aId,
-                       float aValue) override {
+                       float aValue) {
     ValueFor(aId)->SetPercentValue(aValue);
   }
 
-  void SetAutoValue(nsCSSPropertyID aId) override {
+  void SetAutoValue(nsCSSPropertyID aId) {
     ValueFor(aId)->SetAutoValue();
   }
 
-  void SetAutoValueIfUnset(nsCSSPropertyID aId) override {
+  void SetAutoValueIfUnset(nsCSSPropertyID aId) {
     if (!PropertyIsSet(aId)) {
       SetAutoValue(aId);
     }
   }
 
   void SetPercentValueIfUnset(nsCSSPropertyID aId,
-                              float aValue) override {
+                              float aValue) {
     if (!PropertyIsSet(aId)) {
       SetPercentValue(aId, aValue);
     }
   }
 
-  void SetCurrentColor(nsCSSPropertyID aId) override {
+  void SetCurrentColor(nsCSSPropertyID aId) {
     ValueFor(aId)->SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
   }
 
-  void SetCurrentColorIfUnset(nsCSSPropertyID aId) override {
+  void SetCurrentColorIfUnset(nsCSSPropertyID aId) {
     if (!PropertyIsSet(aId)) {
       SetCurrentColor(aId);
     }
   }
 
   void SetColorValue(nsCSSPropertyID aId,
-                     nscolor aValue) override {
+                     nscolor aValue) {
     ValueFor(aId)->SetColorValue(aValue);
   }
 
   void SetColorValueIfUnset(nsCSSPropertyID aId,
-                            nscolor aValue) override {
+                            nscolor aValue) {
     if (!PropertyIsSet(aId)) {
       SetColorValue(aId, aValue);
     }
   }
 
-  void SetFontFamily(const nsString& aValue) override;
-  void SetTextDecorationColorOverride() override;
+  void SetFontFamily(const nsString& aValue);
+  void SetTextDecorationColorOverride();
 
-  nsRuleData* AsRuleData() override {
+  nsRuleData* AsRuleData() {
     return this;
   }
 
 private:
   inline size_t GetPoisonOffset();
 
 };