Changeset 101524 in webkit
- Timestamp:
- Nov 30, 2011 9:25:17 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r101520 r101524 1 2011-11-30 Antti Koivisto <antti@apple.com> 2 3 Reuse cached style fully if the parent inherited styles are equal 4 https://bugs.webkit.org/show_bug.cgi?id=73421 5 6 Reviewed by Oliver Hunt. 7 8 The matched declaration cache currently restores the non-inherted properties from the cache 9 entry but still applies all inherited properties normally. In case the current parent 10 inherited style is equivalent to the cache entry's, also the inherited style can be reused 11 and no properties need to be applied. This is faster and saves memory (by sharing the 12 style substructures better). 13 14 The new optimized code path has a pretty good hit rate, >50% of all cases on many pages. 15 16 Loading the HTML5 spec this reduces style memory consumption by ~20% (5MB, ~2.5% of total) and 17 speeds up style applying by ~25% for ~0.4s (2-3%) gain in the spec loading benchmark. 18 19 * css/CSSStyleSelector.cpp: 20 (WebCore::CSSStyleSelector::applyDeclaration): 21 (WebCore::CSSStyleSelector::applyDeclarations): 22 23 Remove the code that dynamically disables inherited only applying. We now don't allow 24 styles with explicitly inherited properties to be cached in the first place. 25 26 (WebCore::CSSStyleSelector::findFromMatchedDeclarationCache): 27 28 Return the full cache item. 29 30 (WebCore::CSSStyleSelector::addToMatchedDeclarationCache): 31 32 Also the parent style is now needed for the check for full sharing. 33 34 (WebCore::isCacheableInMatchedDeclarationCache): 35 36 Don't allow styles with explicitly inherited properties to be cached at all. 37 38 (WebCore::CSSStyleSelector::applyMatchedDeclarations): 39 40 If the parent inherited styles are equal reuse the cache entry fully and return without 41 doing anything else. 42 43 * css/CSSStyleSelector.h: 44 * rendering/style/RenderStyle.cpp: 45 (WebCore::RenderStyle::inheritedDataShared): 46 * rendering/style/RenderStyle.h: 47 48 Add fast check for equal inherited properties. 49 1 50 2011-11-30 Renata Hodovan <reni@webkit.org> 2 51 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r101499 r101524 2120 2120 2121 2121 template <bool applyFirst> 2122 void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant, bool &inheritedOnly)2122 void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant, bool inheritedOnly) 2123 2123 { 2124 2124 CSSMutableStyleDeclaration::const_iterator end = styleDeclaration->end(); … … 2128 2128 continue; 2129 2129 if (inheritedOnly && !current.isInherited()) { 2130 if (!current.value()->isInheritedValue())2131 continue;2132 2130 // If the property value is explicitly inherited, we need to apply further non-inherited properties 2133 // as they might override the value inherited here. This is really per-property but that is 2134 // probably not worth optimizing for. 2135 inheritedOnly = false; 2131 // as they might override the value inherited here. For this reason we don't allow declarations with 2132 // explicitly inherited properties to be cached. 2133 ASSERT(!current.value()->isInheritedValue()); 2134 continue; 2136 2135 } 2137 2136 int property = current.id(); … … 2157 2156 2158 2157 template <bool applyFirst> 2159 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex, bool &inheritedOnly)2158 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex, bool inheritedOnly) 2160 2159 { 2161 2160 if (startIndex == -1) … … 2211 2210 } 2212 2211 2213 const RenderStyle* CSSStyleSelector::findFromMatchedDeclarationCache(unsigned hash, const MatchResult& matchResult)2212 const CSSStyleSelector::MatchedStyleDeclarationCacheItem* CSSStyleSelector::findFromMatchedDeclarationCache(unsigned hash, const MatchResult& matchResult) 2214 2213 { 2215 2214 ASSERT(hash); … … 2230 2229 if (cacheItem.matchResult != matchResult) 2231 2230 return 0; 2232 return cacheItem.renderStyle.get();2233 } 2234 2235 void CSSStyleSelector::addToMatchedDeclarationCache(const RenderStyle* style, unsigned hash, const MatchResult& matchResult)2231 return &cacheItem; 2232 } 2233 2234 void CSSStyleSelector::addToMatchedDeclarationCache(const RenderStyle* style, const RenderStyle* parentStyle, unsigned hash, const MatchResult& matchResult) 2236 2235 { 2237 2236 ASSERT(hash); … … 2240 2239 cacheItem.matchResult = matchResult; 2241 2240 // Note that we don't cache the original RenderStyle instance. It may be further modified. 2242 // The RenderStyle in the cache is really just a holder for the non-inheritedsubstructures and never used as-is.2241 // The RenderStyle in the cache is really just a holder for the substructures and never used as-is. 2243 2242 cacheItem.renderStyle = RenderStyle::clone(style); 2243 cacheItem.parentRenderStyle = RenderStyle::clone(parentStyle); 2244 2244 m_matchStyleDeclarationCache.add(hash, cacheItem); 2245 2245 } … … 2253 2253 if (style->zoom() != RenderStyle::initialZoom()) 2254 2254 return false; 2255 // The cache assumes static knowledge about which properties are inherited. 2256 if (parentStyle->hasExplicitlyInheritedProperties()) 2257 return false; 2255 2258 return true; 2256 2259 } … … 2260 2263 unsigned cacheHash = matchResult.isCacheable ? computeDeclarationHash(m_matchedDecls.data(), m_matchedDecls.size()) : 0; 2261 2264 bool applyInheritedOnly = false; 2262 const RenderStyle* cachedStyle= 0;2263 if (cacheHash && (cache dStyle= findFromMatchedDeclarationCache(cacheHash, matchResult))) {2265 const MatchedStyleDeclarationCacheItem* cacheItem = 0; 2266 if (cacheHash && (cacheItem = findFromMatchedDeclarationCache(cacheHash, matchResult))) { 2264 2267 // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact 2265 2268 // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the 2266 2269 // element context. This is fast and saves memory by reusing the style data structures. 2267 m_style->copyNonInheritedFrom(cachedStyle); 2270 m_style->copyNonInheritedFrom(cacheItem->renderStyle.get()); 2271 if (m_parentStyle->inheritedDataShared(cacheItem->parentRenderStyle.get())) { 2272 EInsideLink linkStatus = m_style->insideLink(); 2273 // If the cache item parent style has identical inherited properties to the current parent style then the 2274 // resulting style will be identical too. We copy the inherited properties over from the cache and are done. 2275 m_style->inheritFrom(cacheItem->renderStyle.get()); 2276 // Unfortunately the link status is treated like an inherited property. We need to explicitly restore it. 2277 m_style->setInsideLink(linkStatus); 2278 return; 2279 } 2268 2280 applyInheritedOnly = true; 2269 2281 } … … 2278 2290 applyDeclarations<true>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly); 2279 2291 2280 if (cache dStyle && cachedStyle->effectiveZoom() != m_style->effectiveZoom()) {2292 if (cacheItem && cacheItem->renderStyle->effectiveZoom() != m_style->effectiveZoom()) { 2281 2293 m_fontDirty = true; 2282 2294 applyInheritedOnly = false; … … 2291 2303 2292 2304 // Many properties depend on the font. If it changes we just apply all properties. 2293 if (cache dStyle && cachedStyle->fontDescription() != m_style->fontDescription())2305 if (cacheItem && cacheItem->renderStyle->fontDescription() != m_style->fontDescription()) 2294 2306 applyInheritedOnly = false; 2295 2307 … … 2314 2326 ASSERT(!m_fontDirty); 2315 2327 2316 if (cache dStyle|| !cacheHash)2328 if (cacheItem || !cacheHash) 2317 2329 return; 2318 2330 if (!isCacheableInMatchedDeclarationCache(m_style.get(), m_parentStyle)) 2319 2331 return; 2320 addToMatchedDeclarationCache(m_style.get(), cacheHash, matchResult);2332 addToMatchedDeclarationCache(m_style.get(), m_parentStyle, cacheHash, matchResult); 2321 2333 } 2322 2334 -
trunk/Source/WebCore/css/CSSStyleSelector.h
r101499 r101524 266 266 void applyMatchedDeclarations(const MatchResult&); 267 267 template <bool firstPass> 268 void applyDeclarations(bool important, int startIndex, int endIndex, bool &inheritedOnly);268 void applyDeclarations(bool important, int startIndex, int endIndex, bool inheritedOnly); 269 269 template <bool firstPass> 270 void applyDeclaration(CSSMutableStyleDeclaration*, bool isImportant, bool &inheritedOnly);270 void applyDeclaration(CSSMutableStyleDeclaration*, bool isImportant, bool inheritedOnly); 271 271 272 272 void matchPageRules(RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName); … … 350 350 }; 351 351 static unsigned computeDeclarationHash(MatchedStyleDeclaration*, unsigned size); 352 const RenderStyle* findFromMatchedDeclarationCache(unsigned hash, const MatchResult&); 353 void addToMatchedDeclarationCache(const RenderStyle*, unsigned hash, const MatchResult&); 352 struct MatchedStyleDeclarationCacheItem { 353 Vector<MatchedStyleDeclaration> matchedStyleDeclarations; 354 MatchResult matchResult; 355 RefPtr<RenderStyle> renderStyle; 356 RefPtr<RenderStyle> parentRenderStyle; 357 }; 358 const MatchedStyleDeclarationCacheItem* findFromMatchedDeclarationCache(unsigned hash, const MatchResult&); 359 void addToMatchedDeclarationCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&); 354 360 355 361 // We collect the set of decls that match in |m_matchedDecls|. We then walk the … … 358 364 // for any !important rules. 359 365 Vector<MatchedStyleDeclaration, 64> m_matchedDecls; 360 361 struct MatchedStyleDeclarationCacheItem { 362 Vector<MatchedStyleDeclaration> matchedStyleDeclarations; 363 MatchResult matchResult; 364 RefPtr<RenderStyle> renderStyle; 365 }; 366 366 367 typedef HashMap<unsigned, MatchedStyleDeclarationCacheItem> MatchedStyleDeclarationCache; 367 368 MatchedStyleDeclarationCache m_matchStyleDeclarationCache; -
trunk/Source/WebCore/rendering/style/RenderStyle.cpp
r101288 r101524 320 320 #endif 321 321 || rareInheritedData != other->rareInheritedData; 322 } 323 324 bool RenderStyle::inheritedDataShared(const RenderStyle* other) const 325 { 326 // This is a fast check that only looks if the data structures are shared. 327 return inherited_flags == other->inherited_flags 328 && inherited.get() == other->inherited.get() 329 #if ENABLE(SVG) 330 && m_svgStyle.get() == other->m_svgStyle.get() 331 #endif 332 && rareInheritedData.get() == other->rareInheritedData.get(); 322 333 } 323 334 -
trunk/Source/WebCore/rendering/style/RenderStyle.h
r101399 r101524 1344 1344 1345 1345 bool inheritedNotEqual(const RenderStyle*) const; 1346 bool inheritedDataShared(const RenderStyle*) const; 1346 1347 1347 1348 StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
Note: See TracChangeset
for help on using the changeset viewer.