OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 { | 123 { |
124 if (addRuleFlags & RuleIsInRegionRule) | 124 if (addRuleFlags & RuleIsInRegionRule) |
125 return PropertyWhitelistRegion; | 125 return PropertyWhitelistRegion; |
126 for (const CSSSelector* component = selector; component; component = compone nt->tagHistory()) { | 126 for (const CSSSelector* component = selector; component; component = compone nt->tagHistory()) { |
127 if (component->pseudoType() == CSSSelector::PseudoCue || (component->m_m atch == CSSSelector::PseudoElement && component->value() == TextTrackCue::cueSha dowPseudoId())) | 127 if (component->pseudoType() == CSSSelector::PseudoCue || (component->m_m atch == CSSSelector::PseudoElement && component->value() == TextTrackCue::cueSha dowPseudoId())) |
128 return PropertyWhitelistCue; | 128 return PropertyWhitelistCue; |
129 } | 129 } |
130 return PropertyWhitelistNone; | 130 return PropertyWhitelistNone; |
131 } | 131 } |
132 | 132 |
133 namespace { | |
134 | |
135 // FIXME: Should we move this class to WTF? | |
136 template<typename T> | |
137 class TerminatedArrayBuilder { | |
esprehn
2013/06/26 00:37:33
I'd rather we added a TerminatedArray<T> class wit
abarth-chromium
2013/06/26 00:57:00
Ok. I struggled with how much to abstract this wo
| |
138 public: | |
139 explicit TerminatedArrayBuilder(PassOwnPtr<T> array) | |
140 : m_array(array) | |
141 , m_count(0) | |
142 , m_capacity(0) | |
143 { | |
144 if (!m_array) | |
145 return; | |
146 for (T* item = m_array.get(); !item->isLastInArray(); ++item) | |
147 ++m_count; | |
148 ++m_count; // To count the last item itself. | |
149 m_capacity = m_count; | |
150 } | |
151 | |
152 void grow(size_t count) | |
153 { | |
154 ASSERT(count); | |
155 if (!m_array) { | |
156 ASSERT(!m_count); | |
157 ASSERT(!m_capacity); | |
158 m_capacity = count; | |
159 m_array = adoptPtr(static_cast<T*>(fastMalloc(m_capacity * sizeof(T) ))); | |
160 return; | |
161 } | |
162 m_capacity += count; | |
163 m_array = adoptPtr(static_cast<T*>(fastRealloc(m_array.leakPtr(), m_capa city * sizeof(T)))); | |
164 m_array.get()[m_count - 1].setLastInArray(false); | |
165 } | |
166 | |
167 void append(const T& item) | |
168 { | |
169 RELEASE_ASSERT(m_count < m_capacity); | |
170 m_array.get()[m_count++] = item; | |
esprehn
2013/06/26 00:37:33
This looks easy to break, I can append() an item t
abarth-chromium
2013/06/26 00:57:00
There's an ASSERT in release() to make sure the ar
| |
171 } | |
172 | |
173 PassOwnPtr<T> release() | |
174 { | |
175 RELEASE_ASSERT(m_count == m_capacity); | |
176 if (m_array) | |
177 m_array.get()[m_count - 1].setLastInArray(true); | |
178 assertValid(); | |
179 return m_array.release(); | |
180 } | |
181 | |
182 private: | |
183 #ifndef NDEBUG | |
184 void assertValid() | |
185 { | |
186 for (size_t i = 0; i < m_count; ++i) { | |
187 bool isLastInArray = (i + 1 == m_count); | |
188 ASSERT(m_array.get()[i].isLastInArray() == isLastInArray); | |
189 } | |
190 } | |
191 #else | |
192 void assertValid() { } | |
193 #endif | |
194 | |
195 OwnPtr<T> m_array; | |
196 size_t m_count; | |
197 size_t m_capacity; | |
198 }; | |
199 | |
200 } | |
201 | |
133 RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, A ddRuleFlags addRuleFlags) | 202 RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, A ddRuleFlags addRuleFlags) |
134 : m_rule(rule) | 203 : m_rule(rule) |
135 , m_selectorIndex(selectorIndex) | 204 , m_selectorIndex(selectorIndex) |
205 , m_isLastInArray(0) | |
esprehn
2013/06/26 00:37:33
I think you can just do false here.
abarth-chromium
2013/06/26 00:57:00
Done.
| |
136 , m_position(position) | 206 , m_position(position) |
137 , m_hasFastCheckableSelector((addRuleFlags & RuleCanUseFastCheckSelector) && SelectorCheckerFastPath::canUse(selector())) | 207 , m_hasFastCheckableSelector((addRuleFlags & RuleCanUseFastCheckSelector) && SelectorCheckerFastPath::canUse(selector())) |
138 , m_specificity(selector()->specificity()) | 208 , m_specificity(selector()->specificity()) |
139 , m_hasMultipartSelector(!!selector()->tagHistory()) | 209 , m_hasMultipartSelector(!!selector()->tagHistory()) |
140 , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBa sedOnRuleHash(selector())) | 210 , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBa sedOnRuleHash(selector())) |
141 , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSele ctor(selector())) | 211 , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSele ctor(selector())) |
142 , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector())) | 212 , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector())) |
143 , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin) | 213 , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin) |
144 , m_propertyWhitelistType(determinePropertyWhitelistType(addRuleFlags, selec tor())) | 214 , m_propertyWhitelistType(determinePropertyWhitelistType(addRuleFlags, selec tor())) |
145 { | 215 { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 { | 444 { |
375 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = ru le->selectorList().indexOfNextSelectorAfter(selectorIndex)) | 445 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = ru le->selectorList().indexOfNextSelectorAfter(selectorIndex)) |
376 addRule(rule, selectorIndex, addRuleFlags); | 446 addRule(rule, selectorIndex, addRuleFlags); |
377 } | 447 } |
378 | 448 |
379 void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& co mpactMap) | 449 void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& co mpactMap) |
380 { | 450 { |
381 PendingRuleMap::iterator end = pendingMap.end(); | 451 PendingRuleMap::iterator end = pendingMap.end(); |
382 for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) { | 452 for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) { |
383 OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release(); | 453 OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release(); |
384 size_t pendingSize = pendingRules->size(); | 454 CompactRuleMap::iterator compactRules = compactMap.add(it->key, nullptr) .iterator; |
385 ASSERT(pendingSize); | |
386 | 455 |
387 OwnPtr<Vector<RuleData> >& compactRules = compactMap.add(it->key, nullpt r).iterator->value; | 456 TerminatedArrayBuilder<RuleData> builder(compactRules->value.release()); |
388 if (!compactRules) { | 457 builder.grow(pendingRules->size()); |
389 compactRules = adoptPtr(new Vector<RuleData>); | 458 while (!pendingRules->isEmpty()) { |
390 compactRules->reserveInitialCapacity(pendingSize); | 459 builder.append(pendingRules->peek()); |
391 } else { | 460 pendingRules->pop(); |
392 compactRules->reserveCapacity(compactRules->size() + pendingSize); | |
393 } | 461 } |
394 | 462 |
395 while (!pendingRules->isEmpty()) { | 463 compactRules->value = builder.release(); |
396 compactRules->append(pendingRules->peek()); | |
397 pendingRules->pop(); | |
398 } | |
399 } | 464 } |
400 } | 465 } |
401 | 466 |
402 void RuleSet::compactRules() | 467 void RuleSet::compactRules() |
403 { | 468 { |
404 ASSERT(m_pendingRules); | 469 ASSERT(m_pendingRules); |
405 OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release(); | 470 OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release(); |
406 compactPendingRules(pendingRules->idRules, m_idRules); | 471 compactPendingRules(pendingRules->idRules, m_idRules); |
407 compactPendingRules(pendingRules->classRules, m_classRules); | 472 compactPendingRules(pendingRules->classRules, m_classRules); |
408 compactPendingRules(pendingRules->tagRules, m_tagRules); | 473 compactPendingRules(pendingRules->tagRules, m_tagRules); |
409 compactPendingRules(pendingRules->shadowPseudoElementRules, m_shadowPseudoEl ementRules); | 474 compactPendingRules(pendingRules->shadowPseudoElementRules, m_shadowPseudoEl ementRules); |
410 m_linkPseudoClassRules.shrinkToFit(); | 475 m_linkPseudoClassRules.shrinkToFit(); |
411 m_cuePseudoRules.shrinkToFit(); | 476 m_cuePseudoRules.shrinkToFit(); |
412 m_focusPseudoClassRules.shrinkToFit(); | 477 m_focusPseudoClassRules.shrinkToFit(); |
413 m_universalRules.shrinkToFit(); | 478 m_universalRules.shrinkToFit(); |
414 m_pageRules.shrinkToFit(); | 479 m_pageRules.shrinkToFit(); |
415 } | 480 } |
416 | 481 |
417 } // namespace WebCore | 482 } // namespace WebCore |
OLD | NEW |