| Index: third_party/WebKit/Source/core/css/parser/CSSLazyParsingState.cpp
 | 
| diff --git a/third_party/WebKit/Source/core/css/parser/CSSLazyParsingState.cpp b/third_party/WebKit/Source/core/css/parser/CSSLazyParsingState.cpp
 | 
| index 8370f0a0dbd447696b93fc7dd2c55b6cb6698e6b..1a231c6dc85ded6e06f0492cf21242bf60b8b075 100644
 | 
| --- a/third_party/WebKit/Source/core/css/parser/CSSLazyParsingState.cpp
 | 
| +++ b/third_party/WebKit/Source/core/css/parser/CSSLazyParsingState.cpp
 | 
| @@ -3,8 +3,10 @@
 | 
|  // found in the LICENSE file.
 | 
|  
 | 
|  #include "core/css/parser/CSSLazyParsingState.h"
 | 
| +#include "core/css/parser/CSSLazyPropertyParserImpl.h"
 | 
|  #include "core/css/parser/CSSParserTokenRange.h"
 | 
|  #include "core/frame/UseCounter.h"
 | 
| +#include "platform/Histogram.h"
 | 
|  
 | 
|  namespace blink {
 | 
|  
 | 
| @@ -15,7 +17,19 @@ CSSLazyParsingState::CSSLazyParsingState(const CSSParserContext& context,
 | 
|      : m_context(context),
 | 
|        m_escapedStrings(std::move(escapedStrings)),
 | 
|        m_sheetText(sheetText),
 | 
| -      m_owningContents(contents) {}
 | 
| +      m_owningContents(contents),
 | 
| +      m_parsedStyleRules(0),
 | 
| +      m_totalStyleRules(0),
 | 
| +      m_styleRulesNeededForNextMilestone(0),
 | 
| +      m_usage(UsageGe0) {
 | 
| +  recordUsageMetrics();
 | 
| +}
 | 
| +
 | 
| +CSSLazyPropertyParserImpl* CSSLazyParsingState::createLazyParser(
 | 
| +    const CSSParserTokenRange& block) {
 | 
| +  ++m_totalStyleRules;
 | 
| +  return new CSSLazyPropertyParserImpl(std::move(block), this);
 | 
| +}
 | 
|  
 | 
|  const CSSParserContext& CSSLazyParsingState::context() {
 | 
|    DCHECK(m_owningContents);
 | 
| @@ -25,9 +39,18 @@ const CSSParserContext& CSSLazyParsingState::context() {
 | 
|    return m_context;
 | 
|  }
 | 
|  
 | 
| +void CSSLazyParsingState::countRuleParsed() {
 | 
| +  ++m_parsedStyleRules;
 | 
| +  while (m_parsedStyleRules > m_styleRulesNeededForNextMilestone) {
 | 
| +    DCHECK_NE(UsageAll, m_usage);
 | 
| +    ++m_usage;
 | 
| +    recordUsageMetrics();
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  bool CSSLazyParsingState::shouldLazilyParseProperties(
 | 
|      const CSSSelectorList& selectors,
 | 
| -    const CSSParserTokenRange& block) {
 | 
| +    const CSSParserTokenRange& block) const {
 | 
|    // Simple heuristic for an empty block. Note that |block| here does not
 | 
|    // include {} brackets. We avoid lazy parsing empty blocks so we can avoid
 | 
|    // considering them when possible for matching. Lazy blocks must always be
 | 
| @@ -53,4 +76,34 @@ bool CSSLazyParsingState::shouldLazilyParseProperties(
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| +void CSSLazyParsingState::recordUsageMetrics() {
 | 
| +  DEFINE_STATIC_LOCAL(EnumerationHistogram, usageHistogram,
 | 
| +                      ("Style.LazyUsage.Percent", UsageLastValue));
 | 
| +  switch (m_usage) {
 | 
| +    case UsageGe0:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules * .1;
 | 
| +      break;
 | 
| +    case UsageGt10:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules * .25;
 | 
| +      break;
 | 
| +    case UsageGt25:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules * .5;
 | 
| +      break;
 | 
| +    case UsageGt50:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules * .75;
 | 
| +      break;
 | 
| +    case UsageGt75:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules * .9;
 | 
| +      break;
 | 
| +    case UsageGt90:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules - 1;
 | 
| +      break;
 | 
| +    case UsageAll:
 | 
| +      m_styleRulesNeededForNextMilestone = m_totalStyleRules;
 | 
| +      break;
 | 
| +  }
 | 
| +
 | 
| +  usageHistogram.count(m_usage);
 | 
| +}
 | 
| +
 | 
|  }  // namespace blink
 | 
| 
 |