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

Side by Side Diff: Source/core/css/RuleSet.h

Issue 17314010: RuleSet causes 600 kB of memory fragmentation (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address reviewer feedback Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/core/css/RuleSet.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 * 19 *
20 */ 20 */
21 21
22 #ifndef RuleSet_h 22 #ifndef RuleSet_h
23 #define RuleSet_h 23 #define RuleSet_h
24 24
25 #include "core/css/RuleFeature.h" 25 #include "core/css/RuleFeature.h"
26 #include "core/css/StyleRule.h" 26 #include "core/css/StyleRule.h"
27 #include <wtf/Forward.h> 27 #include "wtf/Forward.h"
28 #include <wtf/HashMap.h> 28 #include "wtf/HashMap.h"
29 #include <wtf/HashSet.h> 29 #include "wtf/HashSet.h"
30 #include <wtf/text/AtomicString.h> 30 #include "wtf/LinkedStack.h"
31 #include "wtf/text/AtomicString.h"
31 32
32 namespace WebCore { 33 namespace WebCore {
33 34
34 enum AddRuleFlags { 35 enum AddRuleFlags {
35 RuleHasNoSpecialState = 0, 36 RuleHasNoSpecialState = 0,
36 RuleHasDocumentSecurityOrigin = 1, 37 RuleHasDocumentSecurityOrigin = 1,
37 RuleCanUseFastCheckSelector = 1 << 1, 38 RuleCanUseFastCheckSelector = 1 << 1,
38 RuleIsInRegionRule = 1 << 2, 39 RuleIsInRegionRule = 1 << 2,
39 }; 40 };
40 41
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED; 106 WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED;
106 public: 107 public:
107 static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); } 108 static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); }
108 109
109 void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, Styl eResolver* = 0, const ContainerNode* = 0); 110 void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, Styl eResolver* = 0, const ContainerNode* = 0);
110 void addStyleRule(StyleRule*, AddRuleFlags); 111 void addStyleRule(StyleRule*, AddRuleFlags);
111 void addRule(StyleRule*, unsigned selectorIndex, AddRuleFlags); 112 void addRule(StyleRule*, unsigned selectorIndex, AddRuleFlags);
112 113
113 const RuleFeatureSet& features() const { return m_features; } 114 const RuleFeatureSet& features() const { return m_features; }
114 115
115 const Vector<RuleData>* idRules(AtomicStringImpl* key) const { ASSERT(!m_has DirtyRules); return m_idRules.get(key); } 116 const Vector<RuleData>* idRules(AtomicStringImpl* key) const { ASSERT(!m_pen dingRules); return m_idRules.get(key); }
116 const Vector<RuleData>* classRules(AtomicStringImpl* key) const { ASSERT(!m_ hasDirtyRules); return m_classRules.get(key); } 117 const Vector<RuleData>* classRules(AtomicStringImpl* key) const { ASSERT(!m_ pendingRules); return m_classRules.get(key); }
117 const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { ASSERT(!m_ha sDirtyRules); return m_tagRules.get(key); } 118 const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { ASSERT(!m_pe ndingRules); return m_tagRules.get(key); }
118 const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) cons t { ASSERT(!m_hasDirtyRules); return m_shadowPseudoElementRules.get(key); } 119 const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) cons t { ASSERT(!m_pendingRules); return m_shadowPseudoElementRules.get(key); }
119 const Vector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_hasDirtyRul es); return &m_linkPseudoClassRules; } 120 const Vector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_pendingRule s); return &m_linkPseudoClassRules; }
120 const Vector<RuleData>* cuePseudoRules() const { ASSERT(!m_hasDirtyRules); r eturn &m_cuePseudoRules; } 121 const Vector<RuleData>* cuePseudoRules() const { ASSERT(!m_pendingRules); re turn &m_cuePseudoRules; }
121 const Vector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_hasDirtyRu les); return &m_focusPseudoClassRules; } 122 const Vector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_pendingRul es); return &m_focusPseudoClassRules; }
122 const Vector<RuleData>* universalRules() const { ASSERT(!m_hasDirtyRules); r eturn &m_universalRules; } 123 const Vector<RuleData>* universalRules() const { ASSERT(!m_pendingRules); re turn &m_universalRules; }
123 const Vector<StyleRulePage*>& pageRules() const { ASSERT(!m_hasDirtyRules); return m_pageRules; } 124 const Vector<StyleRulePage*>& pageRules() const { ASSERT(!m_pendingRules); r eturn m_pageRules; }
124 125
125 unsigned ruleCount() const { return m_ruleCount; } 126 unsigned ruleCount() const { return m_ruleCount; }
126 127
127 void compactRulesIfNeeded() 128 void compactRulesIfNeeded()
128 { 129 {
129 if (!m_hasDirtyRules) 130 if (!m_pendingRules)
130 return; 131 return;
131 shrinkToFit(); 132 compactRules();
132 } 133 }
133 134
134 void reportMemoryUsage(MemoryObjectInfo*) const; 135 void reportMemoryUsage(MemoryObjectInfo*) const;
135 136
136 struct RuleSetSelectorPair { 137 struct RuleSetSelectorPair {
137 RuleSetSelectorPair(const CSSSelector* selector, PassOwnPtr<RuleSet> rul eSet) : selector(selector), ruleSet(ruleSet) { } 138 RuleSetSelectorPair(const CSSSelector* selector, PassOwnPtr<RuleSet> rul eSet) : selector(selector), ruleSet(ruleSet) { }
138 RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selecto r), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { } 139 RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selecto r), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { }
139 void reportMemoryUsage(MemoryObjectInfo*) const; 140 void reportMemoryUsage(MemoryObjectInfo*) const;
140 141
141 const CSSSelector* selector; 142 const CSSSelector* selector;
142 OwnPtr<RuleSet> ruleSet; 143 OwnPtr<RuleSet> ruleSet;
143 }; 144 };
144 145
145 Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets; 146 Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets;
146 147
147 private: 148 private:
148 typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap; 149 typedef HashMap<AtomicStringImpl*, OwnPtr<LinkedStack<RuleData> > > PendingR uleMap;
150 typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > CompactRuleMa p;
149 151
150 RuleSet() 152 RuleSet()
151 : m_ruleCount(0) 153 : m_ruleCount(0)
152 , m_hasDirtyRules(false)
153 { 154 {
154 } 155 }
155 156
156 void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&); 157 void addToRuleSet(AtomicStringImpl* key, PendingRuleMap&, const RuleData&);
157 void addPageRule(StyleRulePage*); 158 void addPageRule(StyleRulePage*);
158 void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin); 159 void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin);
159 160
160 void addChildRules(const Vector<RefPtr<StyleRuleBase> >&, const MediaQueryEv aluator& medium, StyleResolver*, const ContainerNode* scope, bool hasDocumentSec urityOrigin, AddRuleFlags); 161 void addChildRules(const Vector<RefPtr<StyleRuleBase> >&, const MediaQueryEv aluator& medium, StyleResolver*, const ContainerNode* scope, bool hasDocumentSec urityOrigin, AddRuleFlags);
161 bool findBestRuleSetAndAdd(const CSSSelector*, RuleData&); 162 bool findBestRuleSetAndAdd(const CSSSelector*, RuleData&);
162 163
163 void shrinkToFit(); 164 void compactRules();
164 static inline void shrinkMapVectorsToFit(AtomRuleMap&); 165 static void compactPendingRules(PendingRuleMap&, CompactRuleMap&);
165 166
166 AtomRuleMap m_idRules; 167 struct PendingRuleMaps {
167 AtomRuleMap m_classRules; 168 PendingRuleMap idRules;
168 AtomRuleMap m_tagRules; 169 PendingRuleMap classRules;
169 AtomRuleMap m_shadowPseudoElementRules; 170 PendingRuleMap tagRules;
171 PendingRuleMap shadowPseudoElementRules;
172 };
173
174 PendingRuleMaps* ensurePendingRules()
175 {
176 if (!m_pendingRules)
177 m_pendingRules = adoptPtr(new PendingRuleMaps);
178 return m_pendingRules.get();
179 }
180
181 CompactRuleMap m_idRules;
182 CompactRuleMap m_classRules;
183 CompactRuleMap m_tagRules;
184 CompactRuleMap m_shadowPseudoElementRules;
170 Vector<RuleData> m_linkPseudoClassRules; 185 Vector<RuleData> m_linkPseudoClassRules;
171 Vector<RuleData> m_cuePseudoRules; 186 Vector<RuleData> m_cuePseudoRules;
172 Vector<RuleData> m_focusPseudoClassRules; 187 Vector<RuleData> m_focusPseudoClassRules;
173 Vector<RuleData> m_universalRules; 188 Vector<RuleData> m_universalRules;
174 RuleFeatureSet m_features; 189 RuleFeatureSet m_features;
175 Vector<StyleRulePage*> m_pageRules; 190 Vector<StyleRulePage*> m_pageRules;
176 191
177 unsigned m_ruleCount; 192 unsigned m_ruleCount;
178 bool m_hasDirtyRules; 193 OwnPtr<PendingRuleMaps> m_pendingRules;
179 }; 194 };
180 195
181 } // namespace WebCore 196 } // namespace WebCore
182 197
183 #endif // RuleSet_h 198 #endif // RuleSet_h
OLDNEW
« no previous file with comments | « no previous file | Source/core/css/RuleSet.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698