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

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

Issue 2315923002: Lazy Parse CSS (Closed)
Patch Set: plug leaks Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
index f5bd2e8b8f5f2e1f04e700fea4bbf5833d8ffc5c..37e258ec856409a1df31f67299e15deda89dff73 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
@@ -34,10 +34,11 @@
namespace blink {
-CSSParserImpl::CSSParserImpl(const CSSParserContext& context, StyleSheetContents* styleSheet)
+CSSParserImpl::CSSParserImpl(const CSSParserContext& context, StyleSheetContents* styleSheet, bool deferPropertyParsing)
: m_context(context)
, m_styleSheet(styleSheet)
, m_observerWrapper(nullptr)
+, m_deferPropertyParsing(deferPropertyParsing)
{
}
@@ -159,7 +160,7 @@ StyleRuleBase* CSSParserImpl::parseRule(const String& string, const CSSParserCon
return rule;
}
-void CSSParserImpl::parseStyleSheet(const String& string, const CSSParserContext& context, StyleSheetContents* styleSheet)
+void CSSParserImpl::parseStyleSheet(const String& string, const CSSParserContext& context, StyleSheetContents* styleSheet, bool deferPropertyParsing)
{
TRACE_EVENT_BEGIN2(
"blink,blink_style", "CSSParserImpl::parseStyleSheet",
@@ -171,13 +172,19 @@ void CSSParserImpl::parseStyleSheet(const String& string, const CSSParserContext
TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.tokenize");
TRACE_EVENT_BEGIN0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse");
- CSSParserImpl parser(context, styleSheet);
+ CSSParserImpl parser(context, styleSheet, deferPropertyParsing);
bool firstRuleValid = parser.consumeRuleList(scope.tokenRange(), TopLevelRuleList, [&styleSheet](StyleRuleBase* rule) {
if (rule->isCharsetRule())
return;
styleSheet->parserAppendRule(rule);
});
styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid);
+
+ // For lazy parsing the owning contents requires ownership of strings the
+ // scope allocates.
+ if (deferPropertyParsing)
+ styleSheet->takeEscapedStrings(scope.releaseEscapedStrings());
+
TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse");
TRACE_EVENT_END2(
@@ -681,11 +688,19 @@ StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, CSSParse
if (!selectorList.isValid())
return nullptr; // Parse error, invalid selector list
- if (m_observerWrapper)
+ // TODO(csharrison): How should we lazily parse css that needs the observer?
+ if (m_observerWrapper) {
observeSelectors(*m_observerWrapper, prelude);
+ } else if (m_deferPropertyParsing) {
+ DCHECK(m_styleSheet);
+ bool forceStrict = false;
+ StyleRule* rule = StyleRule::createLazy(std::move(selectorList), createDeferredPropertiesClosure(block, m_context, &forceStrict));
+ if (forceStrict)
+ rule->properties();
+ return rule;
+ }
consumeDeclarationList(block, StyleRule::Style);
-
return StyleRule::create(std::move(selectorList), createStylePropertySet(m_parsedProperties, m_context.mode()));
}
@@ -820,4 +835,41 @@ std::unique_ptr<Vector<double>> CSSParserImpl::consumeKeyframeKeyList(CSSParserT
}
}
+// The closure created here must not outlive the underlying StyleSheetContents,
+// as it has non retaining references to the strings backing the tokens, as
+// well as the parser context.
+// Sets forceStrict to true if we should bail out on lazy parsing. This occurs
+// for:
+// - attr() functions (which require invalidation set propogation)
+// - Empty property sets (so that emptiness can be established without forcing
+// a strict point in general.
+std::unique_ptr<CSSParser::DeferredPropertiesClosure> CSSParserImpl::createDeferredPropertiesClosure(CSSParserTokenRange block, const CSSParserContext& context, bool* forceStrict)
+{
+ // TODO(csharrison): A slightly more complex design could have the
+ // StyleSheetContents own the tokens. This would mean we don't have to copy
+ // them to a local vector here.
+ size_t length = block.end() - block.begin();
+ std::unique_ptr<Vector<CSSParserToken>> tokens = WTF::wrapUnique(new Vector<CSSParserToken>);
+ tokens->reserveInitialCapacity(length);
+ while (!block.atEnd()) {
+ const CSSParserToken& token = block.consume();
+ if (token.type() == CSSParserTokenType::FunctionToken && token.value() == "attr") {
Timothy Loh 2016/09/26 05:18:00 I think attr is case insensitive.
Charlie Harrison 2016/09/26 22:14:45 I've moved the check to checking "before/after" in
+ *forceStrict = true;
+ }
+ tokens->append(token);
Timothy Loh 2016/09/26 05:18:01 Probably nicer to use Vector::append(const U*, siz
Charlie Harrison 2016/09/26 22:14:45 Cool :) Done.
+ }
+ if (tokens->isEmpty())
+ *forceStrict = true;
+
+ return WTF::bind(&CSSParserImpl::parseDeclarationListForLazyStyle, WTF::passed(std::move(tokens)), WTF::unretained(&context));
+}
+
+StylePropertySet* CSSParserImpl::parseDeclarationListForLazyStyle(std::unique_ptr<Vector<CSSParserToken>> block, const CSSParserContext* context)
+{
+ CSSParserImpl parser(*context);
+ parser.consumeDeclarationList(*block, StyleRule::Style);
+ return createStylePropertySet(parser.m_parsedProperties, context->mode());
+}
+
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698