| Index: Source/core/css/RuleSet.cpp
|
| diff --git a/Source/core/css/RuleSet.cpp b/Source/core/css/RuleSet.cpp
|
| index a08c06c7676b3fd6617e5eb3798d7bf6fe4e6724..f5db396722d2cb80c02d923affc4fad1de4b97c6 100644
|
| --- a/Source/core/css/RuleSet.cpp
|
| +++ b/Source/core/css/RuleSet.cpp
|
| @@ -200,28 +200,28 @@ static void collectFeaturesFromRuleData(RuleFeatureSet& features, const RuleData
|
| features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
|
| }
|
|
|
| -void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData)
|
| +void RuleSet::addToRuleSet(AtomicStringImpl* key, PendingRuleMap& map, const RuleData& ruleData)
|
| {
|
| if (!key)
|
| return;
|
| - OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).iterator->value;
|
| + OwnPtr<LinkedStack<RuleData> >& rules = map.add(key, nullptr).iterator->value;
|
| if (!rules)
|
| - rules = adoptPtr(new Vector<RuleData>);
|
| - rules->append(ruleData);
|
| + rules = adoptPtr(new LinkedStack<RuleData>);
|
| + rules->push(ruleData);
|
| }
|
|
|
| bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& ruleData)
|
| {
|
| if (component->m_match == CSSSelector::Id) {
|
| - addToRuleSet(component->value().impl(), m_idRules, ruleData);
|
| + addToRuleSet(component->value().impl(), ensurePendingRules()->idRules, ruleData);
|
| return true;
|
| }
|
| if (component->m_match == CSSSelector::Class) {
|
| - addToRuleSet(component->value().impl(), m_classRules, ruleData);
|
| + addToRuleSet(component->value().impl(), ensurePendingRules()->classRules, ruleData);
|
| return true;
|
| }
|
| if (component->isCustomPseudoElement()) {
|
| - addToRuleSet(component->value().impl(), m_shadowPseudoElementRules, ruleData);
|
| + addToRuleSet(component->value().impl(), ensurePendingRules()->shadowPseudoElementRules, ruleData);
|
| return true;
|
| }
|
| if (component->pseudoType() == CSSSelector::PseudoCue) {
|
| @@ -252,7 +252,7 @@ bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& rule
|
| && findBestRuleSetAndAdd(component->tagHistory(), ruleData))
|
| return true;
|
|
|
| - addToRuleSet(component->tagQName().localName().impl(), m_tagRules, ruleData);
|
| + addToRuleSet(component->tagQName().localName().impl(), ensurePendingRules()->tagRules, ruleData);
|
| return true;
|
| }
|
| }
|
| @@ -261,7 +261,6 @@ bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& rule
|
|
|
| void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addRuleFlags)
|
| {
|
| - m_hasDirtyRules = true;
|
| RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
|
| collectFeaturesFromRuleData(m_features, ruleData);
|
|
|
| @@ -273,13 +272,13 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addR
|
|
|
| void RuleSet::addPageRule(StyleRulePage* rule)
|
| {
|
| - m_hasDirtyRules = true;
|
| + ensurePendingRules(); // So that m_pageRules.shrinkToFit() gets called.
|
| m_pageRules.append(rule);
|
| }
|
|
|
| void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin)
|
| {
|
| - m_hasDirtyRules = true;
|
| + ensurePendingRules(); // So that m_regionSelectorsAndRuleSets.shrinkToFit() gets called.
|
| OwnPtr<RuleSet> regionRuleSet = RuleSet::create();
|
| // The region rule set should take into account the position inside the parent rule set.
|
| // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from
|
| @@ -379,20 +378,39 @@ void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags)
|
| addRule(rule, selectorIndex, addRuleFlags);
|
| }
|
|
|
| -void RuleSet::shrinkMapVectorsToFit(AtomRuleMap& map)
|
| +void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& compactMap)
|
| {
|
| - RuleSet::AtomRuleMap::iterator end = map.end();
|
| - for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it)
|
| - it->value->shrinkToFit();
|
| + PendingRuleMap::iterator end = pendingMap.end();
|
| + for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) {
|
| + OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release();
|
| + size_t pendingSize = pendingRules->size();
|
| + ASSERT(pendingSize);
|
| +
|
| + OwnPtr<Vector<RuleData> >& compactRules = compactMap.add(it->key, nullptr).iterator->value;
|
| + if (!compactRules) {
|
| + compactRules = adoptPtr(new Vector<RuleData>);
|
| + compactRules->reserveInitialCapacity(pendingSize);
|
| + } else {
|
| + compactRules->reserveCapacity(compactRules->size() + pendingSize);
|
| + }
|
| +
|
| + while (!pendingRules->isEmpty()) {
|
| + compactRules->append(pendingRules->peek());
|
| + pendingRules->pop();
|
| + }
|
| +
|
| + ASSERT(compactRules->size() == compactRules->capacity());
|
| + }
|
| }
|
|
|
| -void RuleSet::shrinkToFit()
|
| +void RuleSet::compactRules()
|
| {
|
| - m_hasDirtyRules = false;
|
| - shrinkMapVectorsToFit(m_idRules);
|
| - shrinkMapVectorsToFit(m_classRules);
|
| - shrinkMapVectorsToFit(m_tagRules);
|
| - shrinkMapVectorsToFit(m_shadowPseudoElementRules);
|
| + ASSERT(m_pendingRules);
|
| + OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release();
|
| + compactPendingRules(pendingRules->idRules, m_idRules);
|
| + compactPendingRules(pendingRules->classRules, m_classRules);
|
| + compactPendingRules(pendingRules->tagRules, m_tagRules);
|
| + compactPendingRules(pendingRules->shadowPseudoElementRules, m_shadowPseudoElementRules);
|
| m_linkPseudoClassRules.shrinkToFit();
|
| m_cuePseudoRules.shrinkToFit();
|
| m_focusPseudoClassRules.shrinkToFit();
|
|
|