- Revision
- 216083
- Author
- [email protected]
- Date
- 2017-05-02 12:02:43 -0700 (Tue, 02 May 2017)
Log Message
Document style resolvers should share user rulesets
https://bugs.webkit.org/show_bug.cgi?id=171549
Reviewed by Andreas Kling.
Large user stylesheets (like those used by ad blockers) can end up using lots of memory if
a document uses large number of shadow trees. User style is inherently per-document and
the resulting rulesets can be shared between the document and the shadow trees.
* css/DocumentRuleSets.cpp:
(WebCore::DocumentRuleSets::DocumentRuleSets):
(WebCore::DocumentRuleSets::userStyle):
Return per-document user style for shadow trees.
(WebCore::DocumentRuleSets::collectFeatures):
* css/DocumentRuleSets.h:
(WebCore::DocumentRuleSets::setUsesSharedUserStyle):
(WebCore::DocumentRuleSets::userStyle): Deleted.
* css/StyleResolver.cpp:
(WebCore::StyleResolver::StyleResolver):
(WebCore::StyleResolver::initializeUserStyle):
Separate user style initialization from construction.
* css/StyleResolver.h:
* style/StyleScope.cpp:
(WebCore::Style::Scope::resolver):
Don't initialize user style for user agents shadow trees.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (216082 => 216083)
--- trunk/Source/WebCore/ChangeLog 2017-05-02 18:46:38 UTC (rev 216082)
+++ trunk/Source/WebCore/ChangeLog 2017-05-02 19:02:43 UTC (rev 216083)
@@ -1,3 +1,36 @@
+2017-05-02 Antti Koivisto <[email protected]>
+
+ Document style resolvers should share user rulesets
+ https://bugs.webkit.org/show_bug.cgi?id=171549
+
+ Reviewed by Andreas Kling.
+
+ Large user stylesheets (like those used by ad blockers) can end up using lots of memory if
+ a document uses large number of shadow trees. User style is inherently per-document and
+ the resulting rulesets can be shared between the document and the shadow trees.
+
+ * css/DocumentRuleSets.cpp:
+ (WebCore::DocumentRuleSets::DocumentRuleSets):
+ (WebCore::DocumentRuleSets::userStyle):
+
+ Return per-document user style for shadow trees.
+
+ (WebCore::DocumentRuleSets::collectFeatures):
+ * css/DocumentRuleSets.h:
+ (WebCore::DocumentRuleSets::setUsesSharedUserStyle):
+ (WebCore::DocumentRuleSets::userStyle): Deleted.
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::StyleResolver):
+ (WebCore::StyleResolver::initializeUserStyle):
+
+ Separate user style initialization from construction.
+
+ * css/StyleResolver.h:
+ * style/StyleScope.cpp:
+ (WebCore::Style::Scope::resolver):
+
+ Don't initialize user style for user agents shadow trees.
+
2017-05-02 Myles C. Maxfield <[email protected]>
Font Loading API specifies font is loaded but sizing of font after load reports inconsistent values
Modified: trunk/Source/WebCore/css/DocumentRuleSets.cpp (216082 => 216083)
--- trunk/Source/WebCore/css/DocumentRuleSets.cpp 2017-05-02 18:46:38 UTC (rev 216082)
+++ trunk/Source/WebCore/css/DocumentRuleSets.cpp 2017-05-02 19:02:43 UTC (rev 216083)
@@ -37,7 +37,8 @@
namespace WebCore {
-DocumentRuleSets::DocumentRuleSets()
+DocumentRuleSets::DocumentRuleSets(StyleResolver& styleResolver)
+ : m_styleResolver(styleResolver)
{
m_authorStyle = std::make_unique<RuleSet>();
m_authorStyle->disableAutoShrinkToFit();
@@ -47,13 +48,22 @@
{
}
-void DocumentRuleSets::initUserStyle(ExtensionStyleSheets& extensionStyleSheets, const MediaQueryEvaluator& medium, StyleResolver& resolver)
+RuleSet* DocumentRuleSets::userStyle() const
{
+ if (m_usesSharedUserStyle)
+ return m_styleResolver.document().styleScope().resolver().ruleSets().userStyle();
+ return m_userStyle.get();
+}
+
+void DocumentRuleSets::initializeUserStyle()
+{
+ auto& extensionStyleSheets = m_styleResolver.document().extensionStyleSheets();
+ auto& mediaQueryEvaluator = m_styleResolver.mediaQueryEvaluator();
auto tempUserStyle = std::make_unique<RuleSet>();
if (CSSStyleSheet* pageUserSheet = extensionStyleSheets.pageUserSheet())
- tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), medium, &resolver);
- collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), *tempUserStyle, medium, resolver);
- collectRulesFromUserStyleSheets(extensionStyleSheets.documentUserStyleSheets(), *tempUserStyle, medium, resolver);
+ tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), mediaQueryEvaluator, &m_styleResolver);
+ collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), *tempUserStyle, mediaQueryEvaluator, m_styleResolver);
+ collectRulesFromUserStyleSheets(extensionStyleSheets.documentUserStyleSheets(), *tempUserStyle, mediaQueryEvaluator, m_styleResolver);
if (tempUserStyle->ruleCount() > 0 || tempUserStyle->pageRules().size() > 0)
m_userStyle = WTFMove(tempUserStyle);
}
@@ -112,8 +122,8 @@
if (m_authorStyle)
m_features.add(m_authorStyle->features());
- if (m_userStyle)
- m_features.add(m_userStyle->features());
+ if (auto* userStyle = this->userStyle())
+ m_features.add(userStyle->features());
m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
Modified: trunk/Source/WebCore/css/DocumentRuleSets.h (216082 => 216083)
--- trunk/Source/WebCore/css/DocumentRuleSets.h 2017-05-02 18:46:38 UTC (rev 216082)
+++ trunk/Source/WebCore/css/DocumentRuleSets.h 2017-05-02 19:02:43 UTC (rev 216083)
@@ -40,12 +40,12 @@
class DocumentRuleSets {
public:
- DocumentRuleSets();
+ DocumentRuleSets(StyleResolver&);
~DocumentRuleSets();
-
+
bool isAuthorStyleDefined() const { return m_isAuthorStyleDefined; }
RuleSet& authorStyle() const { return *m_authorStyle.get(); }
- RuleSet* userStyle() const { return m_userStyle.get(); }
+ RuleSet* userStyle() const;
const RuleFeatureSet& features() const;
RuleSet* sibling() const { return m_siblingRuleSet.get(); }
RuleSet* uncommonAttribute() const { return m_uncommonAttributeRuleSet.get(); }
@@ -59,7 +59,9 @@
};
const AttributeRules* ancestorAttributeRulesForHTML(const AtomicString&) const;
- void initUserStyle(ExtensionStyleSheets&, const MediaQueryEvaluator&, StyleResolver&);
+ void setUsesSharedUserStyle(bool b) { m_usesSharedUserStyle = b; }
+ void initializeUserStyle();
+
void resetAuthorStyle();
void appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&, MediaQueryEvaluator*, InspectorCSSOMWrappers&, StyleResolver*);
@@ -72,7 +74,9 @@
bool m_isAuthorStyleDefined { false };
std::unique_ptr<RuleSet> m_authorStyle;
std::unique_ptr<RuleSet> m_userStyle;
+ bool m_usesSharedUserStyle { false };
+ StyleResolver& m_styleResolver;
mutable RuleFeatureSet m_features;
mutable unsigned m_defaultStyleVersionOnFeatureCollection { 0 };
mutable std::unique_ptr<RuleSet> m_siblingRuleSet;
Modified: trunk/Source/WebCore/css/StyleResolver.cpp (216082 => 216083)
--- trunk/Source/WebCore/css/StyleResolver.cpp 2017-05-02 18:46:38 UTC (rev 216082)
+++ trunk/Source/WebCore/css/StyleResolver.cpp 2017-05-02 19:02:43 UTC (rev 216083)
@@ -228,7 +228,8 @@
}
StyleResolver::StyleResolver(Document& document)
- : m_matchedPropertiesCacheAdditionsSinceLastSweep(0)
+ : m_ruleSets(*this)
+ , m_matchedPropertiesCacheAdditionsSinceLastSweep(0)
, m_matchedPropertiesCacheSweepTimer(*this, &StyleResolver::sweepMatchedPropertiesCache)
, m_document(document)
, m_matchAuthorAndUserStyles(m_document.settings().authorAndUserStylesEnabled())
@@ -267,8 +268,6 @@
m_ruleSets.resetAuthorStyle();
- m_ruleSets.initUserStyle(m_document.extensionStyleSheets(), m_mediaQueryEvaluator, *this);
-
#if ENABLE(SVG_FONTS)
if (m_document.svgExtensions()) {
const HashSet<SVGFontFaceElement*>& svgFontFaceElements = m_document.svgExtensions()->svgFontFaceElements();
Modified: trunk/Source/WebCore/style/StyleScope.cpp (216082 => 216083)
--- trunk/Source/WebCore/style/StyleScope.cpp 2017-05-02 18:46:38 UTC (rev 216082)
+++ trunk/Source/WebCore/style/StyleScope.cpp 2017-05-02 19:02:43 UTC (rev 216083)
@@ -96,6 +96,12 @@
if (!m_resolver) {
SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
m_resolver = std::make_unique<StyleResolver>(m_document);
+
+ if (!m_shadowRoot)
+ m_resolver->ruleSets().initializeUserStyle();
+ else
+ m_resolver->ruleSets().setUsesSharedUserStyle(m_shadowRoot->mode() != ShadowRootMode::UserAgent);
+
m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);
}
ASSERT(!m_shadowRoot || &m_document == &m_shadowRoot->document());