Title: [282142] trunk/Source/WebCore
Revision
282142
Author
wenson_hs...@apple.com
Date
2021-09-08 07:01:50 -0700 (Wed, 08 Sep 2021)

Log Message

Add a fast path for atomizing strings when parsing HTML
https://bugs.webkit.org/show_bug.cgi?id=229907
rdar://82854612

Reviewed by Yusuke Suzuki and Darin Adler.

On various subtests in Speedometer 2, a nontrivial amount of time is spent mapping raw UChar data vectors into
AtomStrings while parsing HTML tag names, attribute names and attribute values. Most of this happens underneath
the AtomHTMLToken constructor, which computes a hash for each string in the process of adding it to the atom
string table; the time it takes to compute this string hash increases linearly with the length of the string.

However, over the course of the benchmark, the vast majority of AtomStrings created out of tag names, attribute
names and attribute values are both:

(1) Strings that we've already recently atomized, and
(2) Usually distinguishable from other atom strings based solely on their first character, last character, and
    overall string length.

As such, it's possible to slightly improve string atomization performance in this particular case (i.e. parsing
HTML) by maintaining a smaller cache of recently atomized AtomStrings that we index using a simple, constant-
time hash function that considers only the first character, last character, and length of the string. In terms
of the cache hit rate in this AtomString cache, the default string hashing algorithm only barely outperforms
this simple hash function on Speedometer (i.e., a cache hit rate of 99.24% using the default hash algorithm vs.
99.15% using the "first/last character and length" hash).

Using this technique, we can get a significant performance improvement on Speedometer by introducing two small,
fixed-size (512 capacity) AtomString tables: one to hold tag names and attribute names, and another to hold
attribute values (which seems to contain a much larger set of unique strings); we additionally use the cheap "2-
char & length" hash algorithm described above to index into these fixed-size tables.

This allows us to more efficiently atomize not only known tag and attribute names, but also custom element tag
names and attribute names and values that tend to appear frequently in markup (e.g. due to using certain
_javascript_ frameworks that get and set HTML attributes).

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* html/parser/AtomHTMLToken.h:
(WebCore::AtomHTMLToken::initializeAttributes):
(WebCore::AtomHTMLToken::AtomHTMLToken):
* html/parser/HTMLAtomStringCache.cpp: Added.
(WebCore::HTMLAtomStringCache::cache):
* html/parser/HTMLAtomStringCache.h: Added.

Add a helper class that exposes three static inline helper methods: `makeTagOrAttributeName` and
`makeAttributeValue`, which return AtomStrings for the given `Vector<UChar>` (consulting the corresponding
cache if possible); and `clear`, which empties all cached atom strings.

(WebCore::HTMLAtomStringCache::makeTagOrAttributeName):
(WebCore::HTMLAtomStringCache::makeAttributeValue):
(WebCore::HTMLAtomStringCache::clear):
(WebCore::HTMLAtomStringCache::make):

Additionally add an upper length limit for characters that we include in this cache; in practice, longer strings
tend to be repeatedly atomized less frequently than shorter strings. The 36-character limit also allows for
frequently-parsed (and atomized) UUIDs to be cached.

(WebCore::HTMLAtomStringCache::cacheSlot):

This hashing algorithm was inspired by `calculateWithTwoCharacters`, but with constants specifically chosen to
minimize collisions between common HTML tag and attribute names.

* page/MemoryRelease.cpp:
(WebCore::releaseNoncriticalMemory):
* page/cocoa/MemoryReleaseCocoa.mm:
(WebCore::jettisonExpensiveObjectsOnTopLevelNavigation):

Add logic to clear the HTML atom string cache upon receiving a low memory warning, and upon top-level
navigation.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282141 => 282142)


