Changeset 207284 in webkit
- Timestamp:
- Oct 13, 2016 4:47:41 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r207282 r207284 74 74 * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm: 75 75 (WebCore::WebCoreAVFResourceLoader::startLoading): 76 77 2016-10-13 Antti Koivisto <antti@apple.com> 78 79 Share inline stylesheets between shadow trees 80 https://bugs.webkit.org/show_bug.cgi?id=163353 81 82 Reviewed by Ryosuke Niwa and Andreas Kling. 83 84 If shadow trees have identical inline stylesheets the data structures can be shared. 85 In future this will also allow sharing style resolvers. 86 87 * css/parser/CSSParserMode.h: 88 (WebCore::CSSParserContextHash::hash): 89 (WebCore::CSSParserContextHash::equal): 90 (WTF::HashTraits<WebCore::CSSParserContext>::constructDeletedValue): 91 (WTF::HashTraits<WebCore::CSSParserContext>::isDeletedValue): 92 (WTF::HashTraits<WebCore::CSSParserContext>::emptyValue): 93 94 Make CSSParserContext hashable. 95 96 * dom/InlineStyleSheetOwner.cpp: 97 (WebCore::makeInlineStyleSheetCacheKey): 98 (WebCore::inlineStyleSheetCache): 99 100 Implement a simple cache for sharing stylesheets with identical text and context. 101 102 (WebCore::InlineStyleSheetOwner::createSheet): 103 (WebCore::InlineStyleSheetOwner::clearCache): 104 * dom/InlineStyleSheetOwner.h: 105 * platform/MemoryPressureHandler.cpp: 106 (WebCore::MemoryPressureHandler::releaseNoncriticalMemory): 76 107 77 108 2016-10-13 Antti Koivisto <antti@apple.com> -
trunk/Source/WebCore/css/parser/CSSParserMode.h
r206839 r207284 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
r206917 r207284 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
r206917 r207284 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
r206951 r207284 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.