Backed out changesets b749fc196a50, 2791eac8d760 (bug 1355721) for build bustage
authorGregory Szorc <gps@mozilla.com>
Thu, 24 Aug 2017 20:30:17 -0700
changeset 426256 e28de8d5a10728d257c452e5e5aa6b550642b676
parent 426255 4c480935fe7f76cb4c057d8ec0f09bf0d7b511e0
child 426257 51ae9cd5f5130686b226cb06b862ef37d1604c4c
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1355721
milestone57.0a1
backs outb749fc196a5089dbd200cca4d840d3a8cfe26713
2791eac8d760aa51a213ccafc85c14059112e381
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
Backed out changesets b749fc196a50, 2791eac8d760 (bug 1355721) for build bustage CLOSED TREE
gfx/thebes/gfxFontFeatures.cpp
gfx/thebes/gfxFontFeatures.h
js/src/devtools/rootAnalysis/analyzeHeapWrites.js
layout/base/PresShell.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/style/ServoBindingList.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/StyleSetHandle.h
layout/style/StyleSetHandleInlines.h
layout/style/nsCSSRules.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/gfx/thebes/gfxFontFeatures.cpp
+++ b/gfx/thebes/gfxFontFeatures.cpp
@@ -47,36 +47,26 @@ gfxFontFeatureValueSet::AddFontFeatureVa
 
     uint32_t i, numFeatureValues = aValues.Length();
     for (i = 0; i < numFeatureValues; i++) {
         const FeatureValues& fv = aValues.ElementAt(i);
         uint32_t alternate = fv.alternate;
         uint32_t j, numValues = fv.valuelist.Length();
         for (j = 0; j < numValues; j++) {
             const ValueList& v = fv.valuelist.ElementAt(j);
-            auto* array = AppendFeatureValueHashEntry(family, v.name, alternate);
-            *array = v.featureSelectors;
+            nsAutoString name(v.name);
+            ToLowerCase(name);
+            FeatureValueHashKey key(family, alternate, name);
+            FeatureValueHashEntry *entry = mFontFeatureValues.PutEntry(key);
+            entry->mKey = key;
+            entry->mValues = v.featureSelectors;
         }
     }
 }
 
-
-nsTArray<uint32_t>*
-gfxFontFeatureValueSet::AppendFeatureValueHashEntry(const nsAString& aFamily,
-                                                    const nsAString& aName,
-                                                    uint32_t aAlternate)
-{
-    nsAutoString name(aName);
-    ToLowerCase(name);
-    FeatureValueHashKey key(aFamily, aAlternate, name);
-    FeatureValueHashEntry *entry = mFontFeatureValues.PutEntry(key);
-    entry->mKey = key;
-    return &entry->mValues;
-}
-
 bool
 gfxFontFeatureValueSet::FeatureValueHashEntry::KeyEquals(
                                                const KeyTypePointer aKey) const
 {
     return aKey->mPropVal == mKey.mPropVal &&
            aKey->mFamily.Equals(mKey.mFamily) &&
            aKey->mName.Equals(mKey.mName);
 }
