OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 #include "core/css/MediaQueryEvaluator.h" | 56 #include "core/css/MediaQueryEvaluator.h" |
57 #include "core/css/PageRuleCollector.h" | 57 #include "core/css/PageRuleCollector.h" |
58 #include "core/css/RuleSet.h" | 58 #include "core/css/RuleSet.h" |
59 #include "core/css/StylePropertySet.h" | 59 #include "core/css/StylePropertySet.h" |
60 #include "core/css/resolver/AnimatedStyleBuilder.h" | 60 #include "core/css/resolver/AnimatedStyleBuilder.h" |
61 #include "core/css/resolver/MatchResult.h" | 61 #include "core/css/resolver/MatchResult.h" |
62 #include "core/css/resolver/MediaQueryResult.h" | 62 #include "core/css/resolver/MediaQueryResult.h" |
63 #include "core/css/resolver/SharedStyleFinder.h" | 63 #include "core/css/resolver/SharedStyleFinder.h" |
64 #include "core/css/resolver/StyleAdjuster.h" | 64 #include "core/css/resolver/StyleAdjuster.h" |
65 #include "core/css/resolver/StyleBuilder.h" | 65 #include "core/css/resolver/StyleBuilder.h" |
| 66 #include "core/css/resolver/StyleResolverStats.h" |
66 #include "core/css/resolver/ViewportStyleResolver.h" | 67 #include "core/css/resolver/ViewportStyleResolver.h" |
67 #include "core/dom/CSSSelectorWatch.h" | 68 #include "core/dom/CSSSelectorWatch.h" |
68 #include "core/dom/NodeRenderStyle.h" | 69 #include "core/dom/NodeRenderStyle.h" |
69 #include "core/dom/StyleEngine.h" | 70 #include "core/dom/StyleEngine.h" |
70 #include "core/dom/Text.h" | 71 #include "core/dom/Text.h" |
71 #include "core/dom/shadow/ElementShadow.h" | 72 #include "core/dom/shadow/ElementShadow.h" |
72 #include "core/dom/shadow/ShadowRoot.h" | 73 #include "core/dom/shadow/ShadowRoot.h" |
73 #include "core/html/HTMLIFrameElement.h" | 74 #include "core/html/HTMLIFrameElement.h" |
74 #include "core/inspector/InspectorInstrumentation.h" | 75 #include "core/inspector/InspectorInstrumentation.h" |
75 #include "core/frame/Frame.h" | 76 #include "core/frame/Frame.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 if (rightToLeftDecl->isEmpty()) | 120 if (rightToLeftDecl->isEmpty()) |
120 rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl); | 121 rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl); |
121 return rightToLeftDecl; | 122 return rightToLeftDecl; |
122 } | 123 } |
123 | 124 |
124 StyleResolver::StyleResolver(Document& document) | 125 StyleResolver::StyleResolver(Document& document) |
125 : m_document(document) | 126 : m_document(document) |
126 , m_fontSelector(CSSFontSelector::create(&document)) | 127 , m_fontSelector(CSSFontSelector::create(&document)) |
127 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) | 128 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) |
128 , m_styleResourceLoader(document.fetcher()) | 129 , m_styleResourceLoader(document.fetcher()) |
| 130 , m_styleResolverStatsSequence(0) |
129 { | 131 { |
130 Element* root = document.documentElement(); | 132 Element* root = document.documentElement(); |
131 | 133 |
132 m_fontSelector->registerForInvalidationCallbacks(this); | 134 m_fontSelector->registerForInvalidationCallbacks(this); |
133 | 135 |
134 CSSDefaultStyleSheets::initDefaultStyle(root); | 136 CSSDefaultStyleSheets::initDefaultStyle(root); |
135 | 137 |
136 // construct document root element default style. this is needed | 138 // construct document root element default style. this is needed |
137 // to evaluate media queries that contain relative constraints, like "screen
and (max-width: 10em)" | 139 // to evaluate media queries that contain relative constraints, like "screen
and (max-width: 10em)" |
138 // This is here instead of constructor, because when constructor is run, | 140 // This is here instead of constructor, because when constructor is run, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 { | 308 { |
307 return m_features.idsInRules.contains(id.impl()); | 309 return m_features.idsInRules.contains(id.impl()); |
308 } | 310 } |
309 | 311 |
310 void StyleResolver::addToStyleSharingList(Element& element) | 312 void StyleResolver::addToStyleSharingList(Element& element) |
311 { | 313 { |
312 // Never add elements to the style sharing list if we're not in a recalcStyl
e, | 314 // Never add elements to the style sharing list if we're not in a recalcStyl
e, |
313 // otherwise we could leave stale pointers in there. | 315 // otherwise we could leave stale pointers in there. |
314 if (!document().inStyleRecalc()) | 316 if (!document().inStyleRecalc()) |
315 return; | 317 return; |
| 318 INCREMENT_STYLE_STATS_COUNTER(*this, sharedStyleCandidates); |
316 if (m_styleSharingList.size() >= styleSharingListSize) | 319 if (m_styleSharingList.size() >= styleSharingListSize) |
317 m_styleSharingList.remove(--m_styleSharingList.end()); | 320 m_styleSharingList.remove(--m_styleSharingList.end()); |
318 m_styleSharingList.prepend(&element); | 321 m_styleSharingList.prepend(&element); |
319 } | 322 } |
320 | 323 |
321 void StyleResolver::clearStyleSharingList() | 324 void StyleResolver::clearStyleSharingList() |
322 { | 325 { |
323 m_styleSharingList.clear(); | 326 m_styleSharingList.clear(); |
324 } | 327 } |
325 | 328 |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 | 1210 |
1208 void StyleResolver::invalidateMatchedPropertiesCache() | 1211 void StyleResolver::invalidateMatchedPropertiesCache() |
1209 { | 1212 { |
1210 m_matchedPropertiesCache.clear(); | 1213 m_matchedPropertiesCache.clear(); |
1211 } | 1214 } |
1212 | 1215 |
1213 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult, Element* animatingElement) | 1216 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult, Element* animatingElement) |
1214 { | 1217 { |
1215 const Element* element = state.element(); | 1218 const Element* element = state.element(); |
1216 ASSERT(element); | 1219 ASSERT(element); |
1217 STYLE_STATS_ADD_MATCHED_PROPERTIES_SEARCH(); | 1220 |
| 1221 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply); |
1218 | 1222 |
1219 unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(
matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0; | 1223 unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(
matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0; |
1220 bool applyInheritedOnly = false; | 1224 bool applyInheritedOnly = false; |
1221 const CachedMatchedProperties* cachedMatchedProperties = 0; | 1225 const CachedMatchedProperties* cachedMatchedProperties = 0; |
1222 | 1226 |
1223 if (cacheHash && (cachedMatchedProperties = m_matchedPropertiesCache.find(ca
cheHash, state, matchResult)) | 1227 if (cacheHash && (cachedMatchedProperties = m_matchedPropertiesCache.find(ca
cheHash, state, matchResult)) |
1224 && MatchedPropertiesCache::isCacheable(element, state.style(), state.par
entStyle())) { | 1228 && MatchedPropertiesCache::isCacheable(element, state.style(), state.par
entStyle())) { |
1225 STYLE_STATS_ADD_MATCHED_PROPERTIES_HIT(); | 1229 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit); |
1226 // We can build up the style by copying non-inherited properties from an
earlier style object built using the same exact | 1230 // We can build up the style by copying non-inherited properties from an
earlier style object built using the same exact |
1227 // style declarations. We then only need to apply the inherited properti
es, if any, as their values can depend on the | 1231 // style declarations. We then only need to apply the inherited properti
es, if any, as their values can depend on the |
1228 // element context. This is fast and saves memory by reusing the style d
ata structures. | 1232 // element context. This is fast and saves memory by reusing the style d
ata structures. |
1229 state.style()->copyNonInheritedFrom(cachedMatchedProperties->renderStyle
.get()); | 1233 state.style()->copyNonInheritedFrom(cachedMatchedProperties->renderStyle
.get()); |
1230 if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->pa
rentRenderStyle.get()) && !isAtShadowBoundary(element)) { | 1234 if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->pa
rentRenderStyle.get()) && !isAtShadowBoundary(element)) { |
1231 STYLE_STATS_ADD_MATCHED_PROPERTIES_HIT_SHARED_INHERITED(); | 1235 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHi
t); |
1232 | 1236 |
1233 EInsideLink linkStatus = state.style()->insideLink(); | 1237 EInsideLink linkStatus = state.style()->insideLink(); |
1234 // If the cache item parent style has identical inherited properties
to the current parent style then the | 1238 // If the cache item parent style has identical inherited properties
to the current parent style then the |
1235 // resulting style will be identical too. We copy the inherited prop
erties over from the cache and are done. | 1239 // resulting style will be identical too. We copy the inherited prop
erties over from the cache and are done. |
1236 state.style()->inheritFrom(cachedMatchedProperties->renderStyle.get(
)); | 1240 state.style()->inheritFrom(cachedMatchedProperties->renderStyle.get(
)); |
1237 | 1241 |
1238 // Unfortunately the link status is treated like an inherited proper
ty. We need to explicitly restore it. | 1242 // Unfortunately the link status is treated like an inherited proper
ty. We need to explicitly restore it. |
1239 state.style()->setInsideLink(linkStatus); | 1243 state.style()->setInsideLink(linkStatus); |
1240 return; | 1244 return; |
1241 } | 1245 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 } | 1326 } |
1323 applyAnimatedProperties<LowPriorityProperties>(state, compositableVa
luesForTransitions); | 1327 applyAnimatedProperties<LowPriorityProperties>(state, compositableVa
luesForTransitions); |
1324 } | 1328 } |
1325 } | 1329 } |
1326 | 1330 |
1327 // Start loading resources referenced by this style. | 1331 // Start loading resources referenced by this style. |
1328 m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyle
Resources()); | 1332 m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyle
Resources()); |
1329 | 1333 |
1330 ASSERT(!state.fontBuilder().fontDirty()); | 1334 ASSERT(!state.fontBuilder().fontDirty()); |
1331 | 1335 |
1332 #ifdef STYLE_STATS | |
1333 if (!cachedMatchedProperties) | |
1334 STYLE_STATS_ADD_MATCHED_PROPERTIES_TO_CACHE(); | |
1335 #endif | |
1336 | |
1337 if (cachedMatchedProperties || !cacheHash) | 1336 if (cachedMatchedProperties || !cacheHash) |
1338 return; | 1337 return; |
1339 if (!MatchedPropertiesCache::isCacheable(element, state.style(), state.paren
tStyle())) | 1338 if (!MatchedPropertiesCache::isCacheable(element, state.style(), state.paren
tStyle())) |
1340 return; | 1339 return; |
1341 STYLE_STATS_ADD_MATCHED_PROPERTIES_ENTERED_INTO_CACHE(); | 1340 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded); |
1342 m_matchedPropertiesCache.add(state.style(), state.parentStyle(), cacheHash,
matchResult); | 1341 m_matchedPropertiesCache.add(state.style(), state.parentStyle(), cacheHash,
matchResult); |
1343 } | 1342 } |
1344 | 1343 |
1345 CSSPropertyValue::CSSPropertyValue(CSSPropertyID id, const StylePropertySet& pro
pertySet) | 1344 CSSPropertyValue::CSSPropertyValue(CSSPropertyID id, const StylePropertySet& pro
pertySet) |
1346 : property(id), value(propertySet.getPropertyCSSValue(id).get()) | 1345 : property(id), value(propertySet.getPropertyCSSValue(id).get()) |
1347 { } | 1346 { } |
1348 | 1347 |
| 1348 void StyleResolver::enableStats(StatsReportType reportType) |
| 1349 { |
| 1350 if (m_styleResolverStats) |
| 1351 return; |
| 1352 m_styleResolverStats = StyleResolverStats::create(); |
| 1353 m_styleResolverStatsTotals = StyleResolverStats::create(); |
| 1354 if (reportType == ReportSlowStats) { |
| 1355 m_styleResolverStats->printMissedCandidateCount = true; |
| 1356 m_styleResolverStatsTotals->printMissedCandidateCount = true; |
| 1357 } |
| 1358 } |
| 1359 |
| 1360 void StyleResolver::disableStats() |
| 1361 { |
| 1362 m_styleResolverStatsSequence = 0; |
| 1363 m_styleResolverStats.clear(); |
| 1364 m_styleResolverStatsTotals.clear(); |
| 1365 } |
| 1366 |
| 1367 void StyleResolver::printStats() |
| 1368 { |
| 1369 if (!m_styleResolverStats) |
| 1370 return; |
| 1371 fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_sty
leResolverStatsSequence, m_document.url().string().utf8().data()); |
| 1372 fprintf(stderr, "%s\n", m_styleResolverStats->report().utf8().data()); |
| 1373 fprintf(stderr, "== Totals ==\n"); |
| 1374 fprintf(stderr, "%s\n", m_styleResolverStatsTotals->report().utf8().data()); |
| 1375 } |
| 1376 |
1349 void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, s
ize_t count, RenderStyle* style) | 1377 void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, s
ize_t count, RenderStyle* style) |
1350 { | 1378 { |
1351 StyleResolverState state(document(), document().documentElement(), style); | 1379 StyleResolverState state(document(), document().documentElement(), style); |
1352 state.setStyle(style); | 1380 state.setStyle(style); |
1353 | 1381 |
1354 state.fontBuilder().initForStyleResolve(document(), style, state.useSVGZoomR
ules()); | 1382 state.fontBuilder().initForStyleResolve(document(), style, state.useSVGZoomR
ules()); |
1355 | 1383 |
1356 for (size_t i = 0; i < count; ++i) { | 1384 for (size_t i = 0; i < count; ++i) { |
1357 if (properties[i].value) { | 1385 if (properties[i].value) { |
1358 // As described in BUG66291, setting font-size and line-height on a
font may entail a CSSPrimitiveValue::computeLengthDouble call, | 1386 // As described in BUG66291, setting font-size and line-height on a
font may entail a CSSPrimitiveValue::computeLengthDouble call, |
(...skipping 15 matching lines...) Expand all Loading... |
1374 bool StyleResolver::affectedByViewportChange() const | 1402 bool StyleResolver::affectedByViewportChange() const |
1375 { | 1403 { |
1376 unsigned s = m_viewportDependentMediaQueryResults.size(); | 1404 unsigned s = m_viewportDependentMediaQueryResults.size(); |
1377 for (unsigned i = 0; i < s; i++) { | 1405 for (unsigned i = 0; i < s; i++) { |
1378 if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expressio
n) != m_viewportDependentMediaQueryResults[i]->m_result) | 1406 if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expressio
n) != m_viewportDependentMediaQueryResults[i]->m_result) |
1379 return true; | 1407 return true; |
1380 } | 1408 } |
1381 return false; | 1409 return false; |
1382 } | 1410 } |
1383 | 1411 |
1384 #ifdef STYLE_STATS | |
1385 StyleSharingStats StyleResolver::m_styleSharingStats; | |
1386 | |
1387 static void printStyleStats(unsigned searches, unsigned elementsEligibleForShari
ng, unsigned stylesShared, unsigned searchFoundSiblingForSharing, unsigned searc
hesMissedSharing, | |
1388 unsigned matchedPropertiesSearches, unsigned matchedPropertiesHit, unsigned
matchedPropertiesSharedInheritedHit, unsigned matchedPropertiesToCache, unsigned
matchedPropertiesEnteredIntoCache) | |
1389 { | |
1390 double percentOfElementsSharingStyle = (stylesShared * 100.0) / searches; | |
1391 double percentOfNodesEligibleForSharing = (elementsEligibleForSharing * 100.
0) / searches; | |
1392 double percentOfEligibleSharingRelativesFound = (searchFoundSiblingForSharin
g * 100.0) / searches; | |
1393 double percentOfMatchedPropertiesHit = (matchedPropertiesHit * 100.0) / matc
hedPropertiesSearches; | |
1394 double percentOfMatchedPropertiesSharedInheritedHit = (matchedPropertiesShar
edInheritedHit * 100.0) / matchedPropertiesSearches; | |
1395 double percentOfMatchedPropertiesEnteredIntoCache = (matchedPropertiesEntere
dIntoCache * 100.0) / matchedPropertiesToCache; | |
1396 | |
1397 fprintf(stderr, "%u elements checked, %u were eligible for style sharing (%.
2f%%).\n", searches, elementsEligibleForSharing, percentOfNodesEligibleForSharin
g); | |
1398 fprintf(stderr, "%u elements were found to share with, %u were possible (%.2
f%%).\n", searchFoundSiblingForSharing, searchesMissedSharing + searchFoundSibli
ngForSharing, percentOfEligibleSharingRelativesFound); | |
1399 fprintf(stderr, "%u styles were actually shared once sibling and attribute r
ules were considered (%.2f%%).\n", stylesShared, percentOfElementsSharingStyle); | |
1400 fprintf(stderr, "%u/%u (%.2f%%) matched property lookups hit the cache.\n",
matchedPropertiesHit, matchedPropertiesSearches, percentOfMatchedPropertiesHit); | |
1401 fprintf(stderr, "%u/%u (%.2f%%) matched property lookups hit the cache and s
hared inherited data.\n", matchedPropertiesSharedInheritedHit, matchedProperties
Searches, percentOfMatchedPropertiesSharedInheritedHit); | |
1402 fprintf(stderr, "%u/%u (%.2f%%) matched properties were cacheable\n", matche
dPropertiesEnteredIntoCache, matchedPropertiesToCache, percentOfMatchedPropertie
sEnteredIntoCache); | |
1403 } | |
1404 | |
1405 void StyleSharingStats::printStats() const | |
1406 { | |
1407 fprintf(stderr, "-----------------------------------------------------------
---------------------\n"); | |
1408 fprintf(stderr, "This recalc style:\n"); | |
1409 printStyleStats(m_searches, m_elementsEligibleForSharing, m_stylesShared, m_
searchFoundSiblingForSharing, m_searchesMissedSharing, | |
1410 m_matchedPropertiesSearches, m_matchedPropertiesHit, m_matchedProperties
SharedInheritedHit, m_matchedPropertiesToCache, m_matchedPropertiesEnteredIntoCa
che); | |
1411 | |
1412 fprintf(stderr, "Total:\n"); | |
1413 printStyleStats(m_totalSearches, m_totalElementsEligibleForSharing, m_totalS
tylesShared, m_totalSearchFoundSiblingForSharing, m_totalSearchesMissedSharing, | |
1414 m_totalMatchedPropertiesSearches, m_totalMatchedPropertiesHit, m_totalMa
tchedPropertiesSharedInheritedHit, m_totalMatchedPropertiesToCache, m_totalMatch
edPropertiesEnteredIntoCache); | |
1415 fprintf(stderr, "-----------------------------------------------------------
---------------------\n"); | |
1416 } | |
1417 #endif | |
1418 | |
1419 } // namespace WebCore | 1412 } // namespace WebCore |
OLD | NEW |