--- trunk/Source/WebCore/ChangeLog	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/ChangeLog	2021-09-08 14:01:50 UTC (rev 282142)
@@ -1,3 +1,74 @@
+2021-09-08  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        Add a fast path for atomizing strings when parsing HTML
+        https://bugs.webkit.org/show_bug.cgi?id=229907
+        rdar://82854612
+
+        Reviewed by Yusuke Suzuki and Darin Adler.
+
+        On various subtests in Speedometer 2, a nontrivial amount of time is spent mapping raw UChar data vectors into
+        AtomStrings while parsing HTML tag names, attribute names and attribute values. Most of this happens underneath
+        the AtomHTMLToken constructor, which computes a hash for each string in the process of adding it to the atom
+        string table; the time it takes to compute this string hash increases linearly with the length of the string.
+
+        However, over the course of the benchmark, the vast majority of AtomStrings created out of tag names, attribute
+        names and attribute values are both:
+
+        (1) Strings that we've already recently atomized, and
+        (2) Usually distinguishable from other atom strings based solely on their first character, last character, and
+            overall string length.
+
+        As such, it's possible to slightly improve string atomization performance in this particular case (i.e. parsing
+        HTML) by maintaining a smaller cache of recently atomized AtomStrings that we index using a simple, constant-
+        time hash function that considers only the first character, last character, and length of the string. In terms
+        of the cache hit rate in this AtomString cache, the default string hashing algorithm only barely outperforms
+        this simple hash function on Speedometer (i.e., a cache hit rate of 99.24% using the default hash algorithm vs.
+        99.15% using the "first/last character and length" hash).
+
+        Using this technique, we can get a significant performance improvement on Speedometer by introducing two small,
+        fixed-size (512 capacity) AtomString tables: one to hold tag names and attribute names, and another to hold
+        attribute values (which seems to contain a much larger set of unique strings); we additionally use the cheap "2-
+        char & length" hash algorithm described above to index into these fixed-size tables.
+
+        This allows us to more efficiently atomize not only known tag and attribute names, but also custom element tag
+        names and attribute names and values that tend to appear frequently in markup (e.g. due to using certain
+        _javascript_ frameworks that get and set HTML attributes).
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/parser/AtomHTMLToken.h:
+        (WebCore::AtomHTMLToken::initializeAttributes):
+        (WebCore::AtomHTMLToken::AtomHTMLToken):
+        * html/parser/HTMLAtomStringCache.cpp: Added.
+        (WebCore::HTMLAtomStringCache::cache):
+        * html/parser/HTMLAtomStringCache.h: Added.
+
+        Add a helper class that exposes three static inline helper methods: `makeTagOrAttributeName` and
+        `makeAttributeValue`, which return AtomStrings for the given `Vector<UChar>` (consulting the corresponding
+        cache if possible); and `clear`, which empties all cached atom strings.
+
+        (WebCore::HTMLAtomStringCache::makeTagOrAttributeName):
+        (WebCore::HTMLAtomStringCache::makeAttributeValue):
+        (WebCore::HTMLAtomStringCache::clear):
+        (WebCore::HTMLAtomStringCache::make):
+
+        Additionally add an upper length limit for characters that we include in this cache; in practice, longer strings
+        tend to be repeatedly atomized less frequently than shorter strings. The 36-character limit also allows for
+        frequently-parsed (and atomized) UUIDs to be cached.
+
+        (WebCore::HTMLAtomStringCache::cacheSlot):
+
+        This hashing algorithm was inspired by `calculateWithTwoCharacters`, but with constants specifically chosen to
+        minimize collisions between common HTML tag and attribute names.
+
+        * page/MemoryRelease.cpp:
+        (WebCore::releaseNoncriticalMemory):
+        * page/cocoa/MemoryReleaseCocoa.mm:
+        (WebCore::jettisonExpensiveObjectsOnTopLevelNavigation):
+
+        Add logic to clear the HTML atom string cache upon receiving a low memory warning, and upon top-level
+        navigation.
+
 2021-09-08  Alan Bujtas  <za...@apple.com>
 
         [LFC][IFC] Add support for inline box ink overflow

Modified: trunk/Source/WebCore/Sources.txt (282141 => 282142)


