Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(626)

Side by Side Diff: third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp

Issue 2289333003: CSS Lazy Parsing perf jobs (Closed)
Patch Set: CL for src perf tryjob to run blink_style.top_25 benchmark on all-android platform(s) Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/css/parser/CSSParserImpl.h" 5 #include "core/css/parser/CSSParserImpl.h"
6 6
7 #include "core/css/CSSCustomIdentValue.h" 7 #include "core/css/CSSCustomIdentValue.h"
8 #include "core/css/CSSCustomPropertyDeclaration.h" 8 #include "core/css/CSSCustomPropertyDeclaration.h"
9 #include "core/css/CSSKeyframesRule.h" 9 #include "core/css/CSSKeyframesRule.h"
10 #include "core/css/CSSStyleSheet.h" 10 #include "core/css/CSSStyleSheet.h"
(...skipping 17 matching lines...) Expand all
28 #include "core/frame/Deprecation.h" 28 #include "core/frame/Deprecation.h"
29 #include "core/frame/UseCounter.h" 29 #include "core/frame/UseCounter.h"
30 #include "platform/tracing/TraceEvent.h" 30 #include "platform/tracing/TraceEvent.h"
31 #include "wtf/PtrUtil.h" 31 #include "wtf/PtrUtil.h"
32 #include <bitset> 32 #include <bitset>
33 #include <memory> 33 #include <memory>
34 34
35 namespace blink { 35 namespace blink {
36 36
37 CSSParserImpl::CSSParserImpl(const CSSParserContext& context, 37 CSSParserImpl::CSSParserImpl(const CSSParserContext& context,
38 StyleSheetContents* styleSheet) 38 StyleSheetContents* styleSheet,
39 bool deferPropertyParsing)
39 : m_context(context), 40 : m_context(context),
40 m_styleSheet(styleSheet), 41 m_styleSheet(styleSheet),
41 m_observerWrapper(nullptr) {} 42 m_observerWrapper(nullptr),
43 m_deferPropertyParsing(deferPropertyParsing) {}
42 44
43 bool CSSParserImpl::parseValue(MutableStylePropertySet* declaration, 45 bool CSSParserImpl::parseValue(MutableStylePropertySet* declaration,
44 CSSPropertyID unresolvedProperty, 46 CSSPropertyID unresolvedProperty,
45 const String& string, 47 const String& string,
46 bool important, 48 bool important,
47 const CSSParserContext& context) { 49 const CSSParserContext& context) {
48 CSSParserImpl parser(context); 50 CSSParserImpl parser(context);
49 StyleRule::RuleType ruleType = StyleRule::Style; 51 StyleRule::RuleType ruleType = StyleRule::Style;
50 if (declaration->cssParserMode() == CSSViewportRuleMode) 52 if (declaration->cssParserMode() == CSSViewportRuleMode)
51 ruleType = StyleRule::Viewport; 53 ruleType = StyleRule::Viewport;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 if (!rule) 187 if (!rule)
186 return nullptr; // Parse error, failed to consume rule 188 return nullptr; // Parse error, failed to consume rule
187 range.consumeWhitespace(); 189 range.consumeWhitespace();
188 if (!rule || !range.atEnd()) 190 if (!rule || !range.atEnd())
189 return nullptr; // Parse error, trailing garbage 191 return nullptr; // Parse error, trailing garbage
190 return rule; 192 return rule;
191 } 193 }
192 194
193 void CSSParserImpl::parseStyleSheet(const String& string, 195 void CSSParserImpl::parseStyleSheet(const String& string,
194 const CSSParserContext& context, 196 const CSSParserContext& context,
195 StyleSheetContents* styleSheet) { 197 StyleSheetContents* styleSheet,
198 bool deferPropertyParsing) {
196 TRACE_EVENT_BEGIN2("blink,blink_style", "CSSParserImpl::parseStyleSheet", 199 TRACE_EVENT_BEGIN2("blink,blink_style", "CSSParserImpl::parseStyleSheet",
197 "baseUrl", context.baseURL().getString().utf8(), "mode", 200 "baseUrl", context.baseURL().getString().utf8(), "mode",
198 context.mode()); 201 context.mode());
199 202
200 TRACE_EVENT_BEGIN0("blink,blink_style", 203 TRACE_EVENT_BEGIN0("blink,blink_style",
201 "CSSParserImpl::parseStyleSheet.tokenize"); 204 "CSSParserImpl::parseStyleSheet.tokenize");
202 CSSTokenizer::Scope scope(string); 205 styleSheet->m_scope = CSSTokenizer::Scope(string);
203 TRACE_EVENT_END0("blink,blink_style", 206 TRACE_EVENT_END0("blink,blink_style",
204 "CSSParserImpl::parseStyleSheet.tokenize"); 207 "CSSParserImpl::parseStyleSheet.tokenize");
205 208
206 TRACE_EVENT_BEGIN0("blink,blink_style", 209 TRACE_EVENT_BEGIN0("blink,blink_style",
207 "CSSParserImpl::parseStyleSheet.parse"); 210 "CSSParserImpl::parseStyleSheet.parse");
208 CSSParserImpl parser(context, styleSheet); 211 CSSParserImpl parser(context, styleSheet, deferPropertyParsing);
209 bool firstRuleValid = parser.consumeRuleList( 212 bool firstRuleValid = parser.consumeRuleList(
210 scope.tokenRange(), TopLevelRuleList, [&styleSheet](StyleRuleBase* rule) { 213 styleSheet->m_scope.tokenRange(), TopLevelRuleList, [&styleSheet](StyleRul eBase* rule) {
211 if (rule->isCharsetRule()) 214 if (rule->isCharsetRule())
212 return; 215 return;
213 styleSheet->parserAppendRule(rule); 216 styleSheet->parserAppendRule(rule);
214 }); 217 });
215 styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid); 218 styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid);
219
220 // For lazy parsing the owning contents requires ownership of strings the
221 // scope allocates.
222 if (deferPropertyParsing)
223 styleSheet->takeEscapedStrings(styleSheet->m_scope.releaseEscapedStrings());
224
216 TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse"); 225 TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse");
217 226
218 TRACE_EVENT_END2("blink,blink_style", "CSSParserImpl::parseStyleSheet", 227 TRACE_EVENT_END2("blink,blink_style", "CSSParserImpl::parseStyleSheet",
219 "tokenCount", scope.tokenCount(), "length", string.length()); 228 "tokenCount", styleSheet->m_scope.tokenCount(), "length", str ing.length());
220 } 229 }
221 230
222 CSSSelectorList CSSParserImpl::parsePageSelector( 231 CSSSelectorList CSSParserImpl::parsePageSelector(
223 CSSParserTokenRange range, 232 CSSParserTokenRange range,
224 StyleSheetContents* styleSheet) { 233 StyleSheetContents* styleSheet) {
225 // We only support a small subset of the css-page spec. 234 // We only support a small subset of the css-page spec.
226 range.consumeWhitespace(); 235 range.consumeWhitespace();
227 AtomicString typeSelector; 236 AtomicString typeSelector;
228 if (range.peek().type() == IdentToken) 237 if (range.peek().type() == IdentToken)
229 typeSelector = range.consume().value().toAtomicString(); 238 typeSelector = range.consume().value().toAtomicString();
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 wrapper.observer().endRuleHeader(wrapper.endOffset(originalRange)); 767 wrapper.observer().endRuleHeader(wrapper.endOffset(originalRange));
759 } 768 }
760 769
761 StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, 770 StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude,
762 CSSParserTokenRange block) { 771 CSSParserTokenRange block) {
763 CSSSelectorList selectorList = 772 CSSSelectorList selectorList =
764 CSSSelectorParser::parseSelector(prelude, m_context, m_styleSheet); 773 CSSSelectorParser::parseSelector(prelude, m_context, m_styleSheet);
765 if (!selectorList.isValid()) 774 if (!selectorList.isValid())
766 return nullptr; // Parse error, invalid selector list 775 return nullptr; // Parse error, invalid selector list
767 776
768 if (m_observerWrapper) 777 // TODO(csharrison): How should we lazily parse css that needs the observer?
778 if (m_observerWrapper) {
769 observeSelectors(*m_observerWrapper, prelude); 779 observeSelectors(*m_observerWrapper, prelude);
770 780 } else if (m_deferPropertyParsing &&
781 shouldLazilyParseProperties(selectorList)) {
782 DCHECK(m_styleSheet);
783 return StyleRule::createLazy(
784 std::move(selectorList),
785 createDeferredPropertiesClosure(block, m_styleSheet->parserContext(),
786 m_context.useCounter()));
787 }
771 consumeDeclarationList(block, StyleRule::Style); 788 consumeDeclarationList(block, StyleRule::Style);
772
773 return StyleRule::create( 789 return StyleRule::create(
774 std::move(selectorList), 790 std::move(selectorList),
775 createStylePropertySet(m_parsedProperties, m_context.mode())); 791 createStylePropertySet(m_parsedProperties, m_context.mode()));
776 } 792 }
777 793
778 void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, 794 void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range,
779 StyleRule::RuleType ruleType) { 795 StyleRule::RuleType ruleType) {
780 ASSERT(m_parsedProperties.isEmpty()); 796 ASSERT(m_parsedProperties.isEmpty());
781 797
782 bool useObserver = m_observerWrapper && (ruleType == StyleRule::Style || 798 bool useObserver = m_observerWrapper && (ruleType == StyleRule::Style ||
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 result->append(1); 947 result->append(1);
932 else 948 else
933 return nullptr; // Parser error, invalid value in keyframe selector 949 return nullptr; // Parser error, invalid value in keyframe selector
934 if (range.atEnd()) 950 if (range.atEnd())
935 return result; 951 return result;
936 if (range.consume().type() != CommaToken) 952 if (range.consume().type() != CommaToken)
937 return nullptr; // Parser error 953 return nullptr; // Parser error
938 } 954 }
939 } 955 }
940 956
957 // The closure created here must not outlive the underlying StyleSheetContents,
958 // as it has non retaining references to the strings backing the tokens, as
959 // well as the parser context.
960 std::unique_ptr<DeferredPropertiesClosure>
961 CSSParserImpl::createDeferredPropertiesClosure(
962 CSSParserTokenRange block,
963 const CSSParserContext& sheetContext,
964 UseCounter* counter) {
965 return WTF::bind(&CSSParserImpl::parseDeclarationListForLazyStyle, block,
966 WTF::unretained(&sheetContext), WTF::unretained(counter));
967 }
968
969 StylePropertySet* CSSParserImpl::parseDeclarationListForLazyStyle(
970 CSSParserTokenRange block,
971 const CSSParserContext* sheetContext,
972 UseCounter* counter) {
973 CSSParserContext context(*sheetContext, counter);
974 CSSParserImpl parser(context);
975 parser.consumeDeclarationList(block, StyleRule::Style);
976 return createStylePropertySet(parser.m_parsedProperties, context.mode());
977 }
978
979 // Disallow lazy parsing for blocks which have
980 // - before/after in their selector list. This ensures we don't cause a
981 // collectFeatures() when we trigger parsing for attr() functions which would
982 // trigger expensive invalidation propagation.
983 //
984 // Note: another optimization might be to disallow lazy parsing for rules which
985 // will end up being empty. This is hard to know without parsing but we may be
986 // able to catch the {}, { } cases. This would be to hit
987 // StyleRule::shouldConsiderForMatchingRules more.
988 bool CSSParserImpl::shouldLazilyParseProperties(
989 const CSSSelectorList& selectors) {
990 for (const auto* s = selectors.first(); s; s = CSSSelectorList::next(*s)) {
991 const CSSSelector::PseudoType type(s->getPseudoType());
992 if (type == CSSSelector::PseudoBefore || type == CSSSelector::PseudoAfter)
993 return false;
994 }
995 return true;
996 }
997
941 } // namespace blink 998 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/parser/CSSParserImpl.h ('k') | third_party/WebKit/Source/core/css/parser/CSSTokenizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698