Some improvements to RuleSet shrinking.
<https://webkit.org/b/140534>

Reviewed by Antti Koivisto.

Give an inline capacity (1) to the RuleData Vectors in RuleSet.
The vast majority of Vectors have only a single entry, and this
avoids having to allocate a separate Vector backing store for them.

Also make sure to shrink some Vectors that we weren't already,
like those in RuleFeatureSet.

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::collectMatchingRulesForList):
* css/ElementRuleCollector.h:
* css/RuleFeature.cpp:
(WebCore::RuleFeatureSet::shrinkToFit):
* css/RuleFeature.h:
* css/RuleSet.cpp:
(WebCore::RuleSet::addToRuleSet):
(WebCore::rulesCountForName):
(WebCore::shrinkMapVectorsToFit):
(WebCore::RuleSet::shrinkToFit):
* css/RuleSet.h:
(WebCore::RuleSet::idRules):
(WebCore::RuleSet::classRules):
(WebCore::RuleSet::tagRules):
(WebCore::RuleSet::shadowPseudoElementRules):
(WebCore::RuleSet::linkPseudoClassRules):
(WebCore::RuleSet::cuePseudoRules):
(WebCore::RuleSet::focusPseudoClassRules):
(WebCore::RuleSet::universalRules):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@178580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index a43aa0c..755f70b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,38 @@
+2015-01-16  Andreas Kling  <akling@apple.com>
+
+        Some improvements to RuleSet shrinking.
+        <https://webkit.org/b/140534>
+
+        Reviewed by Antti Koivisto.
+
+        Give an inline capacity (1) to the RuleData Vectors in RuleSet.
+        The vast majority of Vectors have only a single entry, and this
+        avoids having to allocate a separate Vector backing store for them.
+
+        Also make sure to shrink some Vectors that we weren't already,
+        like those in RuleFeatureSet.
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+        * css/ElementRuleCollector.h:
+        * css/RuleFeature.cpp:
+        (WebCore::RuleFeatureSet::shrinkToFit):
+        * css/RuleFeature.h:
+        * css/RuleSet.cpp:
+        (WebCore::RuleSet::addToRuleSet):
+        (WebCore::rulesCountForName):
+        (WebCore::shrinkMapVectorsToFit):
+        (WebCore::RuleSet::shrinkToFit):
+        * css/RuleSet.h:
+        (WebCore::RuleSet::idRules):
+        (WebCore::RuleSet::classRules):
+        (WebCore::RuleSet::tagRules):
+        (WebCore::RuleSet::shadowPseudoElementRules):
+        (WebCore::RuleSet::linkPseudoClassRules):
+        (WebCore::RuleSet::cuePseudoRules):
+        (WebCore::RuleSet::focusPseudoClassRules):
+        (WebCore::RuleSet::universalRules):
+
 2015-01-16  Antti Koivisto  <antti@apple.com>
 
         Correct naming for FontCascade implementation files
diff --git a/Source/WebCore/css/ElementRuleCollector.cpp b/Source/WebCore/css/ElementRuleCollector.cpp
index 0081a27..bacf797 100644
--- a/Source/WebCore/css/ElementRuleCollector.cpp
+++ b/Source/WebCore/css/ElementRuleCollector.cpp
@@ -351,7 +351,7 @@
     return selectorChecker.match(ruleData.selector(), &m_element, context, specificity);
 }
 