--- a/gfx/thebes/gfxFontFeatures.h
+++ b/gfx/thebes/gfxFontFeatures.h
@@ -45,17 +45,17 @@ operator<(const gfxAlternateValue& a, co
 inline bool
 operator==(const gfxAlternateValue& a, const gfxAlternateValue& b)
 {
     return (a.alternate == b.alternate) && (a.value == b.value);
 }
 
 class gfxFontFeatureValueSet final {
 public:
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFeatureValueSet)
+    NS_INLINE_DECL_REFCOUNTING(gfxFontFeatureValueSet)
 
     gfxFontFeatureValueSet();
 
     struct ValueList {
         ValueList(const nsAString& aName, const nsTArray<uint32_t>& aSelectors)
           : name(aName), featureSelectors(aSelectors)
         {}
         nsString             name;
@@ -72,23 +72,16 @@ public:
     GetFontFeatureValuesFor(const nsAString& aFamily,
                             uint32_t aVariantProperty,
                             const nsAString& aName,
                             nsTArray<uint32_t>& aValues);
     void
     AddFontFeatureValues(const nsAString& aFamily,
                 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aValues);
 
-    // Appends a new hash entry with given key values and returns a pointer to
-    // mValues array to fill. This should be filled first.
-    nsTArray<uint32_t>*
-    AppendFeatureValueHashEntry(const nsAString& aFamily,
-                                const nsAString& aName,
-                                uint32_t aAlternate);
-
 private:
     // Private destructor, to discourage deletion outside of Release():
     ~gfxFontFeatureValueSet() {}
 
     struct FeatureValueHashKey {
         nsString mFamily;
         uint32_t mPropVal;
         nsString mName;
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -209,18 +209,16 @@ function treatAsSafeArgument(entry, varN
         ["Gecko_ClearWillChange", "aDisplay", null],
         ["Gecko_AppendWillChange", "aDisplay", null],
         ["Gecko_CopyWillChangeFrom", "aDest", null],
         ["Gecko_InitializeImageCropRect", "aImage", null],
         ["Gecko_CopyShapeSourceFrom", "aDst", null],
         ["Gecko_DestroyShapeSource", "aShape", null],
         ["Gecko_StyleShapeSource_SetURLValue", "aShape", null],
         ["Gecko_nsFont_InitSystem", "aDest", null],
-        ["Gecko_nsFont_SetFontFeatureValuesLookup", "aFont", null],
-        ["Gecko_nsFont_ResetFontFeatureValuesLookup", "aFont", null],
         ["Gecko_nsStyleFont_FixupNoneGeneric", "aFont", null],
         ["Gecko_StyleTransition_SetUnsupportedProperty", "aTransition", null],
         ["Gecko_AddPropertyToSet", "aPropertySet", null],
         ["Gecko_CalcStyleDifference", "aAnyStyleChanged", null],
         ["Gecko_nsStyleSVG_CopyContextProperties", "aDst", null],
         ["Gecko_nsStyleFont_PrefillDefaultForGeneric", "aFont", null],
         ["Gecko_nsStyleSVG_SetContextPropertiesLength", "aSvg", null],
         ["Gecko_ClearAlternateValues", "aFont", null],
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4153,18 +4153,16 @@ PresShell::DoFlushPendingNotifications(m
 
       // Flush any pending update of the user font set, since that could
       // cause style changes (for updating ex/ch units, and to cause a
       // reflow).
       mDocument->FlushUserFontSet();
 
       mPresContext->FlushCounterStyles();
 
-      mPresContext->FlushFontFeatureValues();
-
       // Flush any requested SMIL samples.
       if (mDocument->HasAnimationController()) {
         mDocument->GetAnimationController()->FlushResampleRequests();
       }
 
       if (aFlush.mFlushAnimations && mPresContext->EffectCompositor()) {
         mPresContext->EffectCompositor()->PostRestyleForThrottledAnimations();
       }
@@ -4546,17 +4544,16 @@ nsIPresShell::RestyleForCSSRuleChanges()
     // We don't want to mess with restyles at this point
     return;
   }
 
   mDocument->RebuildUserFontSet();
 
   if (mPresContext) {
     mPresContext->RebuildCounterStyles();
-    mPresContext->RebuildFontFeatureValues();
   }
 
   if (!mDidInitialize) {
     // Nothing to do here, since we have no frames yet
     return;
   }
 
   mStyleSet->InvalidateStyleForCSSRuleChanges();
@@ -9150,18 +9147,16 @@ PresShell::DidCauseReflow()
 
 void
 PresShell::WillDoReflow()
 {
   mDocument->FlushUserFontSet();
 
   mPresContext->FlushCounterStyles();
 
-  mPresContext->FlushFontFeatureValues();
-
   mFrameConstructor->BeginUpdate();
 
   mLastReflowStart = GetPerformanceNow();
 }
 
 void
 PresShell::DidDoReflow(bool aInterruptible)
 {
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -273,18 +273,16 @@ nsPresContext::nsPresContext(nsIDocument
     mPrefChangePendingNeedsReflow(false),
     mIsEmulatingMedia(false),
     mIsGlyph(false),
     mUsesRootEMUnits(false),
     mUsesExChUnits(false),
     mPendingViewportChange(false),
     mCounterStylesDirty(true),
     mPostedFlushCounterStyles(false),
-    mFontFeatureValuesDirty(true),
-    mPostedFlushFontFeatureValues(false),
     mSuppressResizeReflow(false),
     mIsVisual(false),
     mFireAfterPaintEvents(false),
     mIsChrome(false),
     mIsChromeOriginImage(false),
     mPaintFlashing(false),
     mPaintFlashingInitialized(false),
     mHasWarnedAboutPositionedTableParts(false),
@@ -2066,17 +2064,16 @@ nsPresContext::RebuildAllStyleData(nsCha
 
   mUsesRootEMUnits = false;
   mUsesExChUnits = false;
   if (nsStyleSet* styleSet = mShell->StyleSet()->GetAsGecko()) {
     styleSet->SetUsesViewportUnits(false);
   }
   mDocument->RebuildUserFontSet();
   RebuildCounterStyles();
-  RebuildFontFeatureValues();
 
   RestyleManager()->RebuildAllStyleData(aExtraHint, aRestyleHint);
 }
 
 void
 nsPresContext::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
                                             nsRestyleHint aRestyleHint)
 {
@@ -3124,52 +3121,16 @@ nsPresContext::GetBidiEngine()
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mBidiEngine) {
     mBidiEngine.reset(new nsBidi());
   }
   return *mBidiEngine;
 }
 
-void
-nsPresContext::FlushFontFeatureValues()
-{
-  if (!mShell) {
-    return; // we've been torn down
-  }
-
-  if (mFontFeatureValuesDirty) {
-    StyleSetHandle styleSet = mShell->StyleSet();
-    mFontFeatureValuesLookup = styleSet->BuildFontFeatureValueSet();
-    mFontFeatureValuesDirty = false;
-  }
-}
-
-void
-nsPresContext::RebuildFontFeatureValues()
-{
-  if (!mShell) {
-    return; // we've been torn down
-  }
-
-  mFontFeatureValuesDirty = true;
-  mShell->SetNeedStyleFlush();
-
-  if (!mPostedFlushFontFeatureValues) {
-    nsCOMPtr<nsIRunnable> ev =
-      NewRunnableMethod("nsPresContext::HandleRebuildFontFeatureValues",
-                        this, &nsPresContext::HandleRebuildFontFeatureValues);
-    nsresult rv =
-      Document()->Dispatch(TaskCategory::Other, ev.forget());
-    if (NS_SUCCEEDED(rv)) {
-      mPostedFlushFontFeatureValues = true;
-    }
-  }
-}
-
 nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
                                      nsPresContextType aType)
   : nsPresContext(aDocument, aType),
     mDOMGeneration(0)
 {
 }
 
 nsRootPresContext::~nsRootPresContext()
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -54,21 +54,19 @@ class nsIDocShell;
 class nsIDocument;
 class nsITheme;
 class nsIContent;
 class nsIFrame;
 class nsFrameManager;
 class nsILinkHandler;
 class nsIAtom;
 class nsIRunnable;
-class gfxFontFeatureValueSet;
 class gfxUserFontEntry;
 class gfxUserFontSet;
 class gfxTextPerfMetrics;
-class nsCSSFontFeatureValuesRule;
 class nsPluginFrame;
 class nsTransitionManager;
 class nsAnimationManager;
 class nsRefreshDriver;
 class nsIWidget;
 class nsDeviceContext;
 class gfxMissingFontRecorder;
 
@@ -1005,19 +1003,16 @@ public:
   void UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont = nullptr);
 
   gfxMissingFontRecorder *MissingFontRecorder() { return mMissingFonts; }
   void NotifyMissingFonts();
 
   void FlushCounterStyles();
   void RebuildCounterStyles(); // asynchronously
 
-  void FlushFontFeatureValues();
-  void RebuildFontFeatureValues(); // asynchronously
-
   // Ensure that it is safe to hand out CSS rules outside the layout
   // engine by ensuring that all CSS style sheets have unique inners
   // and, if necessary, synchronously rebuilding all style data.
   void EnsureSafeToHandOutCSSRules();
 
   // Mark an area as invalidated, associated with a given transaction id (allocated
   // by nsRefreshDriver::GetTransactionId).
   // Invalidated regions will be dispatched to MozAfterPaint events when
@@ -1184,20 +1179,16 @@ public:
   }
 
   void SetHasWarnedAboutTooLargeDashedOrDottedRadius() {
     mHasWarnedAboutTooLargeDashedOrDottedRadius = true;
   }
 
   nsBidi& GetBidiEngine();
 
-  gfxFontFeatureValueSet* GetFontFeatureValuesLookup() const {
-    return mFontFeatureValuesLookup;
-  }
-
 protected:
   friend class nsRunnableMethod<nsPresContext>;
   void ThemeChangedInternal();
   void SysColorChangedInternal();
   void RefreshSystemMetrics();
 
   // update device context's resolution from the widget
   void UIResolutionChangedInternal();
@@ -1270,21 +1261,16 @@ protected:
 
   void AppUnitsPerDevPixelChanged();
 
   void HandleRebuildCounterStyles() {
     mPostedFlushCounterStyles = false;
     FlushCounterStyles();
   }
 
-  void HandleRebuildFontFeatureValues() {
-    mPostedFlushFontFeatureValues = false;
-    FlushFontFeatureValues();
-  }
-
   bool HavePendingInputEvent();
 
   // Can't be inline because we can't include nsStyleSet.h.
   bool HasCachedStyleData();
 
   // Creates a one-shot timer with the given aCallback & aDelay.
   // Returns a refcounted pointer to the timer (or nullptr on failure).
   already_AddRefed<nsITimer> CreateTimer(nsTimerCallbackFunc aCallback,
@@ -1309,17 +1295,16 @@ protected:
   RefPtr<nsRefreshDriver> mRefreshDriver;
   RefPtr<mozilla::EffectCompositor> mEffectCompositor;
   RefPtr<nsTransitionManager> mTransitionManager;
   RefPtr<nsAnimationManager> mAnimationManager;
   RefPtr<mozilla::RestyleManager> mRestyleManager;
   RefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
   nsIAtom* MOZ_UNSAFE_REF("always a static atom") mMedium; // initialized by subclass ctors
   nsCOMPtr<nsIAtom> mMediaEmulated;
-  RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
 
   // This pointer is nulled out through SetLinkHandler() in the destructors of
   // the classes which set it. (using SetLinkHandler() again).
   nsILinkHandler* MOZ_NON_OWNING_REF mLinkHandler;
 
   // Formerly mLangGroup; moving from charset-oriented langGroup to
   // maintaining actual language settings everywhere (see bug 524107).
   // This may in fact hold a langGroup such as x-western rather than
@@ -1479,21 +1464,16 @@ protected:
   // Has there been a change to the viewport's dimensions?
   unsigned              mPendingViewportChange : 1;
 
   // Is the current mCounterStyleManager valid?
   unsigned              mCounterStylesDirty : 1;
   // Do we currently have an event posted to call FlushCounterStyles?
   unsigned              mPostedFlushCounterStyles: 1;
 
-  // Is the current mFontFeatureValuesLookup valid?
-  unsigned              mFontFeatureValuesDirty : 1;
-  // Do we currently have an event posted to call FlushFontFeatureValues?
-  unsigned              mPostedFlushFontFeatureValues: 1;
-
   // resize reflow is suppressed when the only change has been to zoom
   // the document rather than to change the document's dimensions
   unsigned              mSuppressResizeReflow : 1;
 
   unsigned              mIsVisual : 1;
 
   unsigned              mFireAfterPaintEvents : 1;
 
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -99,19 +99,16 @@ SERVO_BINDING_FUNC(Servo_StyleSet_GetKey
                    const nsACString* property,
                    nsTimingFunctionBorrowed timing_function,
                    RawGeckoKeyframeListBorrowedMut keyframe_list)
 SERVO_BINDING_FUNC(Servo_StyleSet_GetFontFaceRules, void,
                    RawServoStyleSetBorrowed set,
                    RawGeckoFontFaceRuleListBorrowedMut list)
 SERVO_BINDING_FUNC(Servo_StyleSet_GetCounterStyleRule, nsCSSCounterStyleRule*,
                    RawServoStyleSetBorrowed set, nsIAtom* name)
-SERVO_BINDING_FUNC(Servo_StyleSet_BuildFontFeatureValueSet, bool,
-                   RawServoStyleSetBorrowed set,
-                   gfxFontFeatureValueSet* list)
 SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations,
                    ServoStyleContextStrong,
                    RawServoStyleSetBorrowed set,
                    ServoStyleContextBorrowedOrNull parent_style,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_StyleContext_AddRef, void, ServoStyleContextBorrowed ctx);
 SERVO_BINDING_FUNC(Servo_StyleContext_Release, void, ServoStyleContextBorrowed ctx);
 
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ServoBindings.h"
 
 #include "ChildIterator.h"
 #include "ErrorReporter.h"
 #include "GeckoProfiler.h"
 #include "gfxFontFamilyList.h"
-#include "gfxFontFeatures.h"
 #include "nsAnimationManager.h"
 #include "nsAttrValueInlines.h"
 #include "nsCSSCounterStyleRule.h"
 #include "nsCSSFontFaceRule.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsCSSProps.h"
 #include "nsCSSParser.h"
 #include "nsCSSPseudoElements.h"
@@ -1337,41 +1336,16 @@ Gecko_nsFont_InitSystem(nsFont* aDest, i
 }
 
 void
 Gecko_nsFont_Destroy(nsFont* aDest)
 {
   aDest->~nsFont();
 }
 
-nsTArrayBorrowed_uint32_t
-Gecko_AppendFeatureValueHashEntry(gfxFontFeatureValueSet* aFontFeatureValues,
-                                  nsIAtom* aFamily, uint32_t aAlternate, nsIAtom* aName)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  return aFontFeatureValues->AppendFeatureValueHashEntry(
-    nsDependentAtomString(aFamily),
-    nsDependentAtomString(aName),
-    aAlternate
-  );
-}
-
-void
-Gecko_nsFont_SetFontFeatureValuesLookup(nsFont* aFont,
-                                        const RawGeckoPresContext* aPresContext)
-{
-  aFont->featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
-}
-
-void
-Gecko_nsFont_ResetFontFeatureValuesLookup(nsFont* aFont)
-{
-  aFont->featureValueLookup = nullptr;
-}
-
 
 void
 Gecko_ClearAlternateValues(nsFont* aFont, size_t aLength)
 {
   aFont->alternateValues.Clear();
   aFont->alternateValues.SetCapacity(aLength);
 }
 