--- trunk/Source/WebCore/Sources.txt	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/Sources.txt	2021-09-08 14:01:50 UTC (rev 282142)
@@ -1312,6 +1312,7 @@
 html/canvas/WebGLVertexArrayObjectOES.cpp
 html/forms/FileIconLoader.cpp
 html/parser/CSSPreloadScanner.cpp
+html/parser/HTMLAtomStringCache.cpp
 html/parser/HTMLConstructionSite.cpp
 html/parser/HTMLDocumentParser.cpp
 html/parser/HTMLElementStack.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (282141 => 282142)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-08 14:01:50 UTC (rev 282142)
@@ -5409,6 +5409,7 @@
 		F48D2A7E2157182600C6752B /* FontAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2A712156DC0A00C6752B /* FontAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F48D2AA52159740D00C6752B /* ColorCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2AA32159740D00C6752B /* ColorCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F49786881FF45FA500E060AB /* PasteboardItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F49786871FF45FA500E060AB /* PasteboardItemInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		F4B0018926E7F21F006EAABE /* HTMLAtomStringCache.h in Headers */ = {isa = PBXBuildFile; fileRef = F4B0018726E7F21F006EAABE /* HTMLAtomStringCache.h */; };
 		F4B2A909265030BA009E7286 /* DataDetectorHighlight.h in Headers */ = {isa = PBXBuildFile; fileRef = F4B2A90626502BA0009E7286 /* DataDetectorHighlight.h */; };
 		F4B422C4220C0568009E1E7D /* DOMPasteAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = F4B422C2220C0000009E1E7D /* DOMPasteAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; };
@@ -16640,6 +16641,8 @@
 		F48D2AA42159740D00C6752B /* ColorCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ColorCocoa.mm; sourceTree = "<group>"; };
 		F49786871FF45FA500E060AB /* PasteboardItemInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasteboardItemInfo.h; sourceTree = "<group>"; };
 		F49E98E421DEE6C1009AE55E /* EditAction.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EditAction.cpp; sourceTree = "<group>"; };
+		F4B0018726E7F21F006EAABE /* HTMLAtomStringCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLAtomStringCache.h; sourceTree = "<group>"; };
+		F4B0018826E7F21F006EAABE /* HTMLAtomStringCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLAtomStringCache.cpp; sourceTree = "<group>"; };
 		F4B2A90626502BA0009E7286 /* DataDetectorHighlight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataDetectorHighlight.h; sourceTree = "<group>"; };
 		F4B2A90826502BC0009E7286 /* DataDetectorHighlight.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorHighlight.mm; sourceTree = "<group>"; };
 		F4B2A90C265087E4009E7286 /* ImageOverlayControllerMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageOverlayControllerMac.mm; sourceTree = "<group>"; };
@@ -24192,6 +24195,8 @@
 				97C1F552122855CB00EDE617 /* AtomHTMLToken.h */,
 				977B3849122883E900B81FF8 /* CSSPreloadScanner.cpp */,
 				977B384A122883E900B81FF8 /* CSSPreloadScanner.h */,
+				F4B0018826E7F21F006EAABE /* HTMLAtomStringCache.cpp */,
+				F4B0018726E7F21F006EAABE /* HTMLAtomStringCache.h */,
 				977B384B122883E900B81FF8 /* HTMLConstructionSite.cpp */,
 				977B384C122883E900B81FF8 /* HTMLConstructionSite.h */,
 				977B384D122883E900B81FF8 /* HTMLDocumentParser.cpp */,
@@ -32306,6 +32311,7 @@
 				BC97E23A109144950010D361 /* HTMLAllCollection.h in Headers */,
 				A8CFF7AB0A156978000A4234 /* HTMLAnchorElement.h in Headers */,
 				A8EA7D2E0A19385500A8EF5F /* HTMLAreaElement.h in Headers */,