-void ElementRuleCollector::collectMatchingRulesForList(const Vector<RuleData>* rules, const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
+void ElementRuleCollector::collectMatchingRulesForList(const RuleSet::RuleDataVector* rules, const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
 {
     if (!rules)
         return;
diff --git a/Source/WebCore/css/ElementRuleCollector.h b/Source/WebCore/css/ElementRuleCollector.h
index 18a50cb..36b31ee 100644
--- a/Source/WebCore/css/ElementRuleCollector.h
+++ b/Source/WebCore/css/ElementRuleCollector.h
@@ -85,7 +85,7 @@
 
     void collectMatchingRules(const MatchRequest&, StyleResolver::RuleRange&);
     void collectMatchingRulesForRegion(const MatchRequest&, StyleResolver::RuleRange&);
-    void collectMatchingRulesForList(const Vector<RuleData>*, const MatchRequest&, StyleResolver::RuleRange&);
+    void collectMatchingRulesForList(const RuleSet::RuleDataVector*, const MatchRequest&, StyleResolver::RuleRange&);
     bool ruleMatches(const RuleData&, unsigned &specificity);
 
     void sortMatchedRules();
diff --git a/Source/WebCore/css/RuleFeature.cpp b/Source/WebCore/css/RuleFeature.cpp
index a3fa98a..c24ec82 100644
--- a/Source/WebCore/css/RuleFeature.cpp
+++ b/Source/WebCore/css/RuleFeature.cpp
@@ -103,4 +103,10 @@
     usesFirstLetterRules = false;
 }
 
+void RuleFeatureSet::shrinkToFit()
+{
+    siblingRules.shrinkToFit();
+    uncommonAttributeRules.shrinkToFit();
+}
+
 } // namespace WebCore
diff --git a/Source/WebCore/css/RuleFeature.h b/Source/WebCore/css/RuleFeature.h
index 0aad811..0a3a57e 100644
--- a/Source/WebCore/css/RuleFeature.h
+++ b/Source/WebCore/css/RuleFeature.h
@@ -52,7 +52,7 @@
 
     void add(const RuleFeatureSet&);
     void clear();
-
+    void shrinkToFit();
     void collectFeaturesFromSelector(const CSSSelector&, bool& hasSiblingSelector);
 
     HashSet<AtomicStringImpl*> idsInRules;
diff --git a/Source/WebCore/css/RuleSet.cpp b/Source/WebCore/css/RuleSet.cpp
index 59a1a26..be73c21 100644
--- a/Source/WebCore/css/RuleSet.cpp
+++ b/Source/WebCore/css/RuleSet.cpp
@@ -183,15 +183,15 @@
 {
     if (!key)
         return;
-    std::unique_ptr<Vector<RuleData>>& rules = map.add(key, nullptr).iterator->value;
+    auto& rules = map.add(key, nullptr).iterator->value;
     if (!rules)
-        rules = std::make_unique<Vector<RuleData>>();
+        rules = std::make_unique<RuleDataVector>();
     rules->append(ruleData);
 }
 
 static unsigned rulesCountForName(const RuleSet::AtomRuleMap& map, AtomicStringImpl* name)
 {
-    if (const Vector<RuleData>* rules = map.get(name))
+    if (const auto* rules = map.get(name))
         return rules->size();
     return 0;
 }
@@ -377,9 +377,8 @@
 
 static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
 {
-    RuleSet::AtomRuleMap::iterator end = map.end();
-    for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it)
-        it->value->shrinkToFit();
+    for (auto& vector : map.values())
+        vector->shrinkToFit();
 }
 
 void RuleSet::shrinkToFit()
@@ -395,6 +394,8 @@
     m_focusPseudoClassRules.shrinkToFit();
     m_universalRules.shrinkToFit();
     m_pageRules.shrinkToFit();
+    m_features.shrinkToFit();
+    m_regionSelectorsAndRuleSets.shrinkToFit();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/RuleSet.h b/Source/WebCore/css/RuleSet.h
index e7d8a0b..e6430cc 100644
--- a/Source/WebCore/css/RuleSet.h
+++ b/Source/WebCore/css/RuleSet.h
@@ -155,7 +155,8 @@
 
     RuleSet();
 
-    typedef HashMap<AtomicStringImpl*, std::unique_ptr<Vector<RuleData>>> AtomRuleMap;
+    typedef Vector<RuleData, 1> RuleDataVector;
+    typedef HashMap<AtomicStringImpl*, std::unique_ptr<RuleDataVector>> AtomRuleMap;
 
     void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, StyleResolver* = 0);
 
@@ -169,16 +170,17 @@
 
     const RuleFeatureSet& features() const { return m_features; }
 
-    const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
-    const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
-    const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); }
-    const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) const { return m_shadowPseudoElementRules.get(key); }
-    const Vector<RuleData>* linkPseudoClassRules() const { return &m_linkPseudoClassRules; }
+    const RuleDataVector* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
+    const RuleDataVector* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
+    const RuleDataVector* tagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); }
+    const RuleDataVector* shadowPseudoElementRules(AtomicStringImpl* key) const { return m_shadowPseudoElementRules.get(key); }
+    const RuleDataVector* linkPseudoClassRules() const { return &m_linkPseudoClassRules; }
 #if ENABLE(VIDEO_TRACK)
-    const Vector<RuleData>* cuePseudoRules() const { return &m_cuePseudoRules; }
+    const RuleDataVector* cuePseudoRules() const { return &m_cuePseudoRules; }
 #endif
-    const Vector<RuleData>* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
-    const Vector<RuleData>* universalRules() const { return &m_universalRules; }
+    const RuleDataVector* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
+    const RuleDataVector* universalRules() const { return &m_universalRules; }
+
     const Vector<StyleRulePage*>& pageRules() const { return m_pageRules; }
     const Vector<RuleSetSelectorPair>& regionSelectorsAndRuleSets() const { return m_regionSelectorsAndRuleSets; }
 
@@ -193,12 +195,12 @@
     AtomRuleMap m_classRules;
     AtomRuleMap m_tagRules;
     AtomRuleMap m_shadowPseudoElementRules;
-    Vector<RuleData> m_linkPseudoClassRules;
+    RuleDataVector m_linkPseudoClassRules;
 #if ENABLE(VIDEO_TRACK)
-    Vector<RuleData> m_cuePseudoRules;
+    RuleDataVector m_cuePseudoRules;
 #endif
-    Vector<RuleData> m_focusPseudoClassRules;
-    Vector<RuleData> m_universalRules;
+    RuleDataVector m_focusPseudoClassRules;
+    RuleDataVector m_universalRules;
     Vector<StyleRulePage*> m_pageRules;
     unsigned m_ruleCount;
     bool m_autoShrinkToFitEnabled;