Changeset 207286 in webkit
- Timestamp:
- Oct 13, 2016 4:59:19 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r207285 r207286 1 2016-10-13 Antti Koivisto <antti@apple.com> 2 3 Share inline stylesheets between shadow trees 4 https://bugs.webkit.org/show_bug.cgi?id=163353 5 6 Reviewed by Ryosuke Niwa and Andreas Kling. 7 8 If shadow trees have identical inline stylesheets the data structures can be shared. 9 In future this will also allow sharing style resolvers. 10 11 * css/parser/CSSParserMode.h: 12 (WebCore::CSSParserContextHash::hash): 13 (WebCore::CSSParserContextHash::equal): 14 (WTF::HashTraits<WebCore::CSSParserContext>::constructDeletedValue): 15 (WTF::HashTraits<WebCore::CSSParserContext>::isDeletedValue): 16 (WTF::HashTraits<WebCore::CSSParserContext>::emptyValue): 17 18 Make CSSParserContext hashable. 19 20 * dom/InlineStyleSheetOwner.cpp: 21 (WebCore::makeInlineStyleSheetCacheKey): 22 (WebCore::inlineStyleSheetCache): 23 24 Implement a simple cache for sharing stylesheets with identical text and context. 25 26 (WebCore::InlineStyleSheetOwner::createSheet): 27 (WebCore::InlineStyleSheetOwner::clearCache): 28 * dom/InlineStyleSheetOwner.h: 29 * platform/MemoryPressureHandler.cpp: 30 (WebCore::MemoryPressureHandler::releaseNoncriticalMemory): 31 1 32 2016-10-13 Antti Koivisto <antti@apple.com> 2 33 -
trunk/Source/WebCore/css/parser/CSSParserMode.h
r207285 r207286 33 33 34 34 #include "URL.h" 35 #include "URLHash.h" 36 #include <wtf/HashFunctions.h> 37 #include <wtf/text/StringHash.h> 35 38 36 39 namespace WebCore { … … 115 118 WEBCORE_EXPORT const CSSParserContext& strictCSSParserContext(); 116 119 120 struct CSSParserContextHash { 121 static unsigned hash(const CSSParserContext& key) 122 { 123 auto hash = URLHash::hash(key.baseURL); 124 hash ^= StringHash::hash(key.charset); 125 unsigned bits = key.isHTMLDocument << 0 126 & key.isHTMLDocument << 1 127 #if ENABLE(CSS_GRID_LAYOUT) 128 & key.cssGridLayoutEnabled << 2 129 #endif 130 #if ENABLE(TEXT_AUTOSIZING) 131 & key.textAutosizingEnabled << 3 132 #endif 133 & key.needsSiteSpecificQuirks << 4 134 & key.enforcesCSSMIMETypeInNoQuirksMode << 5 135 & key.useLegacyBackgroundSizeShorthandBehavior << 6 136 & key.springTimingFunctionEnabled << 7 137 & key.useNewParser << 8 138 #if ENABLE(VARIATION_FONTS) 139 & key.variationFontsEnabled << 9 140 #endif 141 & key.mode << 10; 142 hash ^= WTF::intHash(bits); 143 return hash; 144 } 145 static bool equal(const CSSParserContext& a, const CSSParserContext& b) 146 { 147 return a == b; 148 } 149 static const bool safeToCompareToEmptyOrDeleted = false; 117 150 }; 118 151 152 } 153 154 namespace WTF { 155 template<> struct HashTraits<WebCore::CSSParserContext> : GenericHashTraits<WebCore::CSSParserContext> { 156 static void constructDeletedValue(WebCore::CSSParserContext& slot) { new (NotNull, &slot.baseURL) WebCore::URL(WTF::HashTableDeletedValue); } 157 static bool isDeletedValue(const WebCore::CSSParserContext& value) { return value.baseURL.isHashTableDeletedValue(); } 158 static WebCore::CSSParserContext emptyValue() { return WebCore::CSSParserContext(WebCore::HTMLStandardMode); } 159 }; 160 161 template<> struct DefaultHash<WebCore::CSSParserContext> { 162 typedef WebCore::CSSParserContextHash Hash; 163 }; 164 } 165 119 166 #endif // CSSParserMode_h -
trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp
r207285 r207286 31 31 #include "StyleSheetContents.h" 32 32 #include "TextNodeTraversal.h" 33 #include <wtf/HashMap.h> 33 34 #include <wtf/NeverDestroyed.h> 34 35 35 36 namespace WebCore { 37 38 using InlineStyleSheetCacheKey = std::pair<String, CSSParserContext>; 39 using InlineStyleSheetCache = HashMap<InlineStyleSheetCacheKey, RefPtr<StyleSheetContents>>; 40 41 static InlineStyleSheetCache& inlineStyleSheetCache() 42 { 43 static NeverDestroyed<InlineStyleSheetCache> cache; 44 return cache; 45 } 46 47 static URL inlineStyleSheetBaseURLForElement(const Element& element) 48 { 49 auto* shadowRoot = element.containingShadowRoot(); 50 // User agent shadow trees can't contain document-relative URLs. Use blank URL as base allowing cross-document sharing. 51 return shadowRoot && shadowRoot->mode() == ShadowRoot::Mode::UserAgent ? blankURL() : element.document().baseURL(); 52 } 53 54 static Optional<InlineStyleSheetCacheKey> makeInlineStyleSheetCacheKey(const String& text, const Element& element) 55 { 56 if (text.isEmpty()) 57 return { }; 58 // Only cache for shadow trees. Main document inline stylesheets are generally unique and can't be shared between documents. 59 // FIXME: This could be relaxed when a stylesheet does not contain document-relative URLs (or #urls). 60 if (!element.isInShadowTree()) 61 return { }; 62 63 CSSParserContext context { element.document(), inlineStyleSheetBaseURLForElement(element) }; 64 return std::make_pair(text, context); 65 } 36 66 37 67 InlineStyleSheetOwner::InlineStyleSheetOwner(Document& document, bool createdByParser) … … 153 183 m_styleScope->addPendingSheet(); 154 184 185 auto cacheKey = makeInlineStyleSheetCacheKey(text, element); 186 if (cacheKey) { 187 if (auto* cachedSheet = inlineStyleSheetCache().get(*cacheKey)) { 188 ASSERT(cachedSheet->isCacheable()); 189 m_sheet = CSSStyleSheet::create(*cachedSheet, element); 190 sheetLoaded(element); 191 element.notifyLoadedSheetAndAllCriticalSubresources(false); 192 return; 193 } 194 } 195 155 196 m_loading = true; 156 197 157 m_sheet = CSSStyleSheet::createInline(element, URL(), m_startTextPosition, document.encoding());198 m_sheet = CSSStyleSheet::createInline(element, inlineStyleSheetBaseURLForElement(element), m_startTextPosition, document.encoding()); 158 199 m_sheet->setMediaQueries(mediaQueries.releaseNonNull()); 159 200 m_sheet->setTitle(element.title()); … … 164 205 if (m_sheet) 165 206 m_sheet->contents().checkLoaded(); 207 208 if (cacheKey && m_sheet && m_sheet->contents().isCacheable()) { 209 inlineStyleSheetCache().add(*cacheKey, &m_sheet->contents()); 210 211 // Prevent pathological growth. 212 const size_t maximumInlineStyleSheetCacheSize = 50; 213 if (inlineStyleSheetCache().size() > maximumInlineStyleSheetCacheSize) 214 inlineStyleSheetCache().remove(inlineStyleSheetCache().begin()); 215 } 166 216 } 167 217 … … 190 240 } 191 241 192 } 242 void InlineStyleSheetOwner::clearCache() 243 { 244 inlineStyleSheetCache().clear(); 245 } 246 247 } -
trunk/Source/WebCore/dom/InlineStyleSheetOwner.h
r207285 r207286 53 53 Style::Scope* styleScope() { return m_styleScope; } 54 54 55 static void clearCache(); 56 55 57 private: 56 58 void createSheet(Element&, const String& text); -
trunk/Source/WebCore/platform/MemoryPressureHandler.cpp
r207285 r207286 34 34 #include "GCController.h" 35 35 #include "HTMLMediaElement.h" 36 #include "InlineStyleSheetOwner.h" 36 37 #include "InspectorInstrumentation.h" 37 38 #include "Logging.h" … … 104 105 StyledElement::clearPresentationAttributeCache(); 105 106 } 107 108 { 109 ReliefLogger log("Clear inline stylesheet cache"); 110 InlineStyleSheetOwner::clearCache(); 111 } 106 112 } 107 113
Note: See TracChangeset
for help on using the changeset viewer.