+				F4B0018926E7F21F006EAABE /* HTMLAtomStringCache.h in Headers */,
 				7C5F28FC1A827D8400C0F31F /* HTMLAttachmentElement.h in Headers */,
 				E44613A20CD6331000FADA75 /* HTMLAudioElement.h in Headers */,
 				A871DC1F0A15205700B12A68 /* HTMLBaseElement.h in Headers */,

Modified: trunk/Source/WebCore/html/parser/AtomHTMLToken.h (282141 => 282142)


--- trunk/Source/WebCore/html/parser/AtomHTMLToken.h	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/html/parser/AtomHTMLToken.h	2021-09-08 14:01:50 UTC (rev 282142)
@@ -26,6 +26,7 @@
 
 #pragma once
 
+#include "HTMLAtomStringCache.h"
 #include "HTMLToken.h"
 
 namespace WebCore {
@@ -202,11 +203,11 @@
         if (attribute.name.isEmpty())
             continue;
 
-        AtomString localName(attribute.name);
+        auto localName = HTMLAtomStringCache::makeTagOrAttributeName(attribute.name);
 
         // FIXME: This is N^2 for the number of attributes.
         if (!hasAttribute(m_attributes, localName))
-            m_attributes.uncheckedAppend(Attribute(QualifiedName(nullAtom(), localName, nullAtom()), AtomString(attribute.value)));
+            m_attributes.uncheckedAppend(Attribute(QualifiedName(nullAtom(), localName, nullAtom()), HTMLAtomStringCache::makeAttributeValue(attribute.value)));
     }
 }
 
@@ -218,7 +219,7 @@
         ASSERT_NOT_REACHED();
         return;
     case HTMLToken::DOCTYPE:
-        m_name = AtomString(token.name());
+        m_name = HTMLAtomStringCache::makeTagOrAttributeName(token.name());
         m_doctypeData = token.releaseDoctypeData();
         return;
     case HTMLToken::EndOfFile:
@@ -226,7 +227,7 @@
     case HTMLToken::StartTag:
     case HTMLToken::EndTag:
         m_selfClosing = token.selfClosing();
-        m_name = AtomString(token.name());
+        m_name = HTMLAtomStringCache::makeTagOrAttributeName(token.name());
         initializeAttributes(token.attributes());
         return;
     case HTMLToken::Comment:

Added: trunk/Source/WebCore/html/parser/HTMLAtomStringCache.cpp (0 => 282142)


