Changeset 162394 in webkit
- Timestamp:
- Jan 20, 2014 5:31:37 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r162385 r162394 1 2014-01-20 Benjamin Poulain <benjamin@webkit.org> 2 3 Add a nicer way to iterate over all the attributes of an element 4 https://bugs.webkit.org/show_bug.cgi?id=127266 5 6 Reviewed by Geoffrey Garen. 7 8 When using Element::attributeAt() in a loop, the compiler had to generate two kinds of 9 accessor: 10 -If the element data is unique, the length and data comes from the attribute Vector. 11 -If the element data is shared, the data comes from the tail of elementData itself. 12 13 The choice was done for every access, which caused the assembly to be a little 14 hard to follow. 15 This patch unify the data access by doing everything as a array pointer with offset (getting 16 that data from Vector when necessary). 17 18 To make it easier to do the right thing, a new iterator was added so that range-based loops 19 can replace all the faulty cases. 20 21 * css/SelectorChecker.cpp: 22 (WebCore::anyAttributeMatches): 23 * css/SelectorChecker.h: 24 (WebCore::SelectorChecker::checkExactAttribute): 25 * dom/DatasetDOMStringMap.cpp: 26 (WebCore::DatasetDOMStringMap::getNames): 27 (WebCore::DatasetDOMStringMap::item): 28 (WebCore::DatasetDOMStringMap::contains): 29 * dom/Element.cpp: 30 (WebCore::Element::normalizeAttributes): 31 (WebCore::Element::detachAllAttrNodesFromElement): 32 (WebCore::Element::cloneAttributesFromElement): 33 * dom/Element.h: 34 (WebCore::Element::attributesIterator): 35 * dom/ElementData.cpp: 36 (WebCore::ElementData::isEquivalent): 37 (WebCore::ElementData::findAttributeIndexByNameSlowCase): 38 * dom/ElementData.h: 39 (WebCore::AttributeConstIterator::AttributeConstIterator): 40 (WebCore::AttributeConstIterator::operator*): 41 (WebCore::AttributeConstIterator::operator->): 42 (WebCore::AttributeConstIterator::operator++): 43 (WebCore::AttributeConstIterator::operator==): 44 (WebCore::AttributeConstIterator::operator!=): 45 (WebCore::AttributeIteratorAccessor::AttributeIteratorAccessor): 46 (WebCore::AttributeIteratorAccessor::begin): 47 (WebCore::AttributeIteratorAccessor::end): 48 (WebCore::ElementData::attributesIterator): 49 * dom/Node.cpp: 50 (WebCore::Node::isDefaultNamespace): 51 (WebCore::Node::lookupNamespaceURI): 52 (WebCore::Node::lookupNamespacePrefix): 53 (WebCore::Node::compareDocumentPosition): 54 * dom/StyledElement.cpp: 55 (WebCore::StyledElement::makePresentationAttributeCacheKey): 56 (WebCore::StyledElement::rebuildPresentationAttributeStyle): 57 * editing/MarkupAccumulator.cpp: 58 (WebCore::MarkupAccumulator::appendElement): 59 * editing/markup.cpp: 60 (WebCore::completeURLs): 61 (WebCore::StyledMarkupAccumulator::appendElement): 62 * html/HTMLEmbedElement.cpp: 63 (WebCore::HTMLEmbedElement::parametersForPlugin): 64 * html/HTMLObjectElement.cpp: 65 (WebCore::HTMLObjectElement::parametersForPlugin): 66 * inspector/DOMPatchSupport.cpp: 67 (WebCore::DOMPatchSupport::innerPatchNode): 68 (WebCore::DOMPatchSupport::createDigest): 69 * inspector/InspectorDOMAgent.cpp: 70 (WebCore::InspectorDOMAgent::setAttributesAsText): 71 (WebCore::InspectorDOMAgent::buildArrayForElementAttributes): 72 * inspector/InspectorNodeFinder.cpp: 73 (WebCore::InspectorNodeFinder::matchesElement): 74 * page/PageSerializer.cpp: 75 (WebCore::isCharsetSpecifyingNode): 76 * xml/XPathNodeSet.cpp: 77 (WebCore::XPath::NodeSet::traversalSort): 78 * xml/XPathStep.cpp: 79 (WebCore::XPath::Step::nodesInAxis): 80 * xml/parser/XMLDocumentParserLibxml2.cpp: 81 (WebCore::XMLDocumentParser::XMLDocumentParser): 82 1 83 2014-01-20 Gyuyoung Kim <gyuyoung.kim@samsung.com> 2 84 -
trunk/Source/WebCore/css/SelectorChecker.cpp
r161037 r162394 343 343 { 344 344 ASSERT(element->hasAttributesWithoutUpdate()); 345 for (size_t i = 0, count = element->attributeCount(); i < count; ++i) { 346 const Attribute& attribute = element->attributeAt(i); 347 345 for (const Attribute& attribute : element->attributesIterator()) { 348 346 if (!attribute.matches(selectorAttr.prefix(), element->isHTMLElement() ? selector->attributeCanonicalLocalName() : selectorAttr.localName(), selectorAttr.namespaceURI())) 349 347 continue; -
trunk/Source/WebCore/css/SelectorChecker.h
r156788 r162394 132 132 return false; 133 133 const AtomicString& localName = element->isHTMLElement() ? selector->attributeCanonicalLocalName() : selectorAttributeName.localName(); 134 unsigned size = element->attributeCount(); 135 for (unsigned i = 0; i < size; ++i) { 136 const Attribute& attribute = element->attributeAt(i); 134 for (const Attribute& attribute : element->attributesIterator()) { 137 135 if (attribute.matches(selectorAttributeName.prefix(), localName, selectorAttributeName.namespaceURI()) && (!value || attribute.value().impl() == value)) 138 136 return true; -
trunk/Source/WebCore/dom/DatasetDOMStringMap.cpp
r158569 r162394 139 139 return; 140 140 141 unsigned length = m_element.attributeCount(); 142 for (unsigned i = 0; i < length; i++) { 143 const Attribute& attribute = m_element.attributeAt(i); 141 for (const Attribute& attribute : m_element.attributesIterator()) { 144 142 if (isValidAttributeName(attribute.localName())) 145 143 names.append(convertAttributeNameToPropertyName(attribute.localName())); … … 152 150 return String(); 153 151 154 unsigned length = m_element.attributeCount(); 155 for (unsigned i = 0; i < length; i++) { 156 const Attribute& attribute = m_element.attributeAt(i); 152 for (const Attribute& attribute : m_element.attributesIterator()) { 157 153 if (propertyNameMatchesAttributeName(name, attribute.localName())) 158 154 return attribute.value(); … … 167 163 return false; 168 164 169 unsigned length = m_element.attributeCount(); 170 for (unsigned i = 0; i < length; i++) { 171 const Attribute& attribute = m_element.attributeAt(i); 165 for (const Attribute& attribute : m_element.attributesIterator()) { 172 166 if (propertyNameMatchesAttributeName(name, attribute.localName())) 173 167 return true; -
trunk/Source/WebCore/dom/Element.cpp
r162274 r162394 2315 2315 if (!hasAttributes()) 2316 2316 return; 2317 for ( unsigned i = 0; i < attributeCount(); ++i) {2318 if (RefPtr<Attr> attr = attrIfExists(attribute At(i).name()))2317 for (const Attribute& attribute : attributesIterator()) { 2318 if (RefPtr<Attr> attr = attrIfExists(attribute.name())) 2319 2319 attr->normalize(); 2320 2320 } … … 2917 2917 ASSERT(attrNodeList); 2918 2918 2919 for (unsigned i = 0; i < attributeCount(); ++i) { 2920 const Attribute& attribute = attributeAt(i); 2919 for (const Attribute& attribute : attributesIterator()) { 2921 2920 if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name())) 2922 2921 attrNode->detachFromElementWithValue(attribute.value()); … … 3039 3038 m_elementData = other.m_elementData->makeUniqueCopy(); 3040 3039 3041 unsigned length = m_elementData->length(); 3042 for (unsigned i = 0; i < length; ++i) { 3043 const Attribute& attribute = const_cast<const ElementData*>(m_elementData.get())->attributeAt(i); 3040 for (const Attribute& attribute : attributesIterator()) { 3044 3041 attributeChanged(attribute.name(), attribute.value(), ModifiedByCloning); 3045 3042 } -
trunk/Source/WebCore/dom/Element.h
r162198 r162394 187 187 // Internal methods that assume the existence of attribute storage, one should use hasAttributes() 188 188 // before calling them. 189 AttributeIteratorAccessor attributesIterator() const { return elementData()->attributesIterator(); } 189 190 unsigned attributeCount() const; 190 191 const Attribute& attributeAt(unsigned index) const; -
trunk/Source/WebCore/dom/ElementData.cpp
r162274 r162394 164 164 return isEmpty(); 165 165 166 unsigned len = length(); 167 if (len != other->length()) 166 if (length() != other->length()) 168 167 return false; 169 168 170 for (unsigned i = 0; i < len; i++) { 171 const Attribute& attribute = attributeAt(i); 169 for (const Attribute& attribute : attributesIterator()) { 172 170 const Attribute* otherAttr = other->findAttributeByName(attribute.name()); 173 171 if (!otherAttr || attribute.value() != otherAttr->value()) … … 181 179 { 182 180 // Continue to checking case-insensitively and/or full namespaced names if necessary: 183 for (unsigned i = 0; i < length(); ++i) { 184 const Attribute& attribute = attributeAt(i); 181 const Attribute* attributes = attributeBase(); 182 unsigned length = this->length(); 183 for (unsigned i = 0; i < length; ++i) { 184 const Attribute& attribute = attributes[i]; 185 185 if (!attribute.name().hasPrefix()) { 186 186 if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute.localName())) -
trunk/Source/WebCore/dom/ElementData.h
r162295 r162394 38 38 class UniqueElementData; 39 39 40 class AttributeConstIterator { 41 public: 42 AttributeConstIterator(const Attribute* array, unsigned offset) 43 : m_array(array) 44 , m_offset(offset) 45 { 46 } 47 48 const Attribute& operator*() const { return m_array[m_offset]; } 49 const Attribute* operator->() const { return &m_array[m_offset]; } 50 AttributeConstIterator& operator++() { ++m_offset; return *this; } 51 52 bool operator==(const AttributeConstIterator& other) const { return m_offset == other.m_offset; } 53 bool operator!=(const AttributeConstIterator& other) const { return !(*this == other); } 54 55 private: 56 const Attribute* m_array; 57 unsigned m_offset; 58 }; 59 60 class AttributeIteratorAccessor { 61 public: 62 AttributeIteratorAccessor(const Attribute* array, unsigned size) 63 : m_array(array) 64 , m_size(size) 65 { 66 } 67 68 AttributeConstIterator begin() const { return AttributeConstIterator(m_array, 0); } 69 AttributeConstIterator end() const { return AttributeConstIterator(m_array, m_size); } 70 private: 71 const Attribute* m_array; 72 unsigned m_size; 73 }; 74 40 75 class ElementData : public RefCounted<ElementData> { 41 76 WTF_MAKE_FAST_ALLOCATED; … … 62 97 bool isEmpty() const { return !length(); } 63 98 99 AttributeIteratorAccessor attributesIterator() const; 64 100 const Attribute& attributeAt(unsigned index) const; 65 101 const Attribute* findAttributeByName(const QualifiedName&) const; … … 209 245 } 210 246 247 inline AttributeIteratorAccessor ElementData::attributesIterator() const 248 { 249 if (isUnique()) { 250 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueElementData*>(this)->m_attributeVector; 251 return AttributeIteratorAccessor(attributeVector.data(), attributeVector.size()); 252 } 253 return AttributeIteratorAccessor(static_cast<const ShareableElementData*>(this)->m_attributeArray, arraySize()); 254 } 255 211 256 inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const 212 257 { -
trunk/Source/WebCore/dom/Node.cpp
r162264 r162394 1134 1134 1135 1135 if (elem->hasAttributes()) { 1136 for (unsigned i = 0; i < elem->attributeCount(); i++) { 1137 const Attribute& attribute = elem->attributeAt(i); 1138 1136 for (const Attribute& attribute : elem->attributesIterator()) { 1139 1137 if (attribute.localName() == xmlnsAtom) 1140 1138 return attribute.value() == namespaceURI; … … 1218 1216 1219 1217 if (elem->hasAttributes()) { 1220 for (unsigned i = 0; i < elem->attributeCount(); i++) { 1221 const Attribute& attribute = elem->attributeAt(i); 1218 for (const Attribute& attribute : elem->attributesIterator()) { 1222 1219 1223 1220 if (attribute.prefix() == xmlnsAtom && attribute.localName() == prefix) { … … 1274 1271 const Element* thisElement = toElement(this); 1275 1272 if (thisElement->hasAttributes()) { 1276 for (unsigned i = 0; i < thisElement->attributeCount(); i++) { 1277 const Attribute& attribute = thisElement->attributeAt(i); 1278 1273 for (const Attribute& attribute : thisElement->attributesIterator()) { 1279 1274 if (attribute.prefix() == xmlnsAtom && attribute.value() == _namespaceURI 1280 1275 && originalElement->lookupNamespaceURI(attribute.localName()) == _namespaceURI) … … 1427 1422 Element* owner1 = attr1->ownerElement(); 1428 1423 owner1->synchronizeAllAttributes(); 1429 unsigned length = owner1->attributeCount(); 1430 for (unsigned i = 0; i < length; ++i) { 1431 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an 1424 for (const Attribute& attribute : owner1->attributesIterator()) { 1425 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an 1432 1426 // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of 1433 1427 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example, 1434 1428 // when comparing two attributes of the same element, and inserting or removing additional attributes might change 1435 1429 // the order between existing attributes. 1436 const Attribute& attribute = owner1->attributeAt(i);1437 1430 if (attr1->qualifiedName() == attribute.name()) 1438 1431 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING; -
trunk/Source/WebCore/dom/StyledElement.cpp
r162274 r162394 286 286 if (hasTagName(inputTag)) 287 287 return; 288 unsigned size = attributeCount(); 289 for (unsigned i = 0; i < size; ++i) { 290 const Attribute& attribute = attributeAt(i); 288 for (const Attribute& attribute : attributesIterator()) { 291 289 if (!isPresentationAttribute(attribute.name())) 292 290 continue; … … 336 334 } else { 337 335 style = MutableStyleProperties::create(isSVGElement() ? SVGAttributeMode : CSSQuirksMode); 338 unsigned size = attributeCount(); 339 for (unsigned i = 0; i < size; ++i) { 340 const Attribute& attribute = attributeAt(i); 336 for (const Attribute& attribute : attributesIterator()) 341 337 collectStyleForPresentationAttribute(attribute.name(), attribute.value(), static_cast<MutableStyleProperties&>(*style)); 342 }343 338 } 344 339 -
trunk/Source/WebCore/editing/MarkupAccumulator.cpp
r159326 r162394 427 427 428 428 if (element.hasAttributes()) { 429 unsigned length = element.attributeCount(); 430 for (unsigned int i = 0; i < length; i++) 431 appendAttribute(result, element, element.attributeAt(i), namespaces); 429 for (const Attribute& attribute : element.attributesIterator()) 430 appendAttribute(result, element, attribute, namespaces); 432 431 } 433 432 -
trunk/Source/WebCore/editing/markup.cpp
r162158 r162394 103 103 if (!element.hasAttributes()) 104 104 continue; 105 unsigned length = element.attributeCount(); 106 for (unsigned i = 0; i < length; i++) { 107 const Attribute& attribute = element.attributeAt(i); 105 for (const Attribute& attribute : element.attributesIterator()) { 108 106 if (element.isURLAttribute(attribute) && !attribute.value().isEmpty()) 109 107 changes.append(AttributeChange(&element, attribute.name(), URL(parsedBaseURL, attribute.value()).string())); … … 291 289 appendOpenTag(out, element, 0); 292 290 293 const unsigned length = element.hasAttributes() ? element.attributeCount() : 0;294 291 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline); 295 292 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element); 296 for (unsigned i = 0; i < length; ++i) { 297 const Attribute& attribute = element.attributeAt(i); 298 // We'll handle the style attribute separately, below. 299 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) 300 continue; 301 appendAttribute(out, element, attribute, 0); 293 if (element.hasAttributes()) { 294 for (const Attribute& attribute : element.attributesIterator()) { 295 // We'll handle the style attribute separately, below. 296 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) 297 continue; 298 appendAttribute(out, element, attribute, 0); 299 } 302 300 } 303 301 -
trunk/Source/WebCore/html/HTMLEmbedElement.cpp
r160908 r162394 121 121 return; 122 122 123 for (unsigned i = 0; i < attributeCount(); ++i) { 124 const Attribute& attribute = attributeAt(i); 123 for (const Attribute& attribute : attributesIterator()) { 125 124 paramNames.append(attribute.localName().string()); 126 125 paramValues.append(attribute.value().string()); -
trunk/Source/WebCore/html/HTMLObjectElement.cpp
r161484 r162394 203 203 // Turn the attributes of the <object> element into arrays, but don't override <param> values. 204 204 if (hasAttributes()) { 205 for (unsigned i = 0; i < attributeCount(); ++i) { 206 const Attribute& attribute = attributeAt(i); 205 for (const Attribute& attribute : attributesIterator()) { 207 206 const AtomicString& name = attribute.name().localName(); 208 207 if (!uniqueParamNames.contains(name.impl())) { -
trunk/Source/WebCore/inspector/DOMPatchSupport.cpp
r162374 r162394 198 198 // FIXME: Create a function in Element for copying properties. cloneDataFromElement() is close but not enough for this case. 199 199 if (newElement->hasAttributesWithoutUpdate()) { 200 size_t numAttrs = newElement->attributeCount(); 201 for (size_t i = 0; i < numAttrs; ++i) { 202 const Attribute& attribute = newElement->attributeAt(i); 200 for (const Attribute& attribute : newElement->attributesIterator()) { 203 201 if (!m_domEditor->setAttribute(oldElement, attribute.name().localName(), attribute.value(), ec)) 204 202 return false; … … 434 432 435 433 if (element->hasAttributesWithoutUpdate()) { 436 size_t numAttrs = element->attributeCount();437 434 SHA1 attrsSHA1; 438 for (size_t i = 0; i < numAttrs; ++i) { 439 const Attribute& attribute = element->attributeAt(i); 435 for (const Attribute& attribute : element->attributesIterator()) { 440 436 addStringToSHA1(attrsSHA1, attribute.name().toString()); 441 437 addStringToSHA1(attrsSHA1, attribute.value()); -
trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp
r161768 r162394 680 680 681 681 bool foundOriginalAttribute = false; 682 unsigned numAttrs = childElement->attributeCount(); 683 for (unsigned i = 0; i < numAttrs; ++i) { 682 for (const Attribute& attribute : childElement->attributesIterator()) { 684 683 // Add attribute pair 685 const Attribute& attribute = childElement->attributeAt(i);686 684 foundOriginalAttribute = foundOriginalAttribute || (name && attribute.name().toString() == *name); 687 685 if (!m_domEditor->setAttribute(element, attribute.name().toString(), attribute.value(), errorString)) … … 1323 1321 if (!element->hasAttributes()) 1324 1322 return attributesValue.release(); 1325 unsigned numAttrs = element->attributeCount(); 1326 for (unsigned i = 0; i < numAttrs; ++i) { 1323 for (const Attribute& attribute : element->attributesIterator()) { 1327 1324 // Add attribute pair 1328 const Attribute& attribute = element->attributeAt(i);1329 1325 attributesValue->addItem(attribute.name().toString()); 1330 1326 attributesValue->addItem(attribute.value()); -
trunk/Source/WebCore/inspector/InspectorNodeFinder.cpp
r162374 r162394 123 123 return false; 124 124 125 unsigned numAttrs = element.attributeCount(); 126 for (unsigned i = 0; i < numAttrs; ++i) { 127 if (matchesAttribute(element.attributeAt(i))) 125 for (const Attribute& attribute : element.attributesIterator()) { 126 if (matchesAttribute(attribute)) 128 127 return true; 129 128 } -
trunk/Source/WebCore/page/PageSerializer.cpp
r162158 r162394 75 75 HTMLMetaCharsetParser::AttributeList attributes; 76 76 if (element.hasAttributes()) { 77 for (unsigned i = 0; i < element.attributeCount(); ++i) { 78 const Attribute& attribute = element.attributeAt(i); 77 for (const Attribute& attribute : element.attributesIterator()) { 79 78 // FIXME: We should deal appropriately with the attribute if they have a namespace. 80 79 attributes.append(std::make_pair(attribute.name().toString(), attribute.value().string())); -
trunk/Source/WebCore/xml/XPathNodeSet.cpp
r161425 r162394 219 219 continue; 220 220 221 unsigned attributeCount = element->attributeCount(); 222 for (unsigned i = 0; i < attributeCount; ++i) { 223 RefPtr<Attr> attr = element->attrIfExists(element->attributeAt(i).name()); 221 for (const Attribute& attribute : element->attributesIterator()) { 222 RefPtr<Attr> attr = element->attrIfExists(attribute.name()); 224 223 if (attr && nodes.contains(attr.get())) 225 224 sortedNodes.append(attr); -
trunk/Source/WebCore/xml/XPathStep.cpp
r157205 r162394 362 362 return; 363 363 364 for ( unsigned i = 0; i < contextElement.attributeCount(); ++i) {365 RefPtr<Attr> attr = contextElement.ensureAttr( contextElement.attributeAt(i).name());364 for (const Attribute& attribute : contextElement.attributesIterator()) { 365 RefPtr<Attr> attr = contextElement.ensureAttr(attribute.name()); 366 366 if (nodeMatches(*attr, AttributeAxis, m_nodeTest)) 367 367 nodes.append(attr.release()); -
trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp
r162269 r162394 629 629 Element* element = elemStack.last(); 630 630 if (element->hasAttributes()) { 631 for (unsigned i = 0; i < element->attributeCount(); i++) { 632 const Attribute& attribute = element->attributeAt(i); 631 for (const Attribute& attribute : element->attributesIterator()) { 633 632 if (attribute.localName() == xmlnsAtom) 634 633 m_defaultNamespaceURI = attribute.value();
Note: See TracChangeset
for help on using the changeset viewer.