Changeset 110172 in webkit
- Timestamp:
- Mar 8, 2012 9:42:28 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r110171 r110172 1 2012-03-08 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 Make elements with attributes smaller by eliminating the m_element back pointer in NamedNodeMap 4 https://bugs.webkit.org/show_bug.cgi?id=75069 5 6 Reviewed by Ryosuke Niwa. 7 8 NamedNodeMap is an exposed DOM representation of an element's attribute storage. As part of 9 its implementation it keeps a pointer to its associated Element plus all the attribute 10 storage. 11 12 This commit separate the two things: NamedNodeMap is now a wrapper to Element, containing 13 only the pointer, and the attribute storage is now owned by Element directly. Since usage 14 of NamedNodeMap is not very common, it can be stored in ElementRareData. As a result, most 15 elements with attributes now don't need to allocate memory for that extra pointer in 16 NamedNodeMap. 17 18 One consequence of this implementation is that now we explicitly don't support 19 DocumentType.notations and DocumentType.entities. They weren't supported before, a 20 NamedNodeMap was never created for those attributes -- and some NamedNodeMap functions 21 wouldn't work correctly without an associated Element. 22 23 NamedNodeMap itself was cleaned up, as well as unnecessary references to it removed in the 24 code and comments. 25 26 No new tests and should not change results for existing tests. 27 28 * dom/Attribute.h: 29 (WebCore): 30 * dom/DocumentType.h: 31 (DocumentType): Point out that we don't support does attributes yet. 32 * dom/Element.cpp: 33 (WebCore::Element::~Element): Detaching the NamedNodeMap is no longer necessary because it 34 will be destroyed. We still detach the potential Attrs inside our Attributes by using 35 clearAttributes(). 36 (WebCore::Element::attributes): Looks in ElementRareData now. Note we ensure the creation 37 of the attribute storage. 38 (WebCore): 39 (WebCore::Element::getAttribute): 40 (WebCore::Element::setAttributeInternal): 41 (WebCore::Element::parserSetAttributes): 42 (WebCore::Element::hasAttributes): 43 (WebCore::Element::createAttributeData): 44 (WebCore::Element::insertedIntoDocument): 45 (WebCore::Element::removedFromDocument): 46 (WebCore::Element::getURLAttribute): 47 (WebCore::Element::getNonEmptyURLAttribute): 48 (WebCore::Element::hasNamedNodeMap): Helper function for Node::dumpStatistics(). 49 * dom/Element.h: 50 (Element): 51 (WebCore::Element::attributeData): 52 (WebCore::Element::ensureAttributeData): 53 (WebCore::Element::fastHasAttribute): 54 (WebCore::Element::fastGetAttribute): 55 (WebCore::Element::hasAttributesWithoutUpdate): 56 (WebCore::Element::idForStyleResolution): 57 (WebCore::Element::attributeCount): 58 (WebCore::Element::attributeItem): 59 (WebCore::Element::getAttributeItem): 60 * dom/ElementAttributeData.h: 61 (WebCore::ElementAttributeData::create): 62 (ElementAttributeData): 63 * dom/ElementRareData.h: 64 (ElementRareData): 65 * dom/NamedNodeMap.cpp: Rewriting now that m_attributeData is not a member, using m_element 66 methods when possible. 67 (WebCore::NamedNodeMap::ref): 68 (WebCore::NamedNodeMap::deref): 69 (WebCore::NamedNodeMap::getNamedItem): 70 (WebCore::NamedNodeMap::getNamedItemNS): 71 (WebCore::NamedNodeMap::removeNamedItem): 72 (WebCore::NamedNodeMap::removeNamedItemNS): 73 (WebCore::NamedNodeMap::setNamedItem): 74 (WebCore::NamedNodeMap::item): 75 (WebCore::NamedNodeMap::length): 76 * dom/NamedNodeMap.h: 77 (WebCore): 78 (WebCore::NamedNodeMap::create): 79 (NamedNodeMap): 80 (WebCore::NamedNodeMap::NamedNodeMap): Instead of asserting m_element in every function, we 81 now assert only in the constructor. 82 * dom/Node.cpp: 83 (WebCore::Node::dumpStatistics): Add a counter for elements with rare data, this allows us 84 compare more clearly the impact of moving NamedNodeMap there. 85 (WebCore::Node::isEqualNode): Remove use of mapsEquivalent(). It was dead code, because 86 both entities and notations were always NULL. 87 (WebCore::Node::compareDocumentPosition): 88 * inspector/DOMPatchSupport.h: 89 (WebCore): 90 * svg/SVGElement.cpp: 91 (WebCore::SVGElement::attributeChanged): 92 1 93 2012-03-08 Robin Cao <robin.cao@torchmobile.com.cn> 2 94 -
trunk/Source/WebCore/dom/Attribute.h
r106769 r110172 32 32 class Attr; 33 33 class Element; 34 class NamedNodeMap;35 34 36 35 // This has no counterpart in DOM. -
trunk/Source/WebCore/dom/DocumentType.h
r104130 r110172 38 38 } 39 39 40 // FIXME: We never fill m_entities and m_notations. Current implementation of NamedNodeMap doesn't work without an associated Element yet. 40 41 NamedNodeMap* entities() const { return m_entities.get(); } 41 42 NamedNodeMap* notations() const { return m_notations.get(); } -
trunk/Source/WebCore/dom/Element.cpp
r110119 r110172 53 53 #include "MutationObserverInterestGroup.h" 54 54 #include "MutationRecord.h" 55 #include "NamedNodeMap.h" 55 56 #include "NodeList.h" 56 57 #include "NodeRenderStyle.h" … … 126 127 if (shadowTree()) 127 128 rareData()->m_shadowTree.clear(); 128 if (m_attribute Map)129 m_attribute Map->detachFromElement();129 if (m_attributeData) 130 m_attributeData->clearAttributes(); 130 131 } 131 132 … … 200 201 } 201 202 203 NamedNodeMap* Element::attributes() const 204 { 205 ensureUpdatedAttributeData(); 206 ElementRareData* rareData = const_cast<Element*>(this)->ensureRareData(); 207 if (NamedNodeMap* attributeMap = rareData->m_attributeMap.get()) 208 return attributeMap; 209 210 rareData->m_attributeMap = NamedNodeMap::create(const_cast<Element*>(this)); 211 return rareData->m_attributeMap.get(); 212 } 213 202 214 Node::NodeType Element::nodeType() const 203 215 { … … 220 232 #endif 221 233 222 if (m_attribute Map) {234 if (m_attributeData) { 223 235 if (Attribute* attribute = getAttributeItem(name)) 224 236 return attribute->value(); … … 597 609 #endif 598 610 599 if (m_attribute Map) {600 if (Attribute* attribute = m_attribute Map->attributeData()->getAttributeItem(name, ignoreCase))611 if (m_attributeData) { 612 if (Attribute* attribute = m_attributeData->getAttributeItem(name, ignoreCase)) 601 613 return attribute->value(); 602 614 } … … 631 643 inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value, bool notifyChanged) 632 644 { 633 ElementAttributeData* attributeData = &m_attributeMap->m_attributeData; 634 Attribute* old = index != notFound ? attributeData->attributeItem(index) : 0; 645 Attribute* old = index != notFound ? m_attributeData->attributeItem(index) : 0; 635 646 if (value.isNull()) { 636 647 if (old) 637 attributeData->removeAttribute(index, this);648 m_attributeData->removeAttribute(index, this); 638 649 return; 639 650 } 640 651 641 652 if (!old) { 642 attributeData->addAttribute(Attribute::create(name, value), this);653 m_attributeData->addAttribute(Attribute::create(name, value), this); 643 654 return; 644 655 } … … 734 745 document()->incDOMTreeVersion(); 735 746 736 ASSERT(!m_attribute Map);747 ASSERT(!m_attributeData); 737 748 738 749 if (!attributeVector) 739 750 return; 740 751 741 m_attributeMap = NamedNodeMap::create(this); 742 ElementAttributeData* attributeData = m_attributeMap->attributeData(); 743 attributeData->m_attributes.swap(*attributeVector); 744 745 m_attributeMap->m_element = this; 752 createAttributeData(); 753 m_attributeData->m_attributes.swap(*attributeVector); 754 746 755 // If the element is created as result of a paste or drag-n-drop operation 747 756 // we want to remove all the script and event handlers. 748 757 if (scriptingPermission == FragmentScriptingNotAllowed) { 749 758 unsigned i = 0; 750 while (i < m_attribute Map->length()) {751 const QualifiedName& attributeName = attributeData->m_attributes[i]->name();759 while (i < m_attributeData->length()) { 760 const QualifiedName& attributeName = m_attributeData->m_attributes[i]->name(); 752 761 if (isEventHandlerAttribute(attributeName)) { 753 attributeData->m_attributes.remove(i);762 m_attributeData->m_attributes.remove(i); 754 763 continue; 755 764 } 756 765 757 if (isAttributeToRemove(attributeName, attributeData->m_attributes[i]->value()))758 attributeData->m_attributes[i]->setValue(nullAtom);766 if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i]->value())) 767 m_attributeData->m_attributes[i]->setValue(nullAtom); 759 768 i++; 760 769 } … … 762 771 763 772 // Store the set of attributes that changed on the stack in case 764 // attributeChanged mutates m_attribute Map.773 // attributeChanged mutates m_attributeData. 765 774 Vector<RefPtr<Attribute> > attributes; 766 attributeData->copyAttributesToVector(attributes);775 m_attributeData->copyAttributesToVector(attributes); 767 776 for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter) 768 777 attributeChanged(iter->get()); … … 772 781 { 773 782 updateInvalidAttributes(); 774 return m_attribute Map && m_attributeMap->length();783 return m_attributeData && m_attributeData->length(); 775 784 } 776 785 … … 824 833 } 825 834 826 void Element::createAttribute Map() const827 { 828 m_attribute Map = NamedNodeMap::create(const_cast<Element*>(this));835 void Element::createAttributeData() const 836 { 837 m_attributeData = ElementAttributeData::create(); 829 838 } 830 839 … … 879 888 tree->insertedIntoDocument(); 880 889 881 if (m_attribute Map) {890 if (m_attributeData) { 882 891 if (hasID()) { 883 892 Attribute* idItem = getAttributeItem(document()->idAttributeName()); … … 895 904 void Element::removedFromDocument() 896 905 { 897 if (m_attribute Map) {906 if (m_attributeData) { 898 907 if (hasID()) { 899 908 Attribute* idItem = getAttributeItem(document()->idAttributeName()); … … 1790 1799 { 1791 1800 #if !ASSERT_DISABLED 1792 if (m_attribute Map) {1801 if (m_attributeData) { 1793 1802 if (Attribute* attribute = getAttributeItem(name)) 1794 1803 ASSERT(isURLAttribute(attribute)); … … 1801 1810 { 1802 1811 #if !ASSERT_DISABLED 1803 if (m_attribute Map) {1812 if (m_attributeData) { 1804 1813 if (Attribute* attribute = getAttributeItem(name)) 1805 1814 ASSERT(isURLAttribute(attribute)); … … 1969 1978 #endif 1970 1979 1980 #ifdef DUMP_NODE_STATISTICS 1981 bool Element::hasNamedNodeMap() const 1982 { 1983 return hasRareData() && rareData()->m_attributeMap; 1984 } 1985 #endif 1986 1971 1987 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue) 1972 1988 { -
trunk/Source/WebCore/dom/Element.h
r110086 r110172 28 28 #include "CollectionType.h" 29 29 #include "Document.h" 30 #include "ElementAttributeData.h" 30 31 #include "FragmentScriptingPermission.h" 31 32 #include "HTMLNames.h" 32 #include "NamedNodeMap.h"33 33 #include "ScrollTypes.h" 34 34 … … 131 131 #endif 132 132 133 #ifdef DUMP_NODE_STATISTICS 134 bool hasNamedNodeMap() const; 135 #endif 133 136 bool hasAttributes() const; 134 137 // This variant will not update the potentially invalid attributes. To be used when not interested … … 230 233 NamedNodeMap* attributes() const; 231 234 232 NamedNodeMap* updatedAttributes() const;233 234 235 // This method is called whenever an attribute is added, changed or removed. 235 236 virtual void attributeChanged(Attribute*); … … 238 239 void parserSetAttributes(PassOwnPtr<AttributeVector>, FragmentScriptingPermission); 239 240 240 ElementAttributeData* attributeData() const { return m_attribute Map ? m_attributeMap->attributeData() : 0; }241 ElementAttributeData* attributeData() const { return m_attributeData.get(); } 241 242 ElementAttributeData* ensureAttributeData() const; 242 243 ElementAttributeData* updatedAttributeData() const; … … 437 438 bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle); 438 439 439 void createAttribute Map() const;440 void createAttributeData() const; 440 441 441 442 virtual void updateStyleAttribute() const { } … … 469 470 470 471 private: 471 mutable OwnPtr< NamedNodeMap> m_attributeMap;472 mutable OwnPtr<ElementAttributeData> m_attributeData; 472 473 }; 473 474 … … 529 530 } 530 531 531 inline NamedNodeMap* Element::attributes() const532 {533 updateInvalidAttributes();534 if (!m_attributeMap)535 createAttributeMap();536 return m_attributeMap.get();537 }538 539 inline NamedNodeMap* Element::updatedAttributes() const540 {541 updateInvalidAttributes();542 return m_attributeMap.get();543 }544 545 532 inline ElementAttributeData* Element::ensureAttributeData() const 546 533 { 547 if (!m_attribute Map)548 createAttribute Map();549 return m_attribute Map->attributeData();534 if (!m_attributeData) 535 createAttributeData(); 536 return m_attributeData.get(); 550 537 } 551 538 … … 607 594 { 608 595 ASSERT(fastAttributeLookupAllowed(name)); 609 return m_attribute Map&& getAttributeItem(name);596 return m_attributeData && getAttributeItem(name); 610 597 } 611 598 … … 613 600 { 614 601 ASSERT(fastAttributeLookupAllowed(name)); 615 if (m_attribute Map) {602 if (m_attributeData) { 616 603 if (Attribute* attribute = getAttributeItem(name)) 617 604 return attribute->value(); … … 622 609 inline bool Element::hasAttributesWithoutUpdate() const 623 610 { 624 return m_attribute Map && !m_attributeMap->attributeData()->isEmpty();611 return m_attributeData && !m_attributeData->isEmpty(); 625 612 } 626 613 … … 628 615 { 629 616 ASSERT(hasID()); 630 return attributeData()->idForStyleResolution();617 return m_attributeData->idForStyleResolution(); 631 618 } 632 619 … … 657 644 inline size_t Element::attributeCount() const 658 645 { 659 ASSERT(m_attribute Map);660 return m_attribute Map->length();646 ASSERT(m_attributeData); 647 return m_attributeData->length(); 661 648 } 662 649 663 650 inline Attribute* Element::attributeItem(unsigned index) const 664 651 { 665 ASSERT(m_attribute Map);666 return m_attribute Map->attributeData()->attributeItem(index);652 ASSERT(m_attributeData); 653 return m_attributeData->attributeItem(index); 667 654 } 668 655 669 656 inline Attribute* Element::getAttributeItem(const QualifiedName& name) const 670 657 { 671 ASSERT(m_attribute Map);672 return m_attribute Map->attributeData()->getAttributeItem(name);658 ASSERT(m_attributeData); 659 return m_attributeData->getAttributeItem(name); 673 660 } 674 661 -
trunk/Source/WebCore/dom/ElementAttributeData.h
r110119 r110172 83 83 class ElementAttributeData { 84 84 public: 85 static PassOwnPtr<ElementAttributeData> create() 86 { 87 return adoptPtr(new ElementAttributeData); 88 } 89 85 90 ~ElementAttributeData(); 86 91 … … 109 114 Attribute* getAttributeItem(const QualifiedName& name) const { return m_attributes.getAttributeItem(name); } 110 115 size_t getAttributeItemIndex(const QualifiedName& name) const { return m_attributes.getAttributeItemIndex(name); } 116 size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const; 111 117 112 118 // These functions do no error checking. … … 123 129 private: 124 130 friend class Element; 125 friend class NamedNodeMap;126 131 127 132 ElementAttributeData() … … 132 137 void copyAttributesToVector(Vector<RefPtr<Attribute> >&); 133 138 Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const; 134 size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const;135 139 size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const; 136 140 void setAttributes(const ElementAttributeData& other, Element*); -
trunk/Source/WebCore/dom/ElementRareData.h
r109084 r110172 27 27 #include "Element.h" 28 28 #include "HTMLCollection.h" 29 #include "NamedNodeMap.h" 29 30 #include "NodeRareData.h" 30 31 #include "ShadowTree.h" … … 70 71 OwnPtr<ClassList> m_classList; 71 72 OwnPtr<ShadowTree> m_shadowTree; 73 OwnPtr<NamedNodeMap> m_attributeMap; 72 74 73 75 bool m_styleAffectedByEmpty; -
trunk/Source/WebCore/dom/NamedNodeMap.cpp
r110119 r110172 43 43 void NamedNodeMap::ref() 44 44 { 45 ASSERT(m_element);46 45 m_element->ref(); 47 46 } … … 49 48 void NamedNodeMap::deref() 50 49 { 51 ASSERT(m_element);52 50 m_element->deref(); 53 51 } … … 55 53 PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const 56 54 { 57 return m_ attributeData.getAttributeNode(name, shouldIgnoreAttributeCase(m_element), m_element);55 return m_element->attributeData()->getAttributeNode(name, shouldIgnoreAttributeCase(m_element), m_element); 58 56 } 59 57 60 58 PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const String& localName) const 61 59 { 62 return m_ attributeData.getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), m_element);60 return m_element->attributeData()->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), m_element); 63 61 } 64 62 65 63 PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec) 66 64 { 67 ASSERT(m_element);65 ElementAttributeData* attributeData = m_element->attributeData(); 68 66 69 size_t index = m_attributeData.getAttributeItemIndex(name, shouldIgnoreAttributeCase(m_element));67 size_t index = attributeData->getAttributeItemIndex(name, shouldIgnoreAttributeCase(m_element)); 70 68 if (index == notFound) { 71 69 ec = NOT_FOUND_ERR; … … 73 71 } 74 72 75 return m_attributeData.takeAttribute(index, m_element);73 return attributeData->takeAttribute(index, m_element); 76 74 } 77 75 78 76 PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec) 79 77 { 80 return removeNamedItem(QualifiedName(nullAtom, localName, namespaceURI), ec); 78 ElementAttributeData* attributeData = m_element->attributeData(); 79 80 size_t index = attributeData->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)); 81 if (index == notFound) { 82 ec = NOT_FOUND_ERR; 83 return 0; 84 } 85 86 return attributeData->takeAttribute(index, m_element); 81 87 } 82 88 83 89 PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec) 84 90 { 85 if (! m_element || !node) {91 if (!node) { 86 92 ec = NOT_FOUND_ERR; 87 93 return 0; … … 102 108 } 103 109 104 PassRefPtr<Node> NamedNodeMap::removeNamedItem(const QualifiedName& name, ExceptionCode& ec)105 {106 ASSERT(m_element);107 108 size_t index = m_attributeData.getAttributeItemIndex(name);109 if (index == notFound) {110 ec = NOT_FOUND_ERR;111 return 0;112 }113 114 return m_attributeData.takeAttribute(index, m_element);115 }116 117 110 PassRefPtr<Node> NamedNodeMap::item(unsigned index) const 118 111 { 119 112 if (index >= length()) 120 113 return 0; 121 122 return m_attributeData.m_attributes[index]->createAttrIfNeeded(m_element); 114 return m_element->attributeItem(index)->createAttrIfNeeded(m_element); 123 115 } 124 116 125 void NamedNodeMap::detachFromElement() 117 size_t NamedNodeMap::length() const 126 118 { 127 // This can't happen if the holder of the map is JavaScript, because we mark the 128 // element if the map is alive. So it has no impact on web page behavior. Because 129 // of that, we can simply clear all the attributes to avoid accessing stale 130 // pointers to do things like create Attr objects. 131 m_element = 0; 132 m_attributeData.clearAttributes(); 133 } 134 135 bool NamedNodeMap::mapsEquivalent(const NamedNodeMap* otherMap) const 136 { 137 if (!otherMap) 138 return m_attributeData.isEmpty(); 139 return m_attributeData.isEquivalent(otherMap->attributeData()); 119 return m_element->attributeCount(); 140 120 } 141 121 -
trunk/Source/WebCore/dom/NamedNodeMap.h
r110119 r110172 26 26 #define NamedNodeMap_h 27 27 28 #include "ElementAttributeData.h" 29 #include "SpaceSplitString.h" 28 #include <wtf/PassOwnPtr.h> 29 #include <wtf/PassRefPtr.h> 30 #include <wtf/text/WTFString.h> 30 31 31 32 namespace WebCore { 32 33 33 34 class Node; 35 class Element; 34 36 35 37 typedef int ExceptionCode; … … 38 40 friend class Element; 39 41 public: 40 static PassOwnPtr<NamedNodeMap> create(Element* element = 0)42 static PassOwnPtr<NamedNodeMap> create(Element* element) 41 43 { 42 44 return adoptPtr(new NamedNodeMap(element)); … … 54 56 PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&); 55 57 56 PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);57 58 PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&); 58 59 PassRefPtr<Node> setNamedItemNS(Node*, ExceptionCode&); 59 60 60 61 PassRefPtr<Node> item(unsigned index) const; 61 size_t length() const { return m_attributeData.length(); } 62 63 bool mapsEquivalent(const NamedNodeMap* otherMap) const; 64 65 // These functions do no error checking. 66 void addAttribute(PassRefPtr<Attribute> attribute) { m_attributeData.addAttribute(attribute, m_element); } 62 size_t length() const; 67 63 68 64 Element* element() const { return m_element; } 69 70 ElementAttributeData* attributeData() { return &m_attributeData; }71 const ElementAttributeData* attributeData() const { return &m_attributeData; }72 65 73 66 private: … … 75 68 : m_element(element) 76 69 { 70 // Only supports NamedNodeMaps with Element associated, DocumentType.entities and DocumentType.notations are not supported yet. 71 ASSERT(m_element); 77 72 } 78 79 void detachFromElement();80 Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const { return m_attributeData.getAttributeItem(name, shouldIgnoreAttributeCase); }81 82 // FIXME: NamedNodeMap is being broken up into two classes, one containing data83 // for elements with attributes, and one for exposure to the DOM.84 // See <http://webkit.org/b/75069> for more information.85 ElementAttributeData m_attributeData;86 73 87 74 Element* m_element; -
trunk/Source/WebCore/dom/Node.cpp
r110128 r110172 161 161 size_t attributesWithAttr = 0; 162 162 size_t elementsWithAttributeStorage = 0; 163 size_t elementsWithRareData = 0; 163 164 size_t elementsWithNamedNodeMap = 0; 164 165 … … 166 167 Node* node = *it; 167 168 168 if (node->hasRareData()) 169 if (node->hasRareData()) { 169 170 ++nodesWithRareData; 171 if (node->isElementNode()) { 172 ++elementsWithRareData; 173 if (toElement(node)->hasNamedNodeMap()) 174 ++elementsWithNamedNodeMap; 175 } 176 } 170 177 171 178 switch (node->nodeType()) { … … 182 189 attributes += attributeData->length(); 183 190 ++elementsWithAttributeStorage; 184 // FIXME: This will change once attribute storage goes out of NamedNodeMap.185 ++elementsWithNamedNodeMap;186 191 for (unsigned i = 0; i < attributeData->length(); ++i) { 187 192 Attribute* attr = attributeData->attributeItem(i); … … 273 278 printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr); 274 279 printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementAttributeData)); 280 printf(" Number of Elements with RareData: %zu\n", elementsWithRareData); 275 281 printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap)); 276 282 #endif … … 1804 1810 return false; 1805 1811 1806 NamedNodeMap* entities = documentTypeThis->entities(); 1807 NamedNodeMap* otherEntities = documentTypeOther->entities(); 1808 if (!entities && otherEntities) 1809 return false; 1810 if (entities && !entities->mapsEquivalent(otherEntities)) 1811 return false; 1812 1813 NamedNodeMap* notations = documentTypeThis->notations(); 1814 NamedNodeMap* otherNotations = documentTypeOther->notations(); 1815 if (!notations && otherNotations) 1816 return false; 1817 if (notations && !notations->mapsEquivalent(otherNotations)) 1818 return false; 1812 // FIXME: We don't compare entities or notations because currently both are always empty. 1819 1813 } 1820 1814 … … 2115 2109 // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first. 2116 2110 Element* owner1 = attr1->ownerElement(); 2117 owner1->updatedAttribute s(); // Force update invalid attributes.2111 owner1->updatedAttributeData(); // Force update invalid attributes. 2118 2112 unsigned length = owner1->attributeCount(); 2119 2113 for (unsigned i = 0; i < length; ++i) { -
trunk/Source/WebCore/inspector/DOMPatchSupport.h
r107399 r110172 45 45 class DOMEditor; 46 46 class Document; 47 class NamedNodeMap;48 47 class Node; 49 48 -
trunk/Source/WebCore/svg/SVGElement.cpp
r109342 r110172 416 416 // When an animated SVG property changes through SVG DOM, svgAttributeChanged() is called, not attributeChanged(). 417 417 // Next time someone tries to access the XML attributes, the synchronization code starts. During that synchronization 418 // SVGAnimatedPropertySynchronizer may call NamedNodeMap::removeAttribute(), which in turn calls attributeChanged().418 // SVGAnimatedPropertySynchronizer may call ElementAttributeData::removeAttribute(), which in turn calls attributeChanged(). 419 419 // At this point we're not allowed to call svgAttributeChanged() again - it may lead to extra work being done, or crashes 420 420 // see bug https://bugs.webkit.org/show_bug.cgi?id=40994. -
trunk/Source/WebKit/chromium/ChangeLog
r110130 r110172 1 2012-03-08 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 Make elements with attributes smaller by eliminating the m_element back pointer in NamedNodeMap 4 https://bugs.webkit.org/show_bug.cgi?id=75069 5 6 Reviewed by Ryosuke Niwa. 7 8 * src/WebElement.cpp: Include NamedNodeMap.h since Element.h doesn't include it anymore. 9 1 10 2012-03-07 Kent Tamura <tkent@chromium.org> 2 11 -
trunk/Source/WebKit/chromium/src/WebElement.cpp
r102283 r110172 35 35 36 36 #include "Element.h" 37 #include "NamedNodeMap.h" 37 38 #include "RenderBoxModelObject.h" 38 39 #include "RenderObject.h"
Note: See TracChangeset
for help on using the changeset viewer.