Low memory notification shouldn't cause style recalc
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jul 2017 19:53:55 +0000 (19:53 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jul 2017 19:53:55 +0000 (19:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173574
<rdar://problem/32616997>

Reviewed by Andreas Kling.

Source/WebCore:

Patch mostly by Myles.

When we receive a low memory warning, we clear the style resolver. Previously, we were using
this as an opportunity to also purge the CSSFontSelector. However, purging the font selector
is wasteful, since the exact same set of CSSFontFace objects will be recreated as soon as the
CSSFontSelector is recreated. It's also harmful because this purge operation causes fonts to
be removed from the document's working set, and therefore triggers a relayout. Instead, this
call should be softened to only delete any transitory caches the CSSFontSelector owns.

We can simply delay the rebuild of the CSSFontSelector to
StyleResolver::appendAuthorStyleSheets(), when it's really needed. This way, we can sidestep
this whole problem.

There's also an added benefit: Now, buildStarted() doesn't have to be idempotent, so we can
enforce a stricter calling sequence with ASSERT()s.

* css/CSSFontFaceSet.cpp:
(WebCore::CSSFontFaceSet::emptyCaches):
* css/CSSFontFaceSet.h:
* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::emptyCaches):

    Add a separate function to clear font selector caches.

(WebCore::CSSFontSelector::buildStarted):
(WebCore::CSSFontSelector::buildCompleted):
(WebCore::CSSFontSelector::addFontFaceRule):
(WebCore::CSSFontSelector::fontModified):

    No need to invalidate while building.

(WebCore::CSSFontSelector::fontRangesForFamily):
* css/CSSFontSelector.h:
* css/StyleResolver.cpp:
(WebCore::StyleResolver::StyleResolver):
(WebCore::StyleResolver::addCurrentSVGFontFaceRules):

    Factor into a function from the constructor.

(WebCore::StyleResolver::appendAuthorStyleSheets):

    Font selector build is now started and finished by StyleScope.

* css/StyleResolver.h:
* dom/Document.cpp:
(WebCore::Document::resolveStyle):

    Call FrameView::styleDidChange() to update any custom scrollbars.
    This bug was hidden by spurious style recalcs, tested by fast/css/scrollbar-dynamic-style-change.html

(WebCore::Document::userAgentShadowTreeStyleResolver):
(WebCore::Document::didClearStyleResolver):

    Don't start the font selector rebuild after clearing the resolver. It would cause style recalc trashing.
    Instead the build starts when the new resolver is constructed.

* page/MemoryRelease.cpp:
(WebCore::releaseCriticalMemory):

    Release font selector caches.

* style/StyleScope.cpp:
(WebCore::Style::Scope::resolver):

LayoutTests:

* platform/mac/printing/width-overflow-expected.txt:

    1px width change that doesn't affect what is being tested.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219145 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/printing/width-overflow-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontFaceSet.cpp
Source/WebCore/css/CSSFontFaceSet.h
Source/WebCore/css/CSSFontSelector.cpp
Source/WebCore/css/CSSFontSelector.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/dom/Document.cpp
Source/WebCore/page/MemoryRelease.cpp
Source/WebCore/style/StyleScope.cpp

index eddceaf..5b5e49e 100644 (file)
@@ -1,3 +1,15 @@
+2017-07-05  Antti Koivisto  <antti@apple.com>
+
+        Low memory notification shouldn't cause style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=173574
+        <rdar://problem/32616997>
+
+        Reviewed by Andreas Kling.
+
+        * platform/mac/printing/width-overflow-expected.txt:
+
+            1px width change that doesn't affect what is being tested.
+
 2017-07-05  Jonathan Bedard  <jbedard@apple.com>
 
         Move internal iOS 11 TestExpectations to OpenSource
index 0362dca..ad69046 100644 (file)
@@ -8,11 +8,11 @@ layer at (0,0) size 1300x2284
           text run at (0,0) width 765: "To run this test manually, print this page. If the right side of any lines is printed without being truncated, the test passes."
       RenderBlock {DIV} at (0,34) size 1300x2218
         RenderBlock {P} at (0,0) size 1300x72
-          RenderText {#text} at (0,0) size 1289x72
-            text run at (0,0) width 1289: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
-            text run at (0,18) width 1289: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
-            text run at (0,36) width 1289: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
-            text run at (0,54) width 526: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
+          RenderText {#text} at (0,0) size 1288x72
+            text run at (0,0) width 1288: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
+            text run at (0,18) width 1288: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
+            text run at (0,36) width 1288: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
+            text run at (0,54) width 525: "A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A"
         RenderBlock {P} at (0,88) size 1300x72
           RenderText {#text} at (0,0) size 1288x72
             text run at (0,0) width 1288: "B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B"
@@ -96,9 +96,9 @@ layer at (0,0) size 1300x2284
             text run at (0,36) width 1288: "O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O"
             text run at (0,54) width 790: "O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O"
         RenderBlock {P} at (0,1284) size 1300x54
-          RenderText {#text} at (0,0) size 1290x54
-            text run at (0,0) width 1290: "P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P"
-            text run at (0,18) width 1290: "P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P"
+          RenderText {#text} at (0,0) size 1289x54
+            text run at (0,0) width 1289: "P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P"
+            text run at (0,18) width 1289: "P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P"
             text run at (0,36) width 1105: "P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P"
         RenderBlock {P} at (0,1354) size 1300x72
           RenderText {#text} at (0,0) size 1288x72
@@ -122,7 +122,7 @@ layer at (0,0) size 1300x2284
             text run at (0,0) width 1292: "T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T"
             text run at (0,18) width 1292: "T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T"
             text run at (0,36) width 1292: "T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T"
-            text run at (0,54) width 159: "T T T T T T T T T T T T"
+            text run at (0,54) width 158: "T T T T T T T T T T T T"
         RenderBlock {P} at (0,1688) size 1300x72
           RenderText {#text} at (0,0) size 1288x72
             text run at (0,0) width 1288: "U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U"
@@ -153,7 +153,7 @@ layer at (0,0) size 1300x2284
             text run at (0,0) width 1299: "Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y"
             text run at (0,18) width 1299: "Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y"
             text run at (0,36) width 1299: "Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y"
-            text run at (0,54) width 581: "Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y"
+            text run at (0,54) width 580: "Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y"
         RenderBlock {P} at (0,2146) size 1300x72
           RenderText {#text} at (0,0) size 1291x72
             text run at (0,0) width 1291: "Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z"
index eae59fa..646f65d 100644 (file)
@@ -1,3 +1,75 @@
+2017-07-05  Antti Koivisto  <antti@apple.com>
+
+        Low memory notification shouldn't cause style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=173574
+        <rdar://problem/32616997>
+
+        Reviewed by Andreas Kling.
+
+        Patch mostly by Myles.
+
+        When we receive a low memory warning, we clear the style resolver. Previously, we were using
+        this as an opportunity to also purge the CSSFontSelector. However, purging the font selector
+        is wasteful, since the exact same set of CSSFontFace objects will be recreated as soon as the
+        CSSFontSelector is recreated. It's also harmful because this purge operation causes fonts to
+        be removed from the document's working set, and therefore triggers a relayout. Instead, this
+        call should be softened to only delete any transitory caches the CSSFontSelector owns.
+
+        We can simply delay the rebuild of the CSSFontSelector to
+        StyleResolver::appendAuthorStyleSheets(), when it's really needed. This way, we can sidestep
+        this whole problem.
+
+        There's also an added benefit: Now, buildStarted() doesn't have to be idempotent, so we can
+        enforce a stricter calling sequence with ASSERT()s.
+
+        * css/CSSFontFaceSet.cpp:
+        (WebCore::CSSFontFaceSet::emptyCaches):
+        * css/CSSFontFaceSet.h:
+        * css/CSSFontSelector.cpp:
+        (WebCore::CSSFontSelector::emptyCaches):
+
+            Add a separate function to clear font selector caches.
+
+        (WebCore::CSSFontSelector::buildStarted):
+        (WebCore::CSSFontSelector::buildCompleted):
+        (WebCore::CSSFontSelector::addFontFaceRule):
+        (WebCore::CSSFontSelector::fontModified):
+
+            No need to invalidate while building.
+
+        (WebCore::CSSFontSelector::fontRangesForFamily):
+        * css/CSSFontSelector.h:
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::StyleResolver):
+        (WebCore::StyleResolver::addCurrentSVGFontFaceRules):
+
+            Factor into a function from the constructor.
+
+        (WebCore::StyleResolver::appendAuthorStyleSheets):
+
+            Font selector build is now started and finished by StyleScope.
+
+        * css/StyleResolver.h:
+        * dom/Document.cpp:
+        (WebCore::Document::resolveStyle):
+
+            Call FrameView::styleDidChange() to update any custom scrollbars.
+            This bug was hidden by spurious style recalcs, tested by fast/css/scrollbar-dynamic-style-change.html
+
+        (WebCore::Document::userAgentShadowTreeStyleResolver):
+        (WebCore::Document::didClearStyleResolver):
+
+            Don't start the font selector rebuild after clearing the resolver. It would cause style recalc trashing.
+            Instead the build starts when the new resolver is constructed.
+
+        * page/MemoryRelease.cpp:
+        (WebCore::releaseCriticalMemory):
+
+            Release font selector caches.
+
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::resolver):
+
 2017-07-05  Brent Fulgham  <bfulgham@apple.com>
 
         [WK2] Prevent ResourceLoadStatistics from triggering a cascade of read/write events
index 4cbe557..a896528 100644 (file)
@@ -268,6 +268,11 @@ void CSSFontFaceSet::purge()
         remove(item.get());
 }
 
+void CSSFontFaceSet::emptyCaches()
+{
+    m_cache.clear();
+}
+
 void CSSFontFaceSet::clear()
 {
     for (auto& face : m_faces)
index 2b7e2eb..a6d608e 100644 (file)
@@ -60,6 +60,7 @@ public:
     void add(CSSFontFace&);
     void remove(const CSSFontFace&);
     void purge();
+    void emptyCaches();
     void clear();
     CSSFontFace& operator[](size_t i);
 
index 00cf2cb..0b2e6ff 100644 (file)
@@ -51,6 +51,7 @@
 #include "StyleRule.h"
 #include "WebKitFontFamilyNames.h"
 #include <wtf/Ref.h>
+#include <wtf/SetForScope.h>
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
@@ -91,15 +92,20 @@ bool CSSFontSelector::isEmpty() const
     return !m_cssFontFaceSet->faceCount();
 }
 
+void CSSFontSelector::emptyCaches()
+{
+    m_cssFontFaceSet->emptyCaches();
+}
+
 void CSSFontSelector::buildStarted()
 {
     m_buildIsUnderway = true;
-    m_stagingArea.clear();
     m_cssFontFaceSet->purge();
     ++m_version;
 
-    m_cssConnectionsPossiblyToRemove.clear();
-    m_cssConnectionsEncounteredDuringBuild.clear();
+    ASSERT(m_cssConnectionsPossiblyToRemove.isEmpty());
+    ASSERT(m_cssConnectionsEncounteredDuringBuild.isEmpty());
+    ASSERT(m_stagingArea.isEmpty());
     for (size_t i = 0; i < m_cssFontFaceSet->faceCount(); ++i) {
         CSSFontFace& face = m_cssFontFaceSet.get()[i];
         if (face.cssConnection())
@@ -124,7 +130,9 @@ void CSSFontSelector::buildCompleted()
 
     for (auto& item : m_stagingArea)
         addFontFaceRule(item.styleRuleFontFace, item.isInitiatingElementInUserAgentShadowTree);
+    m_cssConnectionsEncounteredDuringBuild.clear();
     m_stagingArea.clear();
+    m_cssConnectionsPossiblyToRemove.clear();
 }
 
 void CSSFontSelector::addFontFaceRule(StyleRuleFontFace& fontFaceRule, bool isInitiatingElementInUserAgentShadowTree)
@@ -162,7 +170,7 @@ void CSSFontSelector::addFontFaceRule(StyleRuleFontFace& fontFaceRule, bool isIn
     if (!srcList.length())
         return;
 
-    m_creatingFont = true;
+    SetForScope<bool> creatingFont(m_creatingFont, true);
     Ref<CSSFontFace> fontFace = CSSFontFace::create(this, &fontFaceRule);
 
     if (!fontFace->setFamilies(*fontFamily))
@@ -211,7 +219,6 @@ void CSSFontSelector::addFontFaceRule(StyleRuleFontFace& fontFaceRule, bool isIn
     }
 
     m_cssFontFaceSet->add(fontFace.get());
-    m_creatingFont = false;
     ++m_version;
 }
 
@@ -242,7 +249,7 @@ void CSSFontSelector::fontLoaded()
 
 void CSSFontSelector::fontModified()
 {
-    if (!m_creatingFont)
+    if (!m_creatingFont && !m_buildIsUnderway)
         dispatchInvalidationCallbacks();
 }
 
@@ -280,7 +287,7 @@ static const AtomicString& resolveGenericFamily(Document* document, const FontDe
 FontRanges CSSFontSelector::fontRangesForFamily(const FontDescription& fontDescription, const AtomicString& familyName)
 {
     // If this ASSERT() fires, it usually means you forgot a document.updateStyleIfNeeded() somewhere.
-    ASSERT(!m_buildIsUnderway || m_isComputingRootStyleFont);
+    ASSERT(!m_buildIsUnderway || m_computingRootStyleFontCount);
 
     // FIXME: The spec (and Firefox) says user specified generic families (sans-serif etc.) should be resolved before the @font-face lookup too.
     bool resolveGenericFamilyFirst = familyName == standardFamily;
index 623f248..56d5112 100644 (file)
@@ -63,6 +63,7 @@ public:
     RefPtr<Font> fallbackFontAt(const FontDescription&, size_t) final;
 
     void clearDocument();
+    void emptyCaches();
     void buildStarted();
     void buildCompleted();
 
@@ -82,7 +83,8 @@ public:
 
     FontFaceSet& fontFaceSet();
 
-    void setIsComputingRootStyleFont(bool value) { m_isComputingRootStyleFont = value; }
+    void incrementIsComputingRootStyleFont() { ++m_computingRootStyleFontCount; }
+    void decrementIsComputingRootStyleFont() { --m_computingRootStyleFontCount; }
 
 private:
     explicit CSSFontSelector(Document&);
@@ -111,9 +113,9 @@ private:
 
     unsigned m_uniqueId;
     unsigned m_version;
+    unsigned m_computingRootStyleFontCount { 0 };
     bool m_creatingFont { false };
     bool m_buildIsUnderway { false };
-    bool m_isComputingRootStyleFont { false };
 };
 
 } // namespace WebCore
index fb7adf5..c07a187 100644 (file)
@@ -222,17 +222,20 @@ StyleResolver::StyleResolver(Document& document)
     if (root) {
         m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), nullptr, MatchOnlyUserAgentRules).renderStyle;
         // Turn off assertion against font lookups during style resolver initialization. We may need root style font for media queries.
-        m_document.fontSelector().setIsComputingRootStyleFont(true);
+        m_document.fontSelector().incrementIsComputingRootStyleFont();
         m_rootDefaultStyle->fontCascade().update(&m_document.fontSelector());
         m_rootDefaultStyle->fontCascade().primaryFont();
-        m_document.fontSelector().setIsComputingRootStyleFont(false);
+        m_document.fontSelector().decrementIsComputingRootStyleFont();
     }
 
     if (m_rootDefaultStyle && view)
         m_mediaQueryEvaluator = MediaQueryEvaluator { view->mediaType(), m_document, m_rootDefaultStyle.get() };
 
     m_ruleSets.resetAuthorStyle();
+}
 
+void StyleResolver::addCurrentSVGFontFaceRules()
+{
 #if ENABLE(SVG_FONTS)
     if (m_document.svgExtensions()) {
         const HashSet<SVGFontFaceElement*>& svgFontFaceElements = m_document.svgExtensions()->svgFontFaceElements();
@@ -246,8 +249,6 @@ void StyleResolver::appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&
 {
     m_ruleSets.appendAuthorStyleSheets(styleSheets, &m_mediaQueryEvaluator, m_inspectorCSSOMWrappers, this);
 
-    document().fontSelector().buildCompleted();
-
     if (auto renderView = document().renderView())
         renderView->style().fontCascade().update(&document().fontSelector());
 
index 2c26e2a..e6e84ca 100644 (file)
@@ -157,6 +157,8 @@ public:
 
     void setOverrideDocumentElementStyle(RenderStyle* style) { m_overrideDocumentElementStyle = style; }
 
+    void addCurrentSVGFontFaceRules();
+
 private:
     std::unique_ptr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleRuleKeyframe*, KeyframeValue&);
 
index eefbe35..34c263b 100644 (file)
@@ -1838,6 +1838,8 @@ void Document::resolveStyle(ResolveStyleType type)
 
             RenderTreeUpdater updater(*this);
             updater.commit(WTFMove(styleUpdate));
+
+            frameView.styleDidChange();
         }
 
         updatedCompositingLayers = frameView.updateCompositingLayersAfterStyleChange();
@@ -2148,8 +2150,6 @@ void Document::invalidateMatchedPropertiesCacheAndForceStyleRecalc()
 void Document::didClearStyleResolver()
 {
     m_userAgentShadowTreeStyleResolver = nullptr;
-
-    m_fontSelector->buildStarted();
 }
 
 void Document::createRenderTree()
index 341f9b3..c16f9c0 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "MemoryRelease.h"
 
+#include "CSSFontSelector.h"
 #include "CSSValuePool.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
@@ -84,8 +85,10 @@ static void releaseCriticalMemory(Synchronous synchronous)
 
     Vector<RefPtr<Document>> documents;
     copyToVector(Document::allDocuments(), documents);
-    for (auto& document : documents)
+    for (auto& document : documents) {
         document->styleScope().clearResolver();
+        document->fontSelector().emptyCaches();
+    }
 
     GCController::singleton().deleteAllCode(JSC::DeleteAllCodeIfNotCollecting);
 
index 6302c55..a47faea 100644 (file)
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "StyleScope.h"
 
+#include "CSSFontSelector.h"
 #include "CSSStyleSheet.h"
 #include "Element.h"
 #include "ElementChildIterator.h"
@@ -95,14 +96,20 @@ StyleResolver& Scope::resolver()
 
     if (!m_resolver) {
         SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
+
         m_resolver = std::make_unique<StyleResolver>(m_document);
 
-        if (!m_shadowRoot)
+        if (!m_shadowRoot) {
+            m_document.fontSelector().buildStarted();
             m_resolver->ruleSets().initializeUserStyle();
-        else
+        else
             m_resolver->ruleSets().setUsesSharedUserStyle(m_shadowRoot->mode() != ShadowRootMode::UserAgent);
 
+        m_resolver->addCurrentSVGFontFaceRules();
         m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);
+
+        if (!m_shadowRoot)
+            m_document.fontSelector().buildCompleted();
     }
     ASSERT(!m_shadowRoot || &m_document == &m_shadowRoot->document());
     ASSERT(&m_resolver->document() == &m_document);