@@ -1384,17 +1358,16 @@ Gecko_AppendAlternateValues(nsFont* aFon
   });
 }
 
 void
 Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc)
 {
   aDest->alternateValues.Clear();
   aDest->alternateValues.AppendElements(aSrc->alternateValues);
-  aDest->featureValueLookup = aSrc->featureValueLookup;
 }
 
 void
 Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
                           uint8_t aOrientation, bool aFlip)
 {
   aVisibility->mImageOrientation =
     nsStyleImageOrientation::CreateAsOrientationAndFlip(aOrientation, aFlip);
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -104,17 +104,16 @@ namespace mozilla {
     { MOZ_ASSERT(NS_IsMainThread()); NS_RELEASE(aPtr); }
 
 #define DEFINE_ARRAY_TYPE_FOR(type_)                                \
   struct nsTArrayBorrowed_##type_ {                                 \
     nsTArray<type_>* mArray;                                        \
     MOZ_IMPLICIT nsTArrayBorrowed_##type_(nsTArray<type_>* aArray)  \
       : mArray(aArray) {}                                           \
   }
-DEFINE_ARRAY_TYPE_FOR(uint32_t);
 DEFINE_ARRAY_TYPE_FOR(uintptr_t);
 #undef DEFINE_ARRAY_TYPE_FOR
 
 extern "C" {
 
 class ServoBundledURI
 {
 public:
@@ -297,22 +296,16 @@ void Gecko_FontFamilyList_AppendNamed(Fo
 void Gecko_FontFamilyList_AppendGeneric(FontFamilyList* list, FontFamilyType familyType);
 void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src);
 // will not run destructors on dst, give it uninitialized memory
 // font_id is LookAndFeel::FontID
 void Gecko_nsFont_InitSystem(nsFont* dst, int32_t font_id,
                              const nsStyleFont* font, RawGeckoPresContextBorrowed pres_context);
 void Gecko_nsFont_Destroy(nsFont* dst);
 
-nsTArrayBorrowed_uint32_t Gecko_AppendFeatureValueHashEntry(
-  gfxFontFeatureValueSet* value_set, nsIAtom* family, uint32_t alternate, nsIAtom* name);
-void Gecko_nsFont_SetFontFeatureValuesLookup(nsFont* font,
-                                             const RawGeckoPresContext* pres_context);
-void Gecko_nsFont_ResetFontFeatureValuesLookup(nsFont* font);
-
 // Font variant alternates
 void Gecko_ClearAlternateValues(nsFont* font, size_t length);
 void Gecko_AppendAlternateValues(nsFont* font, uint32_t alternate_name, nsIAtom* atom);
 void Gecko_CopyAlternateValuesFrom(nsFont* dest, const nsFont* src);
 
 // Visibility style
 void Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
                                uint8_t aOrientation,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -41,17 +41,16 @@ args = [
 "arch=x86_64" = ["--target=x86_64-pc-win32"]
 
 [structs]
 headers = [
     "nsStyleStruct.h",
     "mozilla/ServoPropPrefList.h",
     "mozilla/StyleAnimationValue.h",
     "gfxFontConstants.h",
-    "gfxFontFeatures.h",
     "nsThemeConstants.h",
     "mozilla/css/Loader.h",
     "mozilla/dom/AnimationEffectReadOnlyBinding.h",
     "mozilla/dom/KeyframeEffectBinding.h",
     "mozilla/AnimationPropertySegment.h",
     "mozilla/ComputedTiming.h",
     "mozilla/ComputedTimingFunction.h",
     "mozilla/Keyframe.h",
@@ -162,17 +161,16 @@ whitelist-types = [
     "FontFamilyType",
     "FontSizePrefs",
     "FragmentOrURL",
     "FrameRequestCallback",
     "GeckoParserExtraData",
     "GeckoFontMetrics",
     "gfxAlternateValue",
     "gfxFontFeature",
-    "gfxFontFeatureValueSet",
     "gfxFontVariation",
     "GridNamedArea",
     "HalfCorner",
     "Image",
     "ImageURL",
     "Keyframe",
     "nsAttrName",
     "nsAttrValue",
@@ -417,17 +415,16 @@ structs-types = [
     "ServoBundledURI",
     "ServoElementSnapshot",
     "ServoElementSnapshotTable",
     "SheetParsingMode",
     "StyleBasicShape",
     "StyleBasicShapeType",
     "StyleShapeSource",
     "StyleTransition",
-    "gfxFontFeatureValueSet",
     "nsBorderColors",
     "nsCSSCounterStyleRule",
     "nsCSSFontFaceRule",
     "nsCSSKeyword",
     "nsCSSPropertyID",
     "nsCSSPropertyIDSet",
     "nsCSSShadowArray",
     "nsCSSUnit",
@@ -501,17 +498,16 @@ structs-types = [
     "InheritTarget",
     "URLMatchingFunction",
     "StyleRuleInclusion",
     "nsStyleTransformMatrix::MatrixTransformOperator",
     "RawGeckoGfxMatrix4x4",
 ]
 array-types = [
     { cpp-type = "uintptr_t", rust-type = "usize" },
-    { cpp-type = "uint32_t", rust-type = "u32" },
 ]
 servo-owned-types = [
     { name = "RawServoStyleSet", opaque = true },
     { name = "ServoElementSnapshot", opaque = false },
     { name = "RawServoAnimationValueMap", opaque = true },
 ]
 servo-immutable-borrow-types = [
     "RawGeckoNode",
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1373,28 +1373,16 @@ ServoStyleSet::AppendFontFaceRules(nsTAr
 }
 
 nsCSSCounterStyleRule*
 ServoStyleSet::CounterStyleRuleForName(nsIAtom* aName)
 {
   return Servo_StyleSet_GetCounterStyleRule(mRawSet.get(), aName);
 }
 
-already_AddRefed<gfxFontFeatureValueSet>
-ServoStyleSet::BuildFontFeatureValueSet()
-{
-  UpdateStylistIfNeeded();
-  RefPtr<gfxFontFeatureValueSet> set = new gfxFontFeatureValueSet();
-  bool setHasAnyRules = Servo_StyleSet_BuildFontFeatureValueSet(mRawSet.get(), set.get());
-  if (!setHasAnyRules) {
-    return nullptr;
-  }
-  return set.forget();
-}
-
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveForDeclarations(
   const ServoStyleContext* aParentOrNull,
   RawServoDeclarationBlockBorrowed aDeclarations)
 {
   UpdateStylistIfNeeded();
   return Servo_StyleSet_ResolveForDeclarations(mRawSet.get(),
                                                aParentOrNull,
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -368,19 +368,16 @@ public:
                      dom::Element* aElement,
                      const ServoStyleContext* aContext,
                      nsTArray<RefPtr<RawServoAnimationValue>>& aAnimationValues);
 
   bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
 
   nsCSSCounterStyleRule* CounterStyleRuleForName(nsIAtom* aName);
 
-  // Get all the currently-active font feature values set.
-  already_AddRefed<gfxFontFeatureValueSet> BuildFontFeatureValueSet();
-
   already_AddRefed<ServoStyleContext>
   GetBaseContextForElement(dom::Element* aElement,
                            ServoStyleContext* aParentContext,
                            nsPresContext* aPresContext,
                            nsIAtom* aPseudoTag,
                            CSSPseudoElementType aPseudoType,
                            const ServoStyleContext* aStyle);
 
--- a/layout/style/StyleSetHandle.h
+++ b/layout/style/StyleSetHandle.h
@@ -29,17 +29,16 @@ class nsBindingManager;
 class nsCSSCounterStyleRule;
 struct nsFontFaceRuleContainer;
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
 class nsStyleContext;
 class nsStyleSet;
 class nsPresContext;
-class gfxFontFeatureValueSet;
 struct TreeMatchContext;
 
 namespace mozilla {
 
 #define SERVO_BIT 0x1
 
 /**
  * Smart pointer class that can hold a pointer to either an nsStyleSet
@@ -179,17 +178,16 @@ public:
         dom::Element* aPseudoElement,
         EventStates aStateMask);
 
     inline void RootStyleContextAdded();
     inline void RootStyleContextRemoved();
 
     inline bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
     inline nsCSSCounterStyleRule* CounterStyleRuleForName(nsIAtom* aName);
-    inline already_AddRefed<gfxFontFeatureValueSet> BuildFontFeatureValueSet();
 
     inline bool EnsureUniqueInnerOnCSSSheets();
     inline void SetNeedsRestyleAfterEnsureUniqueInner();
 
   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
--- a/layout/style/StyleSetHandleInlines.h
+++ b/layout/style/StyleSetHandleInlines.h
@@ -337,22 +337,16 @@ AppendFontFaceRules(nsTArray<nsFontFaceR
 }
 
 nsCSSCounterStyleRule*
 StyleSetHandle::Ptr::CounterStyleRuleForName(nsIAtom* aName)
 {
   FORWARD(CounterStyleRuleForName, (aName));
 }
 
-already_AddRefed<gfxFontFeatureValueSet>
-StyleSetHandle::Ptr::BuildFontFeatureValueSet()
-{
-  FORWARD(BuildFontFeatureValueSet, ());
-}
-
 bool
 StyleSetHandle::Ptr::EnsureUniqueInnerOnCSSSheets()
 {
   FORWARD(EnsureUniqueInnerOnCSSSheets, ());
 }
 
 void
 StyleSetHandle::Ptr::SetNeedsRestyleAfterEnsureUniqueInner()
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -175,19 +175,19 @@ public:
       mFamilyList(aCopy.mFamilyList),
       mFeatureValues(aCopy.mFeatureValues)
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
 #ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
-  already_AddRefed<mozilla::css::Rule> Clone() const final;
+  virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
   // nsIDOMCSSFontFeatureValuesRule interface
   NS_DECL_NSIDOMCSSFONTFEATUREVALUESRULE
 
   // WebIDL interface
   void GetCssTextImpl(nsAString& aCssText) const final;
 
   const mozilla::FontFamilyList& GetFamilyList() { return mFamilyList; }
@@ -196,17 +196,17 @@ public:
   void AddValueList(int32_t aVariantAlternate,
                     nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList);
 
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
   {
     return mFeatureValues;
   }
 
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
+  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
 protected:
   ~nsCSSFontFeatureValuesRule() {}
 
   mozilla::FontFamilyList mFamilyList;
   nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
 };
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3910,17 +3910,18 @@ nsRuleNode::SetFont(nsPresContext* aPres
     variantAlternates =
       variantAlternatesValue->GetPairValue().mXValue.GetIntValue();
     aFont->mFont.variantAlternates = variantAlternates;
 
     if (variantAlternates & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
       // fetch the feature lookup object from the styleset
       MOZ_ASSERT(aPresContext->StyleSet()->IsGecko(),
                  "ServoStyleSets should not have rule nodes");
-      aFont->mFont.featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
+      aFont->mFont.featureValueLookup =
+        aPresContext->StyleSet()->AsGecko()->GetFontFeatureValuesLookup();
 
       NS_ASSERTION(variantAlternatesValue->GetPairValue().mYValue.GetUnit() ==
                    eCSSUnit_List, "function list not a list value");
       nsStyleUtil::ComputeFunctionalAlternates(
         variantAlternatesValue->GetPairValue().mYValue.GetListValue(),
         aFont->mFont.alternateValues);
     }
     break;
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -212,16 +212,17 @@ nsStyleSet::IsCSSSheetType(SheetType aSh
 nsStyleSet::nsStyleSet()
   : mRuleTree(nullptr),
     mBatching(0),
     mStylesHaveChanged(0),
     mInShutdown(false),
     mInGC(false),
     mAuthorStyleDisabled(false),
     mInReconstruct(false),
+    mInitFontFeatureValuesLookup(true),
     mNeedsRestyleAfterEnsureUniqueInner(false),
     mUsesViewportUnits(false),
     mDirty(0),
     mRootStyleContextCount(0),
 #ifdef DEBUG
     mOldRootNode(nullptr),
 #endif
     mUnusedRuleNodeCount(0)
@@ -2277,39 +2278,16 @@ nsStyleSet::CounterStyleRuleForName(nsIA
     nsCSSCounterStyleRule *result =
       ruleProc->CounterStyleRuleForName(presContext, aName);
     if (result)
       return result;
   }
   return nullptr;
 }
 
-already_AddRefed<gfxFontFeatureValueSet>
-nsStyleSet::BuildFontFeatureValueSet()
-{
-  nsTArray<nsCSSFontFeatureValuesRule*> rules;
-  AppendFontFeatureValuesRules(rules);
-
-  if (rules.IsEmpty()) {
-    return nullptr;
-  }
-
-  RefPtr<gfxFontFeatureValueSet> set = new gfxFontFeatureValueSet();
-  for (nsCSSFontFeatureValuesRule* rule : rules) {
-    const nsTArray<FontFamilyName>& familyList = rule->GetFamilyList().GetFontlist();
-    const nsTArray<gfxFontFeatureValueSet::FeatureValues>&
-      featureValues = rule->GetFeatureValues();
-
-    for (const FontFamilyName& f : familyList) {
-      set->AddFontFeatureValues(f.mName, featureValues);
-    }
-  }
-  return set.forget();
-}
-
 bool
 nsStyleSet::AppendFontFeatureValuesRules(
                                  nsTArray<nsCSSFontFeatureValuesRule*>& aArray)
 {
   NS_ENSURE_FALSE(mInShutdown, false);
   NS_ASSERTION(mBatching == 0, "rule processors out of date");
 
   nsPresContext* presContext = PresContext();
@@ -2320,16 +2298,50 @@ nsStyleSet::AppendFontFeatureValuesRules
         !ruleProc->AppendFontFeatureValuesRules(presContext, aArray))
     {
       return false;
     }
   }
   return true;
 }
 
+already_AddRefed<gfxFontFeatureValueSet>
+nsStyleSet::GetFontFeatureValuesLookup()
+{
+  if (mInitFontFeatureValuesLookup) {
+    mInitFontFeatureValuesLookup = false;
+
+    nsTArray<nsCSSFontFeatureValuesRule*> rules;
+    AppendFontFeatureValuesRules(rules);
+
+    mFontFeatureValuesLookup = new gfxFontFeatureValueSet();
+
+    uint32_t i, numRules = rules.Length();
+    for (i = 0; i < numRules; i++) {
+      nsCSSFontFeatureValuesRule *rule = rules[i];
+
+      const nsTArray<FontFamilyName>& familyList = rule->GetFamilyList().GetFontlist();
+      const nsTArray<gfxFontFeatureValueSet::FeatureValues>&
+        featureValues = rule->GetFeatureValues();
+
+      // for each family
+      size_t f, numFam;
+
+      numFam = familyList.Length();
+      for (f = 0; f < numFam; f++) {
+        mFontFeatureValuesLookup->AddFontFeatureValues(familyList[f].mName,
+                                                       featureValues);
+      }
+    }
+  }
+
+  RefPtr<gfxFontFeatureValueSet> lookup = mFontFeatureValuesLookup;
+  return lookup.forget();
+}
+
 bool
 nsStyleSet::AppendPageRules(nsTArray<nsCSSPageRule*>& aArray)
 {
   NS_ENSURE_FALSE(mInShutdown, false);
   NS_ASSERTION(mBatching == 0, "rule processors out of date");
 
   nsPresContext* presContext = PresContext();
   for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) {
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -315,18 +315,18 @@ class nsStyleSet final
   bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
 
   // Return the winning (in the cascade) @keyframes rule for the given name.
   nsCSSKeyframesRule* KeyframesRuleForName(const nsString& aName);
 
   // Return the winning (in the cascade) @counter-style rule for the given name.
   nsCSSCounterStyleRule* CounterStyleRuleForName(nsIAtom* aName);
 
-  // Return gfxFontFeatureValueSet from font feature values rules.
-  already_AddRefed<gfxFontFeatureValueSet> BuildFontFeatureValueSet();
+  // Fetch object for looking up font feature values
+  already_AddRefed<gfxFontFeatureValueSet> GetFontFeatureValuesLookup();
 
   // Append all the currently-active font feature values rules to aArray.
   // Return true for success and false for failure.
   bool AppendFontFeatureValuesRules(
                               nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
 
   // Append all the currently-active page rules to aArray.  Return
   // true for success and false for failure.
@@ -638,16 +638,17 @@ private:
   // Indicates that the whole document must be restyled.  Changes to scoped
   // style sheets are recorded in mChangedScopeStyleRoots rather than here
   // in mStylesHaveChanged.
   unsigned mStylesHaveChanged : 1;
   unsigned mInShutdown : 1;
   unsigned mInGC : 1;
   unsigned mAuthorStyleDisabled: 1;
   unsigned mInReconstruct : 1;
+  unsigned mInitFontFeatureValuesLookup : 1;
   unsigned mNeedsRestyleAfterEnsureUniqueInner : 1;
   // Does the associated document use viewport units (vw/vh/vmin/vmax)?
   unsigned mUsesViewportUnits : 1;
   unsigned mDirty : int(mozilla::SheetType::Count);  // one bit per sheet type
 
   uint32_t mRootStyleContextCount;
 
 #ifdef DEBUG
@@ -672,16 +673,19 @@ private:
   // Style rule which sets all properties to their initial values for
   // determining when context-sensitive values are in use.
   RefPtr<nsInitialStyleRule> mInitialStyleRule;
 
   // Style rule that sets the internal -x-text-zoom property on
   // <svg:text> elements to disable the effect of text zooming.
   RefPtr<nsDisableTextZoomStyleRule> mDisableTextZoomStyleRule;
 
+  // whether font feature values lookup object needs initialization
+  RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
+
   // Stores pointers to our cached style contexts for non-inheriting anonymous
   // boxes.
   mozilla::EnumeratedArray<nsCSSAnonBoxes::NonInheriting,
                            nsCSSAnonBoxes::NonInheriting::_Count,
                            RefPtr<mozilla::GeckoStyleContext>> mNonInheritingStyleContexts;
 };
 
 #ifdef MOZILLA_INTERNAL_API