Changeset 122621 in webkit
- Timestamp:
- Jul 13, 2012 12:48:40 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r122619 r122621 1 2012-07-13 Ryosuke Niwa <rniwa@webkit.org> 2 3 HTMLCollection should use DynamicNodeList's invalidation model 4 https://bugs.webkit.org/show_bug.cgi?id=90326 5 6 Reviewed by Anders Carlsson. 7 8 Make HTMLCollection invalidated upon attribute and children changes instead of invalidating it on demand 9 by comparing DOM tree versions. Node that HTMLCollections owned by Document are invalidated with other 10 document-rooted node lists in m_listsInvalidatedAtDocument for simplicity although this mechanism is 11 normally used for node lists owned by a non-Document node that contains nodes outside of its subtree. 12 ItemProperties and FormControls are more "traditional" users of the mechanism. 13 14 Also, merged DynamicNodeList::invalidateCache and HTMLCollection::invalidateCache. 15 16 * dom/Document.cpp: 17 (WebCore::Document::registerNodeListCache): Renamed. No longer takes NodeListInvalidationType or 18 NodeListRootType since they can be obtained from the cache base. Increment the node list counter for 19 InvalidateOnIdNameAttrChange when a HTMLCollection is passed in since all HTMLCollections need to be 20 invalidated on id or name content attribute changes due to named getters. 21 (WebCore::Document::unregisterNodeListCache): Ditto. 22 (WebCore::shouldInvalidateNodeListForType): 23 (WebCore::Document::shouldInvalidateNodeListCaches): 24 (WebCore::Document::clearNodeListCaches): 25 * dom/Document.h: 26 (WebCore): Added InvalidateOnIdNameAttrChange, InvalidateOnHRefAttrChange, and InvalidateOnAnyAttrChange. 27 (Document): 28 * dom/DynamicNodeList.cpp: 29 (WebCore::DynamicNodeListCacheBase::invalidateCache): Added. Invalidates caches of both DynamicNodeList 30 and HTMLCollection. We can't afford to use virtual function calls here because this function is called on 31 all node lists and HTML collections owned by ancestors of an element under which a node is added, removed, 32 or its attributes are changed. 33 (WebCore): 34 * dom/DynamicNodeList.h: 35 (WebCore::DynamicNodeListCacheBase::DynamicNodeListCacheBase): Initializes member variables directly 36 instead of calling clearCache now that DynamicNodeListCacheBase::invalidateCache has become polymorphic. 37 (DynamicNodeListCacheBase): Increased the number of bits for m_invalidationType since we now have 9 38 invalidation types. 39 (WebCore::DynamicSubtreeNodeList::~DynamicSubtreeNodeList): 40 (WebCore::DynamicSubtreeNodeList::DynamicSubtreeNodeList): 41 * dom/ElementRareData.h: 42 (ElementRareData): 43 (WebCore::ElementRareData::clearHTMLCollectionCaches): Added. 44 (WebCore::ElementRareData::adoptTreeScope): Added; similar to NodeRareData::adoptTreeScope. 45 * dom/Node.cpp: 46 (WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged): Clears HTML collection caches as well as 47 node list caches. 48 (WebCore::Node::invalidateNodeListsCacheAfterChildrenChanged): Ditto. 49 * dom/NodeRareData.h: 50 (WebCore::NodeListsNodeData::adoptTreeScope): 51 * dom/TreeScopeAdopter.cpp: 52 (WebCore::TreeScopeAdopter::moveTreeToNewScope): Calls ElementRareData's adoptTreeScope as well as 53 NodeRareData's. 54 * html/HTMLAllCollection.cpp: 55 (WebCore::HTMLAllCollection::namedItemWithIndex): 56 * html/HTMLCollection.cpp: 57 (WebCore::rootTypeFromCollectionType): Added. As mentioned above, treat all Document-owned HTML collection 58 as if rooted at document for convenience. 59 (WebCore::invalidationTypeExcludingIdAndNameAttributes): Added. Since all HTML collection requires 60 invalidation on id and name content attribute changes, which is taken care by the special logic in 61 Document::registerNodeListCache, exclude those two attributes from consideration. 62 (WebCore::HTMLCollection::HTMLCollection): Calls Document::registerNodeListCache. 63 (WebCore::HTMLCollection::~HTMLCollection): Calls Document::unregisterNodeListCache. 64 (WebCore::HTMLCollection::length): 65 (WebCore::HTMLCollection::item): 66 (WebCore::HTMLCollection::namedItem): 67 (WebCore::HTMLCollection::updateNameCache): 68 * html/HTMLCollection.h: 69 (WebCore::HTMLCollectionCacheBase::HTMLCollectionCacheBase): 70 (HTMLCollectionCacheBase): Removed m_cacheTreeVersion and clearCache since they're no longer used. 71 (HTMLCollection): 72 * html/HTMLFormCollection.cpp: 73 (WebCore::HTMLFormCollection::namedItem): 74 (WebCore::HTMLFormCollection::updateNameCache): 75 * html/HTMLOptionsCollection.h: 76 (HTMLOptionsCollection): 77 * html/HTMLPropertiesCollection.cpp: 78 (WebCore::HTMLPropertiesCollection::updateNameCache): 79 * html/HTMLPropertiesCollection.h: 80 (WebCore::HTMLPropertiesCollection::invalidateCache): 81 1 82 2012-07-13 Shawn Singh <shawnsingh@chromium.org> 2 83 -
trunk/Source/WebCore/dom/Document.cpp
r122600 r122621 3862 3862 } 3863 3863 3864 void Document::registerDynamicSubtreeNodeList(DynamicSubtreeNodeList* list, NodeListRootType rootType, NodeListInvalidationType invalidationType) 3865 { 3866 m_nodeListCounts[invalidationType]++; 3867 if (rootType == NodeListIsRootedAtDocument) 3864 void Document::registerNodeListCache(DynamicNodeListCacheBase* list) 3865 { 3866 if (list->type() != InvalidCollectionType) 3867 m_nodeListCounts[InvalidateOnIdNameAttrChange]++; 3868 m_nodeListCounts[list->invalidationType()]++; 3869 if (list->rootType() == NodeListIsRootedAtDocument) 3868 3870 m_listsInvalidatedAtDocument.add(list); 3869 3871 } 3870 3872 3871 void Document::unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList* list, NodeListRootType rootType, NodeListInvalidationType invalidationType) 3872 { 3873 m_nodeListCounts[invalidationType]--; 3874 if (rootType == NodeListIsRootedAtDocument) { 3873 void Document::unregisterNodeListCache(DynamicNodeListCacheBase* list) 3874 { 3875 if (list->type() != InvalidCollectionType) 3876 m_nodeListCounts[InvalidateOnIdNameAttrChange]--; 3877 m_nodeListCounts[list->invalidationType()]--; 3878 if (list->rootType() == NodeListIsRootedAtDocument) { 3875 3879 ASSERT(m_listsInvalidatedAtDocument.contains(list)); 3876 3880 m_listsInvalidatedAtDocument.remove(list); … … 3885 3889 case InvalidateOnNameAttrChange: 3886 3890 return attrName == nameAttr; 3891 case InvalidateOnIdNameAttrChange: 3892 return attrName == idAttr || attrName == nameAttr; 3887 3893 case InvalidateOnForAttrChange: 3888 3894 return attrName == forAttr; 3889 3895 case InvalidateForFormControls: 3890 3896 return attrName == nameAttr || attrName == idAttr || attrName == forAttr || attrName == typeAttr; 3897 case InvalidateOnHRefAttrChange: 3898 return attrName == hrefAttr; 3891 3899 case InvalidateOnItemAttrChange: 3892 3900 #if ENABLE(MICRODATA) … … 3896 3904 ASSERT_NOT_REACHED(); 3897 3905 return false; 3906 case InvalidateOnAnyAttrChange: 3907 return true; 3898 3908 } 3899 3909 return false; 3900 3910 } 3901 3911 3902 bool Document::shouldInvalidate DynamicSubtreeNodeList(const QualifiedName* attrName) const3912 bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const 3903 3913 { 3904 3914 if (attrName) { … … 3920 3930 void Document::clearNodeListCaches() 3921 3931 { 3922 HashSet<Dynamic SubtreeNodeList*>::iterator end = m_listsInvalidatedAtDocument.end();3923 for (HashSet<Dynamic SubtreeNodeList*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)3932 HashSet<DynamicNodeListCacheBase*>::iterator end = m_listsInvalidatedAtDocument.end(); 3933 for (HashSet<DynamicNodeListCacheBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it) 3924 3934 (*it)->invalidateCache(); 3925 3935 } -
trunk/Source/WebCore/dom/Document.h
r122556 r122621 80 80 class DocumentType; 81 81 class DocumentWeakReference; 82 class DynamicNodeListCacheBase; 82 83 class EditingText; 83 84 class Element; … … 188 189 enum StyleResolverUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded }; 189 190 190 enum NodeListRootType {191 NodeListIsRootedAtNode,192 NodeListIsRootedAtDocument,193 };194 195 191 enum NodeListInvalidationType { 196 192 DoNotInvalidateOnAttributeChanges = 0, 197 193 InvalidateOnClassAttrChange, 194 InvalidateOnIdNameAttrChange, 198 195 InvalidateOnNameAttrChange, 199 196 InvalidateOnForAttrChange, 200 197 InvalidateForFormControls, 198 InvalidateOnHRefAttrChange, 201 199 InvalidateOnItemAttrChange, 200 InvalidateOnAnyAttrChange, 202 201 }; 203 const int numNodeListInvalidationTypes = InvalidateOn ItemAttrChange + 1;202 const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1; 204 203 205 204 class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext { … … 737 736 void styleRecalcTimerFired(Timer<Document>*); 738 737 739 void register DynamicSubtreeNodeList(DynamicSubtreeNodeList*, NodeListRootType, NodeListInvalidationType);740 void unregister DynamicSubtreeNodeList(DynamicSubtreeNodeList*, NodeListRootType, NodeListInvalidationType);741 bool shouldInvalidate DynamicSubtreeNodeList(const QualifiedName* attrName = 0) const;738 void registerNodeListCache(DynamicNodeListCacheBase*); 739 void unregisterNodeListCache(DynamicNodeListCacheBase*); 740 bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const; 742 741 void clearNodeListCaches(); 743 742 … … 1423 1422 InheritedBool m_designMode; 1424 1423 1425 HashSet<Dynamic SubtreeNodeList*> m_listsInvalidatedAtDocument;1424 HashSet<DynamicNodeListCacheBase*> m_listsInvalidatedAtDocument; 1426 1425 unsigned m_nodeListCounts[numNodeListInvalidationTypes]; 1427 1426 -
trunk/Source/WebCore/dom/DynamicNodeList.cpp
r122498 r122621 26 26 #include "Document.h" 27 27 #include "Element.h" 28 #include "HTMLCollection.h" 29 #include "HTMLPropertiesCollection.h" 28 30 29 31 namespace WebCore { 32 33 void DynamicNodeListCacheBase::invalidateCache() const 34 { 35 m_cachedItem = 0; 36 m_isLengthCacheValid = false; 37 m_isItemCacheValid = false; 38 m_isNameCacheValid = false; 39 if (type() == InvalidCollectionType) 40 return; 41 42 const HTMLCollectionCacheBase* cacheBase = static_cast<const HTMLCollectionCacheBase*>(this); 43 cacheBase->m_idCache.clear(); 44 cacheBase->m_nameCache.clear(); 45 cacheBase->m_cachedElementsArrayOffset = 0; 46 47 #if ENABLE(MICRODATA) 48 // FIXME: There should be more generic mechanism to clear caches in subclasses. 49 if (type() == ItemProperties) 50 static_cast<const HTMLPropertiesCollection*>(this)->invalidateCache(); 51 #endif 52 } 30 53 31 54 unsigned DynamicSubtreeNodeList::length() const -
trunk/Source/WebCore/dom/DynamicNodeList.h
r122533 r122621 36 36 class Node; 37 37 38 enum NodeListRootType { 39 NodeListIsRootedAtNode, 40 NodeListIsRootedAtDocument, 41 }; 42 38 43 class DynamicNodeListCacheBase { 39 44 public: 40 DynamicNodeListCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType) 41 : m_rootedAtDocument(rootType == NodeListIsRootedAtDocument) 45 DynamicNodeListCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType = InvalidCollectionType) 46 : m_cachedItem(0) 47 , m_isLengthCacheValid(false) 48 , m_isItemCacheValid(false) 49 , m_rootedAtDocument(rootType == NodeListIsRootedAtDocument) 42 50 , m_invalidationType(invalidationType) 43 , m_collectionType(InvalidCollectionType) 51 , m_isNameCacheValid(false) 52 , m_collectionType(collectionType) 44 53 { 45 54 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType)); 46 clearCache();47 }48 49 DynamicNodeListCacheBase(CollectionType collectionType)50 : m_rootedAtDocument(false) // Ignored51 , m_invalidationType(DoNotInvalidateOnAttributeChanges) // Ignored52 , m_collectionType(collectionType)53 {54 55 ASSERT(m_collectionType == static_cast<unsigned>(collectionType)); 55 clearCache();56 56 } 57 57 … … 62 62 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); } 63 63 ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); } 64 65 void invalidateCache() const; 64 66 65 67 protected: … … 86 88 void setHasNameCache() const { m_isNameCacheValid = true; } 87 89 88 void clearCache() const89 {90 m_cachedItem = 0;91 m_isLengthCacheValid = false;92 m_isItemCacheValid = false;93 m_isNameCacheValid = false;94 }95 96 90 private: 97 91 mutable Node* m_cachedItem; … … 100 94 mutable unsigned m_isLengthCacheValid : 1; 101 95 mutable unsigned m_isItemCacheValid : 1; 102 103 // From DynamicNodeList104 96 const unsigned m_rootedAtDocument : 1; 105 const unsigned m_invalidationType : 3;97 const unsigned m_invalidationType : 4; 106 98 107 99 // From HTMLCollection … … 134 126 // Other methods (not part of DOM) 135 127 Node* ownerNode() const { return m_ownerNode.get(); } 136 void invalidateCache() { clearCache(); }137 128 138 129 protected: … … 155 146 virtual ~DynamicSubtreeNodeList() 156 147 { 157 document()->unregister DynamicSubtreeNodeList(this, rootType(), invalidationType());148 document()->unregisterNodeListCache(this); 158 149 } 159 150 virtual unsigned length() const OVERRIDE; … … 164 155 : DynamicNodeList(node, rootType, invalidationType) 165 156 { 166 document()->register DynamicSubtreeNodeList(this, rootType, invalidationType);157 document()->registerNodeListCache(this); 167 158 } 168 159 -
trunk/Source/WebCore/dom/ElementRareData.h
r122550 r122621 27 27 #include "Element.h" 28 28 #include "ElementShadow.h" 29 #include "HTMLCollection.h" 29 30 #include "NamedNodeMap.h" 30 31 #include "NodeRareData.h" … … 58 59 return (*m_cachedCollections)[type - FirstNodeCollectionType]; 59 60 } 61 60 62 void removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type) 61 63 { … … 63 65 ASSERT_UNUSED(collection, (*m_cachedCollections)[type - FirstNodeCollectionType] == collection); 64 66 (*m_cachedCollections)[type - FirstNodeCollectionType] = 0; 67 } 68 69 void clearHTMLCollectionCaches() 70 { 71 if (!m_cachedCollections) 72 return; 73 74 for (unsigned i = 0; i < (*m_cachedCollections).size(); i++) { 75 if ((*m_cachedCollections)[i]) 76 (*m_cachedCollections)[i]->invalidateCache(); 77 } 78 } 79 80 void adoptTreeScope(Document* oldDocument, Document* newDocument) 81 { 82 if (!m_cachedCollections) 83 return; 84 85 for (unsigned i = 0; i < (*m_cachedCollections).size(); i++) { 86 HTMLCollection* collection = (*m_cachedCollections)[i]; 87 if (!collection) 88 continue; 89 collection->invalidateCache(); 90 if (oldDocument != newDocument) { 91 oldDocument->unregisterNodeListCache(collection); 92 newDocument->registerNodeListCache(collection); 93 } 94 } 65 95 } 66 96 -
trunk/Source/WebCore/dom/Node.cpp
r122600 r122621 48 48 #include "DynamicNodeList.h" 49 49 #include "Element.h" 50 #include "ElementRareData.h" 50 51 #include "ElementShadow.h" 51 52 #include "Event.h" … … 974 975 return; 975 976 976 if (!document()->shouldInvalidate DynamicSubtreeNodeList(&attrName))977 if (!document()->shouldInvalidateNodeListCaches(&attrName)) 977 978 return; 978 979 … … 984 985 continue; 985 986 NodeRareData* data = node->rareData(); 986 if ( !data->nodeLists())987 continue;988 989 data->nodeLists()->invalidateCaches(&attrName);987 if (data->nodeLists()) 988 data->nodeLists()->invalidateCaches(&attrName); 989 if (node->isElementNode()) 990 static_cast<ElementRareData*>(data)->clearHTMLCollectionCaches(); 990 991 } 991 992 } … … 996 997 rareData()->clearChildNodeListCache(); 997 998 998 if (!document()->shouldInvalidate DynamicSubtreeNodeList())999 if (!document()->shouldInvalidateNodeListCaches()) 999 1000 return; 1000 1001 … … 1005 1006 continue; 1006 1007 NodeRareData* data = node->rareData(); 1007 if ( !data->nodeLists())1008 continue;1009 1010 data->nodeLists()->invalidateCaches();1008 if (data->nodeLists()) 1009 data->nodeLists()->invalidateCaches(); 1010 if (node->isElementNode()) 1011 static_cast<ElementRareData*>(data)->clearHTMLCollectionCaches(); 1011 1012 } 1012 1013 } -
trunk/Source/WebCore/dom/NodeRareData.h
r122498 r122621 139 139 DynamicSubtreeNodeList* list = it->second; 140 140 if (list->isRootedAtDocument()) { 141 oldDocument->unregister DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());142 newDocument->register DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());141 oldDocument->unregisterNodeListCache(list); 142 newDocument->registerNodeListCache(list); 143 143 } 144 144 } … … 148 148 DynamicSubtreeNodeList* list = it->second; 149 149 if (list->isRootedAtDocument()) { 150 oldDocument->unregister DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());151 newDocument->register DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());150 oldDocument->unregisterNodeListCache(list); 151 newDocument->registerNodeListCache(list); 152 152 } 153 153 } … … 157 157 DynamicSubtreeNodeList* list = it->second; 158 158 ASSERT(!list->isRootedAtDocument()); 159 oldDocument->unregister DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());160 newDocument->register DynamicSubtreeNodeList(list, list->rootType(), list->invalidationType());159 oldDocument->unregisterNodeListCache(list); 160 newDocument->registerNodeListCache(list); 161 161 } 162 162 } -
trunk/Source/WebCore/dom/TreeScopeAdopter.cpp
r122498 r122621 27 27 28 28 #include "Document.h" 29 #include "ElementRareData.h" 29 30 #include "ElementShadow.h" 30 31 #include "NodeRareData.h" 32 #include "RenderStyle.h" 31 33 #include "ShadowRoot.h" 32 34 … … 48 50 49 51 for (Node* node = root; node; node = node->traverseNextNode(root)) { 50 NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope); 51 if (rareData && rareData->nodeLists()) 52 rareData->nodeLists()->adoptTreeScope(oldDocument, newDocument); 52 if (NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope)) { 53 if (rareData->nodeLists()) 54 rareData->nodeLists()->adoptTreeScope(oldDocument, newDocument); 55 if (node->isElementNode()) 56 static_cast<ElementRareData*>(rareData)->adoptTreeScope(oldDocument, newDocument); 57 } 53 58 54 59 if (willMoveToNewDocument) -
trunk/Source/WebCore/html/HTMLAllCollection.cpp
r122115 r122621 47 47 Node* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const 48 48 { 49 invalidateCacheIfNeeded();50 49 updateNameCache(); 51 50 -
trunk/Source/WebCore/html/HTMLCollection.cpp
r122531 r122621 77 77 } 78 78 79 static NodeListRootType rootTypeFromCollectionType(CollectionType type) 80 { 81 switch (type) { 82 case DocImages: 83 case DocApplets: 84 case DocEmbeds: 85 case DocObjects: 86 case DocForms: 87 case DocLinks: 88 case DocAnchors: 89 case DocScripts: 90 case DocAll: 91 case WindowNamedItems: 92 case DocumentNamedItems: 93 #if ENABLE(MICRODATA) 94 case ItemProperties: 95 #endif 96 case FormControls: 97 return NodeListIsRootedAtDocument; 98 case NodeChildren: 99 case TableTBodies: 100 case TSectionRows: 101 case TableRows: 102 case TRCells: 103 case SelectOptions: 104 case SelectedOptions: 105 case DataListOptions: 106 case MapAreas: 107 case InvalidCollectionType: 108 return NodeListIsRootedAtNode; 109 } 110 ASSERT_NOT_REACHED(); 111 return NodeListIsRootedAtNode; 112 } 113 114 static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type) 115 { 116 switch (type) { 117 case DocImages: 118 case DocEmbeds: 119 case DocObjects: 120 case DocForms: 121 case DocAnchors: // Depends on name attribute. 122 case DocScripts: 123 case DocAll: 124 case WindowNamedItems: // Depends on id and name attributes. 125 case DocumentNamedItems: // Ditto. 126 case NodeChildren: 127 case TableTBodies: 128 case TSectionRows: 129 case TableRows: 130 case TRCells: 131 case SelectOptions: 132 case MapAreas: 133 return DoNotInvalidateOnAttributeChanges; 134 case DocApplets: 135 case SelectedOptions: 136 case DataListOptions: 137 // FIXME: We can do better some day. 138 return InvalidateOnAnyAttrChange; 139 case DocLinks: 140 return InvalidateOnHRefAttrChange; 141 #if ENABLE(MICRODATA) 142 case ItemProperties: 143 return InvalidateOnItemAttrChange; 144 #endif 145 case FormControls: 146 return InvalidateForFormControls; 147 case InvalidCollectionType: 148 break; 149 } 150 ASSERT_NOT_REACHED(); 151 return DoNotInvalidateOnAttributeChanges; 152 } 153 154 79 155 HTMLCollection::HTMLCollection(Node* base, CollectionType type) 80 : HTMLCollectionCacheBase( type)156 : HTMLCollectionCacheBase(rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type) 81 157 , m_base(base) 82 158 { 83 159 ASSERT(m_base); 160 m_base->document()->registerNodeListCache(this); 84 161 } 85 162 … … 99 176 } else // HTMLNameCollection removes cache by itself. 100 177 ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems); 101 } 102 103 void HTMLCollection::invalidateCacheIfNeeded() const 104 { 105 uint64_t docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion(); 106 107 if (cacheTreeVersion() == docversion) 108 return; 109 110 invalidateCache(); 111 } 112 113 void HTMLCollection::invalidateCache() const 114 { 115 #if ENABLE(MICRODATA) 116 // FIXME: There should be more generic mechanism to clear caches in subclasses. 117 if (type() == ItemProperties) 118 static_cast<const HTMLPropertiesCollection*>(this)->clearCache(); 119 #endif 120 clearCache(static_cast<HTMLDocument*>(m_base->document())->domTreeVersion()); 178 179 m_base->document()->unregisterNodeListCache(this); 121 180 } 122 181 … … 201 260 unsigned HTMLCollection::length() const 202 261 { 203 invalidateCacheIfNeeded();204 262 if (isLengthCacheValid()) 205 263 return cachedLength(); … … 223 281 Node* HTMLCollection::item(unsigned index) const 224 282 { 225 invalidateCacheIfNeeded();226 283 if (isItemCacheValid() && cachedItemOffset() == index) 227 284 return cachedItem(); … … 307 364 // object with a matching name attribute, but only on those elements 308 365 // that are allowed a name attribute. 309 invalidateCacheIfNeeded();310 366 311 367 unsigned arrayOffset = 0; … … 333 389 void HTMLCollection::updateNameCache() const 334 390 { 335 invalidateCacheIfNeeded();336 391 if (hasNameCache()) 337 392 return; -
trunk/Source/WebCore/html/HTMLCollection.h
r122531 r122621 40 40 class HTMLCollectionCacheBase : public DynamicNodeListCacheBase { 41 41 public: 42 HTMLCollectionCacheBase( CollectionType type)43 : DynamicNodeListCacheBase( type)42 HTMLCollectionCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType) 43 : DynamicNodeListCacheBase(rootType, invalidationType, collectionType) 44 44 , m_cachedElementsArrayOffset(0) 45 , m_cacheTreeVersion(0)46 45 { 47 46 } 48 47 49 48 protected: 50 void clearCache(uint64_t currentDomTreeVersion) const51 {52 DynamicNodeListCacheBase::clearCache();53 m_idCache.clear();54 m_nameCache.clear();55 m_cachedElementsArrayOffset = 0;56 m_cacheTreeVersion = currentDomTreeVersion;57 }58 59 49 void setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const 60 50 { … … 63 53 } 64 54 unsigned cachedElementsArrayOffset() const { return m_cachedElementsArrayOffset; } 65 66 uint64_t cacheTreeVersion() const { return m_cacheTreeVersion; }67 55 68 56 typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap; … … 77 65 using DynamicNodeListCacheBase::isRootedAtDocument; 78 66 using DynamicNodeListCacheBase::shouldInvalidateOnAttributeChange; 79 using DynamicNodeListCacheBase::clearCache;80 67 using DynamicNodeListCacheBase::setItemCache; 81 68 … … 83 70 mutable NodeCacheMap m_nameCache; 84 71 mutable unsigned m_cachedElementsArrayOffset; 85 mutable uint64_t m_cacheTreeVersion; 72 73 friend void DynamicNodeListCacheBase::invalidateCache() const; 86 74 }; 87 75 … … 102 90 bool isEmpty() const 103 91 { 104 invalidateCacheIfNeeded();105 92 if (isLengthCacheValid()) 106 93 return !cachedLength(); … … 111 98 bool hasExactlyOneItem() const 112 99 { 113 invalidateCacheIfNeeded();114 100 if (isLengthCacheValid()) 115 101 return cachedLength() == 1; … … 120 106 121 107 Node* base() const { return m_base.get(); } 122 123 void invalidateCache() const;124 void invalidateCacheIfNeeded() const;125 108 126 109 protected: -
trunk/Source/WebCore/html/HTMLFormCollection.cpp
r122518 r122621 112 112 // object with a matching name attribute, but only on those elements 113 113 // that are allowed a name attribute. 114 invalidateCacheIfNeeded();115 114 const Vector<HTMLImageElement*>* imagesElements = base()->hasTagName(fieldsetTag) ? 0 : &formImageElements(); 116 115 if (HTMLElement* item = firstNamedItem(formControlElements(), imagesElements, idAttr, name)) … … 122 121 void HTMLFormCollection::updateNameCache() const 123 122 { 124 invalidateCacheIfNeeded();125 123 if (hasNameCache()) 126 124 return; -
trunk/Source/WebCore/html/HTMLOptionsCollection.h
r122115 r122621 47 47 void setLength(unsigned, ExceptionCode&); 48 48 49 using HTMLCollection::invalidateCacheIfNeeded;50 51 49 private: 52 50 HTMLOptionsCollection(Element*); -
trunk/Source/WebCore/html/HTMLPropertiesCollection.cpp
r122518 r122621 143 143 void HTMLPropertiesCollection::updateNameCache() const 144 144 { 145 invalidateCacheIfNeeded();146 145 if (m_hasPropertyNameCache) 147 146 return; -
trunk/Source/WebCore/html/HTMLPropertiesCollection.h
r122518 r122621 52 52 virtual bool hasNamedItem(const AtomicString&) const OVERRIDE; 53 53 54 void clearCache() const54 void invalidateCache() const 55 55 { 56 56 m_itemRefElements.clear();
Note: See TracChangeset
for help on using the changeset viewer.