Changeset 122637 in webkit
- Timestamp:
- Jul 13, 2012 3:44:46 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r122636 r122637 1 2012-07-13 Ryosuke Niwa <rniwa@webkit.org> 2 3 NodeLists should not invalidate on irreleavnt attribute changes 4 https://bugs.webkit.org/show_bug.cgi?id=91277 5 6 Reviewed by Ojan Vafai. 7 8 Explicitely check the invalidation type and the changed attribute in NodeListNodeData::invalidateCaches 9 and ElementRareData::clearHTMLCollectionCaches to only invalidate node lists affected by the change. 10 11 Also merged invalidateNodeListsCacheAfterAttributeChanged and invalidateNodeListsCacheAfterChildrenChanged 12 as invalidateNodeListCachesInAncestors since they're almost identical after r122498. 13 14 In addition, moved shouldInvalidateNodeListForType from Document.cpp to DynamicNodeList.h and renamed it to 15 shouldInvalidateTypeOnAttributeChange since it needs to called in Node.cpp and ElementRareData.h. 16 17 * dom/Attr.cpp: 18 (WebCore::Attr::setValue): 19 (WebCore::Attr::childrenChanged): 20 * dom/ContainerNode.cpp: 21 (WebCore::ContainerNode::childrenChanged): 22 * dom/Document.cpp: 23 (WebCore::Document::registerNodeListCache): Calls isRootedAtDocument() instead of directly comparing 24 the value of NodeListRootType in order to prepare for the bug 80269. 25 (WebCore::Document::unregisterNodeListCache): Ditto. 26 (WebCore): shouldInvalidateNodeListForType is moved to DynamicNodeList.h 27 (WebCore::Document::shouldInvalidateNodeListCaches): 28 * dom/DynamicNodeList.h: 29 (DynamicNodeListCacheBase): 30 (WebCore::DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange): Moved from Document.cpp. 31 * dom/Element.cpp: 32 (WebCore::Element::attributeChanged): 33 * dom/ElementRareData.h: 34 (WebCore::ElementRareData::clearHTMLCollectionCaches): Takes const QualifiedName* to compare against 35 the invalidation type of HTML collections via shouldInvalidateTypeOnAttributeChange. 36 * dom/Node.cpp: 37 (WebCore::Node::invalidateNodeListCachesInAncestors): Merged invalidateNodeListCachesInAncestors and 38 invalidateNodeListsCacheAfterChildrenChanged. Also pass attrName to clearHTMLCollectionCaches. 39 (WebCore::NodeListsNodeData::invalidateCaches): Compares attrName against the invalidation type of 40 node lists via shouldInvalidateTypeOnAttributeChange. 41 (WebCore): 42 * dom/Node.h: 43 (Node): 44 * dom/NodeRareData.h: 45 (WebCore::NodeRareData::ensureNodeLists): Merged NodeRareData::createNodeLists. 46 (WebCore::NodeRareData::clearChildNodeListCache): Moved from Node.cpp. 47 (NodeRareData): 48 * html/HTMLCollection.h: 49 (HTMLCollectionCacheBase): 50 1 51 2012-07-13 Arpita Bahuguna <arpitabahuguna@gmail.com> 2 52 -
trunk/Source/WebCore/dom/Attr.cpp
r117956 r122637 120 120 m_ignoreChildrenChanged--; 121 121 122 invalidateNodeList sCacheAfterAttributeChanged(m_name, m_element);122 invalidateNodeListCachesInAncestors(&m_name, m_element); 123 123 } 124 124 … … 163 163 return; 164 164 165 invalidateNodeList sCacheAfterAttributeChanged(qualifiedName(), m_element);165 invalidateNodeListCachesInAncestors(&qualifiedName(), m_element); 166 166 167 167 // FIXME: We should include entity references in the value -
trunk/Source/WebCore/dom/ContainerNode.cpp
r119937 r122637 681 681 if (!changedByParser && childCountDelta) 682 682 document()->updateRangesAfterChildrenChanged(this); 683 invalidateNodeList sCacheAfterChildrenChanged();683 invalidateNodeListCachesInAncestors(); 684 684 } 685 685 -
trunk/Source/WebCore/dom/Document.cpp
r122626 r122637 3872 3872 m_nodeListCounts[InvalidateOnIdNameAttrChange]++; 3873 3873 m_nodeListCounts[list->invalidationType()]++; 3874 if (list-> rootType() == NodeListIsRootedAtDocument)3874 if (list->isRootedAtDocument()) 3875 3875 m_listsInvalidatedAtDocument.add(list); 3876 3876 } … … 3881 3881 m_nodeListCounts[InvalidateOnIdNameAttrChange]--; 3882 3882 m_nodeListCounts[list->invalidationType()]--; 3883 if (list-> rootType() == NodeListIsRootedAtDocument) {3883 if (list->isRootedAtDocument()) { 3884 3884 ASSERT(m_listsInvalidatedAtDocument.contains(list)); 3885 3885 m_listsInvalidatedAtDocument.remove(list); … … 3887 3887 } 3888 3888 3889 static ALWAYS_INLINE bool shouldInvalidateNodeListForType(NodeListInvalidationType type, const QualifiedName& attrName)3890 {3891 switch (type) {3892 case InvalidateOnClassAttrChange:3893 return attrName == classAttr;3894 case InvalidateOnNameAttrChange:3895 return attrName == nameAttr;3896 case InvalidateOnIdNameAttrChange:3897 return attrName == idAttr || attrName == nameAttr;3898 case InvalidateOnForAttrChange:3899 return attrName == forAttr;3900 case InvalidateForFormControls:3901 return attrName == nameAttr || attrName == idAttr || attrName == forAttr || attrName == typeAttr;3902 case InvalidateOnHRefAttrChange:3903 return attrName == hrefAttr;3904 case InvalidateOnItemAttrChange:3905 #if ENABLE(MICRODATA)3906 return attrName == itemscopeAttr || attrName == itempropAttr || attrName == itemtypeAttr;3907 #endif // Intentionally fall through3908 case DoNotInvalidateOnAttributeChanges:3909 ASSERT_NOT_REACHED();3910 return false;3911 case InvalidateOnAnyAttrChange:3912 return true;3913 }3914 return false;3915 }3916 3917 3889 bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const 3918 3890 { 3919 3891 if (attrName) { 3920 3892 for (int type = DoNotInvalidateOnAttributeChanges + 1; type < numNodeListInvalidationTypes; type++) { 3921 if (m_nodeListCounts[type] && shouldInvalidateNodeListForType(static_cast<NodeListInvalidationType>(type), *attrName))3893 if (m_nodeListCounts[type] && DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), *attrName)) 3922 3894 return true; 3923 3895 } -
trunk/Source/WebCore/dom/DynamicNodeList.h
r122621 r122637 27 27 #include "CollectionType.h" 28 28 #include "Document.h" 29 #include "HTMLNames.h" 29 30 #include "NodeList.h" 30 31 #include <wtf/Forward.h> … … 58 59 public: 59 60 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootedAtDocument; } 60 ALWAYS_INLINE bool shouldInvalidateOnAttributeChange() const { return m_invalidationType != DoNotInvalidateOnAttributeChanges; }61 ALWAYS_INLINE NodeListRootType rootType() { return m_rootedAtDocument ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode; }62 61 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); } 63 62 ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); } 64 63 65 64 void invalidateCache() const; 65 66 static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&); 66 67 67 68 protected: … … 101 102 const unsigned m_collectionType : 5; 102 103 }; 104 105 ALWAYS_INLINE bool DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName) 106 { 107 switch (type) { 108 case InvalidateOnClassAttrChange: 109 return attrName == HTMLNames::classAttr; 110 case InvalidateOnNameAttrChange: 111 return attrName == HTMLNames::nameAttr; 112 case InvalidateOnIdNameAttrChange: 113 return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr; 114 case InvalidateOnForAttrChange: 115 return attrName == HTMLNames::forAttr; 116 case InvalidateForFormControls: 117 return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr || attrName == HTMLNames::typeAttr; 118 case InvalidateOnHRefAttrChange: 119 return attrName == HTMLNames::hrefAttr; 120 case InvalidateOnItemAttrChange: 121 #if ENABLE(MICRODATA) 122 return attrName == HTMLNames::itemscopeAttr || attrName == HTMLNames::itempropAttr || attrName == HTMLNames::itemtypeAttr; 123 #endif // Intentionally fall through 124 case DoNotInvalidateOnAttributeChanges: 125 ASSERT_NOT_REACHED(); 126 return false; 127 case InvalidateOnAnyAttrChange: 128 return true; 129 } 130 return false; 131 } 103 132 104 133 class DynamicNodeList : public NodeList, public DynamicNodeListCacheBase { -
trunk/Source/WebCore/dom/Element.cpp
r122626 r122637 706 706 } 707 707 708 invalidateNodeList sCacheAfterAttributeChanged(attribute.name(), this);708 invalidateNodeListCachesInAncestors(&attribute.name(), this); 709 709 710 710 if (!AXObjectCache::accessibilityEnabled()) -
trunk/Source/WebCore/dom/ElementRareData.h
r122621 r122637 67 67 } 68 68 69 void clearHTMLCollectionCaches( )69 void clearHTMLCollectionCaches(const QualifiedName* attrName) 70 70 { 71 71 if (!m_cachedCollections) 72 72 return; 73 73 74 bool shouldIgnoreType = !attrName || *attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr; 75 74 76 for (unsigned i = 0; i < (*m_cachedCollections).size(); i++) { 75 if ((*m_cachedCollections)[i]) 76 (*m_cachedCollections)[i]->invalidateCache(); 77 if (HTMLCollection* collection = (*m_cachedCollections)[i]) { 78 if (shouldIgnoreType || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(collection->invalidationType(), *attrName)) 79 collection->invalidateCache(); 80 } 77 81 } 78 82 } -
trunk/Source/WebCore/dom/Node.cpp
r122621 r122637 963 963 } 964 964 965 void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& attrName, Element* attributeOwnerElement) 966 { 967 if (hasRareData() && isAttributeNode()) { 968 NodeRareData* data = rareData(); 969 ASSERT(!data->nodeLists()); 970 data->clearChildNodeListCache(); 971 } 965 void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement) 966 { 967 if (hasRareData() && (!attrName || isAttributeNode())) 968 rareData()->clearChildNodeListCache(); 972 969 973 970 // Modifications to attributes that are not associated with an Element can't invalidate NodeList caches. 974 if (!attributeOwnerElement) 975 return; 976 977 if (!document()->shouldInvalidateNodeListCaches(&attrName)) 978 return; 979 980 document()->clearNodeListCaches(); 981 982 for (Node* node = this; node; node = node->parentNode()) { 983 ASSERT(this == node || !node->isAttributeNode()); 984 if (!node->hasRareData()) 985 continue; 986 NodeRareData* data = node->rareData(); 987 if (data->nodeLists()) 988 data->nodeLists()->invalidateCaches(&attrName); 989 if (node->isElementNode()) 990 static_cast<ElementRareData*>(data)->clearHTMLCollectionCaches(); 991 } 992 } 993 994 void Node::invalidateNodeListsCacheAfterChildrenChanged() 995 { 996 if (hasRareData()) 997 rareData()->clearChildNodeListCache(); 971 if (attrName && !attributeOwnerElement) 972 return; 998 973 999 974 if (!document()->shouldInvalidateNodeListCaches()) … … 1007 982 NodeRareData* data = node->rareData(); 1008 983 if (data->nodeLists()) 1009 data->nodeLists()->invalidateCaches( );984 data->nodeLists()->invalidateCaches(attrName); 1010 985 if (node->isElementNode()) 1011 static_cast<ElementRareData*>(data)->clearHTMLCollectionCaches( );986 static_cast<ElementRareData*>(data)->clearHTMLCollectionCaches(attrName); 1012 987 } 1013 988 } … … 2250 2225 NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end(); 2251 2226 for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) { 2252 if (!attrName || it->second->shouldInvalidateOnAttributeChange()) 2253 it->second->invalidateCache(); 2227 DynamicNodeList* list = it->second; 2228 if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName)) 2229 list->invalidateCache(); 2254 2230 } 2255 2231 2256 2232 NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end(); 2257 2233 for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) { 2258 if (!attrName || it->second->shouldInvalidateOnAttributeChange()) 2259 it->second->invalidateCache(); 2234 DynamicNodeList* list = it->second; 2235 if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName)) 2236 list->invalidateCache(); 2260 2237 } 2261 2238 … … 2773 2750 #endif 2774 2751 2775 void NodeRareData::createNodeLists()2776 {2777 setNodeLists(NodeListsNodeData::create());2778 }2779 2780 void NodeRareData::clearChildNodeListCache()2781 {2782 if (m_childNodeList)2783 m_childNodeList->invalidateCache();2784 }2785 2786 2752 // It's important not to inline removedLastRef, because we don't want to inline the code to 2787 2753 // delete a Node at each deref call site. -
trunk/Source/WebCore/dom/Node.h
r122159 r122637 559 559 #endif 560 560 561 void invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName&, Element* attributeOwnerElement); 562 void invalidateNodeListsCacheAfterChildrenChanged(); 561 void invalidateNodeListCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0); 563 562 NodeListsNodeData* nodeLists(); 564 563 void removeCachedChildNodeList(); -
trunk/Source/WebCore/dom/NodeRareData.h
r122621 r122637 223 223 { 224 224 if (!m_nodeLists) 225 createNodeLists();225 setNodeLists(NodeListsNodeData::create()); 226 226 return m_nodeLists.get(); 227 227 } 228 void clearChildNodeListCache(); 228 void clearChildNodeListCache() 229 { 230 if (m_childNodeList) 231 m_childNodeList->invalidateCache(); 232 } 229 233 230 234 ChildNodeList* childNodeList() const { return m_childNodeList; } … … 345 349 346 350 private: 347 void createNodeLists();348 351 349 352 TreeScope* m_treeScope; -
trunk/Source/WebCore/html/HTMLCollection.h
r122621 r122637 64 64 private: 65 65 using DynamicNodeListCacheBase::isRootedAtDocument; 66 using DynamicNodeListCacheBase::shouldInvalidateOnAttributeChange;67 66 using DynamicNodeListCacheBase::setItemCache; 68 67
Note: See TracChangeset
for help on using the changeset viewer.