--- trunk/Source/WebCore/html/parser/HTMLAtomStringCache.cpp	                        (rev 0)
+++ trunk/Source/WebCore/html/parser/HTMLAtomStringCache.cpp	2021-09-08 14:01:50 UTC (rev 282142)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLAtomStringCache.h"
+
+namespace WebCore {
+
+HTMLAtomStringCache::Cache& HTMLAtomStringCache::cache(Type type)
+{
+    static MainThreadNeverDestroyed<Cache> caches[2];
+    return caches[static_cast<size_t>(type)].get();
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/html/parser/HTMLAtomStringCache.h (0 => 282142)


--- trunk/Source/WebCore/html/parser/HTMLAtomStringCache.h	                        (rev 0)
+++ trunk/Source/WebCore/html/parser/HTMLAtomStringCache.h	2021-09-08 14:01:50 UTC (rev 282142)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/NeverDestroyed.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomString.h>
+
+namespace WebCore {
+
+class HTMLAtomStringCache {
+public:
+    template<size_t inlineCapacity>
+    ALWAYS_INLINE static AtomString makeTagOrAttributeName(const Vector<UChar, inlineCapacity>& string)
+    {
+        return make<Type::TagOrAttributeName>(string);
+    }
+
+    template<size_t inlineCapacity>
+    ALWAYS_INLINE static AtomString makeAttributeValue(const Vector<UChar, inlineCapacity>& string)
+    {
+        return make<Type::AttributeValue>(string);
+    }
+
+    ALWAYS_INLINE static void clear()
+    {
+        // FIXME (webkit.org/b/230019): We should try to find more opportunities to clear this cache without hindering this performance optimization.
+        cache(Type::TagOrAttributeName).fill({ });
+        cache(Type::AttributeValue).fill({ });
+    }
+
+private:
+    enum class Type : bool { TagOrAttributeName, AttributeValue };
+
+    template<HTMLAtomStringCache::Type type, size_t inlineCapacity>
+    ALWAYS_INLINE static AtomString make(const Vector<UChar, inlineCapacity>& string)
+    {
+        if (string.isEmpty())
+            return emptyAtom();
+
+        auto length = string.size();
+        if (length > maxStringLengthForCache)
+            return AtomString(string);
+
+        auto firstCharacter = string[0];
+        auto lastCharacter = string[length - 1];
+        auto& slot = cacheSlot(type, firstCharacter, lastCharacter, length);
+        if (!equal(slot.impl(), string.data(), length)) {
+            AtomString result(string);
+            slot = result;
+            return result;
+        }
+
+        return slot;
+    }
+
+    ALWAYS_INLINE static AtomString& cacheSlot(Type type, UChar firstCharacter, UChar lastCharacter, UChar length)
+    {
+        unsigned hash = (firstCharacter << 6) ^ ((lastCharacter << 14) ^ firstCharacter);
+        hash += (hash >> 14) + (length << 14);
+        hash ^= hash << 14;
+        return cache(type)[(hash + (hash >> 6)) % capacity];
+    }
+
+    static constexpr auto maxStringLengthForCache = 36;
+    static constexpr auto capacity = 512;
+    using Cache = std::array<AtomString, capacity>;
+    static Cache& cache(Type);
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/page/MemoryRelease.cpp (282141 => 282142)


--- trunk/Source/WebCore/page/MemoryRelease.cpp	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/page/MemoryRelease.cpp	2021-09-08 14:01:50 UTC (rev 282142)
@@ -38,6 +38,7 @@
 #include "FontCache.h"
 #include "Frame.h"
 #include "GCController.h"
+#include "HTMLAtomStringCache.h"
 #include "HTMLMediaElement.h"
 #include "InlineStyleSheetOwner.h"
 #include "InspectorInstrumentation.h"
@@ -85,6 +86,7 @@
         MemoryCache::singleton().pruneDeadResourcesToSize(0);
 
     InlineStyleSheetOwner::clearCache();
+    HTMLAtomStringCache::clear();
 }
 
 static void releaseCriticalMemory(Synchronous synchronous, MaintainBackForwardCache maintainBackForwardCache, MaintainMemoryCache maintainMemoryCache)

Modified: trunk/Source/WebCore/page/cocoa/MemoryReleaseCocoa.mm (282141 => 282142)


--- trunk/Source/WebCore/page/cocoa/MemoryReleaseCocoa.mm	2021-09-08 13:33:30 UTC (rev 282141)
+++ trunk/Source/WebCore/page/cocoa/MemoryReleaseCocoa.mm	2021-09-08 14:01:50 UTC (rev 282142)
@@ -28,6 +28,7 @@
 
 #import "FontFamilySpecificationCoreText.h"
 #import "GCController.h"
+#import "HTMLAtomStringCache.h"
 #import "IOSurfacePool.h"
 #import "LayerPool.h"
 #import "LocaleCocoa.h"
@@ -83,7 +84,6 @@
 
 void jettisonExpensiveObjectsOnTopLevelNavigation()
 {
-#if PLATFORM(IOS_FAMILY)
     // Protect against doing excessive jettisoning during repeated navigations.
     const auto minimumTimeSinceNavigation = 2_s;
 
@@ -95,10 +95,13 @@
     if (!shouldJettison)
         return;
 
+#if PLATFORM(IOS_FAMILY)
     // Throw away linked JS code. Linked code is tied to a global object and is not reusable.
     // The immediate memory savings outweigh the cost of recompilation in case we go back again.
     GCController::singleton().deleteAllLinkedCode(JSC::DeleteAllCodeIfNotCollecting);
 #endif
+
+    HTMLAtomStringCache::clear();
 }
 
 void registerMemoryReleaseNotifyCallbacks()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to