Changeset 122498 in webkit
- Timestamp:
- Jul 12, 2012 1:31:09 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r122494 r122498 1 2012-07-11 Ryosuke Niwa <rniwa@webkit.org> 2 3 invalidateNodeListsCacheAfterAttributeChanged should dynamically figure out which attribute needs invalidation 4 https://bugs.webkit.org/show_bug.cgi?id=91046 5 6 Reviewed by Anders Carlsson. 7 8 Added an array of counters (m_nodeListCounts) for each set of attributes (NodeListInvalidationType) node lists care about 9 to Document, and made DynamicSubtreeNodeList's constructor and destructor increment and decrement these counters via 10 registerDynamicSubtreeNodeList and unregisterDynamicSubtreeNodeList respectively. shouldInvalidateDynamicSubtreeNodeList, 11 which is called by invalidateNodeListsCacheAfterAttributeChanged, then use these counters to determine whether a given 12 attribute change should result in node list invalidations. 13 14 Also removed m_numNodeListCaches from TreeScope because this counter has now become redundant with m_nodeListCounts. 15 16 * dom/ChildNodeList.cpp: 17 (WebCore::ChildNodeList::ChildNodeList): Do not invalidate on attribute changes. 18 * dom/ClassNodeList.cpp: 19 (WebCore::ClassNodeList::ClassNodeList): Invalidate on class attribute changes. 20 * dom/Document.cpp: 21 (WebCore::Document::Document): Initialize m_nodeListCounts. 22 (WebCore::Document::~Document): Add assertions to make sure m_listsInvalidatedAtDocument, m_nodeListCounts, and 23 m_collections are all empty. 24 (WebCore::Document::registerDynamicSubtreeNodeList): This function is now called for all DynamicSubtreeNodeLists supposed 25 to just ones rooted at the document in order to increment the counter for each invalidation type. 26 (WebCore::Document::unregisterDynamicSubtreeNodeList): Ditto. 27 (WebCore::shouldInvalidateDynamicSubtreeNodeListForType): Checks the attribute name against NodeListInvalidationType. 28 (WebCore::Document::shouldInvalidateDynamicSubtreeNodeList): Returns true if the given attribute name matches the invalidation 29 type of the existing DynamicSubtreeNodeLists in the document. If the attribute name is not given (used when children change), 30 then it checks for the existence of any DynamicSubtreeNodeLists. Conceptually, this function can be written as a list of 31 "if" statements that checks values in m_nodeListCounts and the attribute name. We use "for" loop and switch statement instead 32 to share logic and detect future addition of values to NodeListInvalidationType. 33 * dom/Document.h: 34 (Document): Moved RootType and InvalidationType from DynamicNodeListCacheBase and renamed them to NodeListRootType and 35 NodeListInvalidationType respectively in order to reduce the possibility of future name collisions. Also the invalidation type 36 now contains 6 values instead of 2. 37 * dom/DynamicNodeList.cpp: 38 (WebCore): 39 * dom/DynamicNodeList.h: 40 (WebCore::DynamicNodeListCacheBase::DynamicNodeListCacheBase): 41 (WebCore::DynamicNodeListCacheBase::shouldInvalidateOnAttributeChange): 42 (WebCore::DynamicNodeListCacheBase::rootType): Added. 43 (WebCore::DynamicNodeListCacheBase::invalidationType): Added. 44 (DynamicNodeListCacheBase): Uses 3 bits to store invalidation type now that the number of values have increased from 2 to 6. 45 (WebCore::DynamicNodeList::DynamicNodeList): 46 (WebCore::DynamicSubtreeNodeList::~DynamicSubtreeNodeList): Call unregisterDynamicSubtreeNodeList. 47 (WebCore::DynamicSubtreeNodeList::DynamicSubtreeNodeList): Call registerDynamicSubtreeNodeList. 48 * dom/MicroDataItemList.cpp: 49 (WebCore::MicroDataItemList::MicroDataItemList): Invalidate on itemscope, itemprop, and itemtype content attribute changes. 50 * dom/NameNodeList.cpp: 51 (WebCore::NameNodeList::NameNodeList): Invalidate on name attribute changes. 52 * dom/Node.cpp: 53 (WebCore::Node::clearRareData): 54 (WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged): Replaced the hard coded check list of attributes, by a call 55 to shouldInvalidateDynamicSubtreeNodeList. 56 (WebCore::Node::invalidateNodeListsCacheAfterChildrenChanged): Calls shouldInvalidateDynamicSubtreeNodeList. 57 (WebCore::Node::getElementsByTagName): 58 (WebCore::Node::getElementsByTagNameNS): 59 (WebCore::Node::getElementsByName): 60 (WebCore::Node::getElementsByClassName): 61 (WebCore::Node::radioNodeList): 62 (WebCore::NodeRareData::createNodeLists): 63 * dom/NodeRareData.h: 64 (WebCore::NodeListsNodeData::adoptTreeScope): Unregister and register node lists in m_tagNodeListCacheNS since all node lists 65 need to be accounted in m_nodeListCounts. 66 (WebCore::NodeRareData::ensureNodeLists): 67 (NodeRareData): 68 * dom/TagNodeList.cpp: 69 (WebCore::TagNodeList::TagNodeList): Do not invalidate on any attribute changes. 70 * dom/TreeScope.cpp: 71 (WebCore::TreeScope::TreeScope): No longer initializes m_numNodeListCaches since it has been removed. 72 * dom/TreeScope.h: 73 (TreeScope): Removed m_numNodeListCaches. 74 * dom/TreeScopeAdopter.cpp: 75 (WebCore::TreeScopeAdopter::moveTreeToNewScope): 76 * html/HTMLCollection.h: 77 (WebCore::HTMLCollectionCacheBase::HTMLCollectionCacheBase): Just pass in DoNotInvalidateOnAttributeChanges for now since 78 it's never used in HTMLCollections. 79 * html/LabelableElement.cpp: 80 (WebCore::LabelableElement::labels): 81 * html/LabelsNodeList.cpp: 82 (WebCore::LabelsNodeList::LabelsNodeList): Invalidate on for content attribute changes. 83 (WebCore::LabelsNodeList::~LabelsNodeList): 84 * html/RadioNodeList.cpp: 85 (WebCore::RadioNodeList::RadioNodeList): Invalidate on id, name, and for content attribute changes. 86 (WebCore::RadioNodeList::~RadioNodeList): 87 1 88 2012-07-12 Gavin Barraclough <barraclough@apple.com> 2 89 -
trunk/Source/WebCore/dom/ChildNodeList.cpp
r121580 r122498 29 29 30 30 ChildNodeList::ChildNodeList(PassRefPtr<Node> node) 31 : DynamicNodeList(node, RootedAtNode, DoNotInvalidateOnAttributeChange)31 : DynamicNodeList(node, NodeListIsRootedAtNode, DoNotInvalidateOnAttributeChanges) 32 32 { 33 33 } -
trunk/Source/WebCore/dom/ClassNodeList.cpp
r121003 r122498 38 38 39 39 ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames) 40 : DynamicSubtreeNodeList(rootNode )40 : DynamicSubtreeNodeList(rootNode, InvalidateOnClassAttrChange) 41 41 , m_classNames(classNames, document()->inQuirksMode()) 42 42 , m_originalClassNames(classNames) -
trunk/Source/WebCore/dom/Document.cpp
r122205 r122498 565 565 static int docID = 0; 566 566 m_docID = docID++; 567 567 568 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++) 569 m_nodeListCounts[i] = 0; 570 568 571 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++) 569 572 m_collections[i] = 0; … … 648 651 if (hasRareData()) 649 652 clearRareData(); 653 654 ASSERT(!m_listsInvalidatedAtDocument.size()); 655 656 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++) 657 ASSERT(!m_nodeListCounts[i]); 658 659 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++) 660 ASSERT(!m_collections[i]); 650 661 651 662 m_document = 0; … … 3866 3877 } 3867 3878 3868 void Document::registerDynamicSubtreeNodeList(DynamicSubtreeNodeList* list) 3869 { 3870 m_listsInvalidatedAtDocument.add(list); 3871 } 3872 3873 void Document::unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList* list) 3874 { 3875 m_listsInvalidatedAtDocument.remove(list); 3879 void Document::registerDynamicSubtreeNodeList(DynamicSubtreeNodeList* list, NodeListRootType rootType, NodeListInvalidationType invalidationType) 3880 { 3881 m_nodeListCounts[invalidationType]++; 3882 if (rootType == NodeListIsRootedAtDocument) 3883 m_listsInvalidatedAtDocument.add(list); 3884 } 3885 3886 void Document::unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList* list, NodeListRootType rootType, NodeListInvalidationType invalidationType) 3887 { 3888 m_nodeListCounts[invalidationType]--; 3889 if (rootType == NodeListIsRootedAtDocument) { 3890 ASSERT(m_listsInvalidatedAtDocument.contains(list)); 3891 m_listsInvalidatedAtDocument.remove(list); 3892 } 3893 } 3894 3895 static ALWAYS_INLINE bool shouldInvalidateNodeListForType(NodeListInvalidationType type, const QualifiedName& attrName) 3896 { 3897 switch (type) { 3898 case InvalidateOnClassAttrChange: 3899 return attrName == classAttr; 3900 case InvalidateOnNameAttrChange: 3901 return attrName == nameAttr; 3902 case InvalidateOnForAttrChange: 3903 return attrName == forAttr; 3904 case InvalidateOnIdNameForAttrChange: 3905 return attrName == nameAttr || attrName == idAttr || attrName == forAttr; 3906 case InvalidateOnItemAttrChange: 3907 #if ENABLE(MICRODATA) 3908 return attrName == itemscopeAttr || attrName == itempropAttr || attrName == itemtypeAttr; 3909 #endif // Intentionally fall through 3910 case DoNotInvalidateOnAttributeChanges: 3911 ASSERT_NOT_REACHED(); 3912 return false; 3913 } 3914 return false; 3915 } 3916 3917 bool Document::shouldInvalidateDynamicSubtreeNodeList(const QualifiedName* attrName) const 3918 { 3919 if (attrName) { 3920 for (int type = DoNotInvalidateOnAttributeChanges + 1; type < numNodeListInvalidationTypes; type++) { 3921 if (m_nodeListCounts[type] && shouldInvalidateNodeListForType(static_cast<NodeListInvalidationType>(type), *attrName)) 3922 return true; 3923 } 3924 return false; 3925 } 3926 3927 for (int type = 0; type < numNodeListInvalidationTypes; type++) { 3928 if (m_nodeListCounts[type]) 3929 return true; 3930 } 3931 3932 return false; 3876 3933 } 3877 3934 … … 5966 6023 String localTypeNames = typeNames.isNull() ? MicroDataItemList::undefinedItemType() : typeNames; 5967 6024 5968 return ensureRareData()->ensureNodeLists( this)->addCacheWithName<MicroDataItemList>(this, DynamicNodeList::MicroDataItemListType, localTypeNames);6025 return ensureRareData()->ensureNodeLists()->addCacheWithName<MicroDataItemList>(this, DynamicNodeList::MicroDataItemListType, localTypeNames); 5969 6026 } 5970 6027 #endif -
trunk/Source/WebCore/dom/Document.h
r122205 r122498 187 187 enum StyleResolverUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded }; 188 188 189 enum NodeListRootType { 190 NodeListIsRootedAtNode, 191 NodeListIsRootedAtDocument, 192 }; 193 194 enum NodeListInvalidationType { 195 DoNotInvalidateOnAttributeChanges = 0, 196 InvalidateOnClassAttrChange, 197 InvalidateOnNameAttrChange, 198 InvalidateOnForAttrChange, 199 InvalidateOnIdNameForAttrChange, 200 InvalidateOnItemAttrChange, 201 }; 202 const int numNodeListInvalidationTypes = InvalidateOnItemAttrChange + 1; 203 189 204 class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext { 190 205 public: … … 724 739 void styleRecalcTimerFired(Timer<Document>*); 725 740 726 void registerDynamicSubtreeNodeList(DynamicSubtreeNodeList*); 727 void unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList*); 741 void registerDynamicSubtreeNodeList(DynamicSubtreeNodeList*, NodeListRootType, NodeListInvalidationType); 742 void unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList*, NodeListRootType, NodeListInvalidationType); 743 bool shouldInvalidateDynamicSubtreeNodeList(const QualifiedName* attrName = 0) const; 728 744 void clearNodeListCaches(); 729 745 … … 1410 1426 1411 1427 HashSet<DynamicSubtreeNodeList*> m_listsInvalidatedAtDocument; 1428 unsigned m_nodeListCounts[numNodeListInvalidationTypes]; 1412 1429 1413 1430 HTMLCollection* m_collections[NumUnnamedDocumentCachedTypes]; -
trunk/Source/WebCore/dom/DynamicNodeList.cpp
r121580 r122498 28 28 29 29 namespace WebCore { 30 31 DynamicSubtreeNodeList::~DynamicSubtreeNodeList()32 {33 }34 30 35 31 unsigned DynamicSubtreeNodeList::length() const -
trunk/Source/WebCore/dom/DynamicNodeList.h
r121580 r122498 37 37 class DynamicNodeListCacheBase { 38 38 public: 39 enum RootType { 40 RootedAtNode, 41 RootedAtDocument, 42 }; 43 44 enum InvalidationType { 45 AlwaysInvalidate, 46 DoNotInvalidateOnAttributeChange, 47 }; 48 49 DynamicNodeListCacheBase(RootType rootType, InvalidationType invalidationType) 50 : m_rootedAtDocument(rootType == RootedAtDocument) 51 , m_shouldInvalidateOnAttributeChange(invalidationType == AlwaysInvalidate) 39 DynamicNodeListCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType) 40 : m_rootedAtDocument(rootType == NodeListIsRootedAtDocument) 41 , m_invalidationType(invalidationType) 52 42 { 43 ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType)); 53 44 clearCache(); 54 45 } … … 56 47 public: 57 48 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootedAtDocument; } 58 ALWAYS_INLINE bool shouldInvalidateOnAttributeChange() const { return m_shouldInvalidateOnAttributeChange; } 49 ALWAYS_INLINE bool shouldInvalidateOnAttributeChange() const { return m_invalidationType != DoNotInvalidateOnAttributeChanges; } 50 ALWAYS_INLINE NodeListRootType rootType() { return m_rootedAtDocument ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode; } 51 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); } 59 52 60 53 protected: … … 93 86 // From DynamicNodeList 94 87 const unsigned m_rootedAtDocument : 1; 95 const unsigned m_ shouldInvalidateOnAttributeChange : 1;88 const unsigned m_invalidationType : 3; 96 89 }; 97 90 … … 107 100 MicroDataItemListType, 108 101 }; 109 DynamicNodeList(PassRefPtr<Node> ownerNode, RootType rootType,InvalidationType invalidationType)102 DynamicNodeList(PassRefPtr<Node> ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType) 110 103 : DynamicNodeListCacheBase(rootType, invalidationType) 111 104 , m_ownerNode(ownerNode) … … 139 132 class DynamicSubtreeNodeList : public DynamicNodeList { 140 133 public: 141 virtual ~DynamicSubtreeNodeList(); 134 virtual ~DynamicSubtreeNodeList() 135 { 136 document()->unregisterDynamicSubtreeNodeList(this, rootType(), invalidationType()); 137 } 142 138 virtual unsigned length() const OVERRIDE; 143 139 virtual Node* item(unsigned index) const OVERRIDE; 144 140 145 141 protected: 146 DynamicSubtreeNodeList(PassRefPtr<Node> node, RootType rootType = RootedAtNode, InvalidationType invalidationType = AlwaysInvalidate)142 DynamicSubtreeNodeList(PassRefPtr<Node> node, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode) 147 143 : DynamicNodeList(node, rootType, invalidationType) 148 { } 144 { 145 document()->registerDynamicSubtreeNodeList(this, rootType, invalidationType); 146 } 149 147 150 148 private: -
trunk/Source/WebCore/dom/MicroDataItemList.cpp
r121149 r122498 46 46 47 47 MicroDataItemList::MicroDataItemList(PassRefPtr<Node> rootNode, const String& typeNames) 48 : DynamicSubtreeNodeList(rootNode )48 : DynamicSubtreeNodeList(rootNode, InvalidateOnItemAttrChange) 49 49 , m_typeNames(typeNames, document()->inQuirksMode()) 50 50 , m_originalTypeNames(typeNames) -
trunk/Source/WebCore/dom/NameNodeList.cpp
r121003 r122498 34 34 35 35 NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name) 36 : DynamicSubtreeNodeList(rootNode )36 : DynamicSubtreeNodeList(rootNode, InvalidateOnNameAttrChange) 37 37 , m_name(name) 38 38 { -
trunk/Source/WebCore/dom/Node.cpp
r122159 r122498 490 490 { 491 491 ASSERT(hasRareData()); 492 if (treeScope() && rareData()->nodeLists())493 treeScope()->removeNodeListCache();494 492 495 493 #if ENABLE(MUTATION_OBSERVERS) … … 966 964 return; 967 965 968 // FIXME: Move the list of attributes each NodeList type cares about to be a static on the 969 // appropriate NodeList class. Then use those lists here and in invalidateCachesThatDependOnAttributes 970 // to only invalidate the cache types that depend on the attribute that changed. 971 // FIXME: Keep track of when we have no caches of a given type so that we can avoid the for-loop 972 // below even if a related attribute changed (e.g. if we have no RadioNodeLists, we don't need 973 // to invalidate any caches when id attributes change.) 974 if (attrName != classAttr 975 #if ENABLE(MICRODATA) 976 && attrName != itemscopeAttr 977 && attrName != itempropAttr 978 && attrName != itemtypeAttr 979 #endif 980 && attrName != nameAttr 981 && attrName != forAttr 982 && (attrName != idAttr || !attributeOwnerElement->isFormControlElement())) 966 if (!document()->shouldInvalidateDynamicSubtreeNodeList(&attrName)) 983 967 return; 984 968 985 969 document()->clearNodeListCaches(); 986 987 if (!treeScope()->hasNodeListCaches())988 return;989 970 990 971 for (Node* node = this; node; node = node->parentNode()) { … … 1005 986 rareData()->clearChildNodeListCache(); 1006 987 988 if (!document()->shouldInvalidateDynamicSubtreeNodeList()) 989 return; 990 1007 991 document()->clearNodeListCaches(); 1008 1009 if (!treeScope()->hasNodeListCaches())1010 return;1011 992 1012 993 for (Node* node = this; node; node = node->parentNode()) { … … 1564 1545 1565 1546 if (document()->isHTMLDocument()) 1566 return ensureRareData()->ensureNodeLists( this)->addCacheWithAtomicName<HTMLTagNodeList>(this, DynamicNodeList::TagNodeListType, localName);1567 return ensureRareData()->ensureNodeLists( this)->addCacheWithAtomicName<TagNodeList>(this, DynamicNodeList::TagNodeListType, localName);1547 return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTagNodeList>(this, DynamicNodeList::TagNodeListType, localName); 1548 return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<TagNodeList>(this, DynamicNodeList::TagNodeListType, localName); 1568 1549 } 1569 1550 … … 1576 1557 return getElementsByTagName(localName); 1577 1558 1578 return ensureRareData()->ensureNodeLists( this)->addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);1559 return ensureRareData()->ensureNodeLists()->addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName); 1579 1560 } 1580 1561 1581 1562 PassRefPtr<NodeList> Node::getElementsByName(const String& elementName) 1582 1563 { 1583 return ensureRareData()->ensureNodeLists( this)->addCacheWithAtomicName<NameNodeList>(this, DynamicNodeList::NameNodeListType, elementName);1564 return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<NameNodeList>(this, DynamicNodeList::NameNodeListType, elementName); 1584 1565 } 1585 1566 1586 1567 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames) 1587 1568 { 1588 return ensureRareData()->ensureNodeLists( this)->addCacheWithName<ClassNodeList>(this, DynamicNodeList::ClassNodeListType, classNames);1569 return ensureRareData()->ensureNodeLists()->addCacheWithName<ClassNodeList>(this, DynamicNodeList::ClassNodeListType, classNames); 1589 1570 } 1590 1571 … … 1592 1573 { 1593 1574 ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag)); 1594 return ensureRareData()->ensureNodeLists( this)->addCacheWithAtomicName<RadioNodeList>(this, DynamicNodeList::RadioNodeListType, name);1575 return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<RadioNodeList>(this, DynamicNodeList::RadioNodeListType, name); 1595 1576 } 1596 1577 … … 2781 2762 #endif 2782 2763 2783 void NodeRareData::createNodeLists(Node* node) 2784 { 2785 ASSERT(node); 2764 void NodeRareData::createNodeLists() 2765 { 2786 2766 setNodeLists(NodeListsNodeData::create()); 2787 if (TreeScope* treeScope = node->treeScope())2788 treeScope->addNodeListCache();2789 2767 } 2790 2768 -
trunk/Source/WebCore/dom/NodeRareData.h
r122159 r122498 130 130 } 131 131 132 void adoptTreeScope( TreeScope* oldTreeScope, TreeScope* newTreeScope,Document* oldDocument, Document* newDocument)132 void adoptTreeScope(Document* oldDocument, Document* newDocument) 133 133 { 134 134 invalidateCaches(); … … 139 139 DynamicSubtreeNodeList* list = it->second; 140 140 if (list->isRootedAtDocument()) { 141 oldDocument->unregisterDynamicSubtreeNodeList(list );142 newDocument->registerDynamicSubtreeNodeList(list );141 oldDocument->unregisterDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 142 newDocument->registerDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 143 143 } 144 144 } … … 148 148 DynamicSubtreeNodeList* list = it->second; 149 149 if (list->isRootedAtDocument()) { 150 oldDocument->unregisterDynamicSubtreeNodeList(list );151 newDocument->registerDynamicSubtreeNodeList(list );150 oldDocument->unregisterDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 151 newDocument->registerDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 152 152 } 153 153 } 154 155 TagNodeListCacheNS::const_iterator tagEnd = m_tagNodeListCacheNS.end(); 156 for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagEnd; ++it) { 157 DynamicSubtreeNodeList* list = it->second; 158 ASSERT(!list->isRootedAtDocument()); 159 oldDocument->unregisterDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 160 newDocument->registerDynamicSubtreeNodeList(list, list->rootType(), list->invalidationType()); 161 } 154 162 } 155 156 if (oldTreeScope)157 oldTreeScope->removeNodeListCache();158 newTreeScope->addNodeListCache();159 163 } 160 164 … … 216 220 void setNodeLists(PassOwnPtr<NodeListsNodeData> lists) { m_nodeLists = lists; } 217 221 NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); } 218 NodeListsNodeData* ensureNodeLists( Node* node)222 NodeListsNodeData* ensureNodeLists() 219 223 { 220 224 if (!m_nodeLists) 221 createNodeLists( node);225 createNodeLists(); 222 226 return m_nodeLists.get(); 223 227 } … … 341 345 342 346 private: 343 void createNodeLists( Node*);347 void createNodeLists(); 344 348 345 349 TreeScope* m_treeScope; -
trunk/Source/WebCore/dom/TagNodeList.cpp
r121003 r122498 32 32 33 33 TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName) 34 : DynamicSubtreeNodeList(rootNode, RootedAtNode, DoNotInvalidateOnAttributeChange)34 : DynamicSubtreeNodeList(rootNode, DoNotInvalidateOnAttributeChanges) 35 35 , m_namespaceURI(namespaceURI) 36 36 , m_localName(localName) -
trunk/Source/WebCore/dom/TreeScope.cpp
r121126 r122498 55 55 : m_rootNode(rootNode) 56 56 , m_parentTreeScope(0) 57 , m_numNodeListCaches(0)58 57 { 59 58 ASSERT(rootNode); -
trunk/Source/WebCore/dom/TreeScope.h
r121126 r122498 62 62 HTMLMapElement* getImageMap(const String& url) const; 63 63 64 void addNodeListCache() { ++m_numNodeListCaches; }65 void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }66 bool hasNodeListCaches() const { return m_numNodeListCaches; }67 68 64 DOMSelection* getSelection() const; 69 65 … … 96 92 DocumentOrderedMap m_imageMapsByName; 97 93 98 unsigned m_numNodeListCaches;99 100 94 mutable RefPtr<DOMSelection> m_selection; 101 95 }; -
trunk/Source/WebCore/dom/TreeScopeAdopter.cpp
r121174 r122498 50 50 NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope); 51 51 if (rareData && rareData->nodeLists()) 52 rareData->nodeLists()->adoptTreeScope( m_oldScope, m_newScope,oldDocument, newDocument);52 rareData->nodeLists()->adoptTreeScope(oldDocument, newDocument); 53 53 54 54 if (willMoveToNewDocument) -
trunk/Source/WebCore/html/HTMLCollection.h
r122353 r122498 41 41 public: 42 42 HTMLCollectionCacheBase(CollectionType type, bool includeChildren) 43 : DynamicNodeListCacheBase( RootedAtNode, AlwaysInvalidate) // These two flags are never used43 : DynamicNodeListCacheBase(NodeListIsRootedAtNode, DoNotInvalidateOnAttributeChanges) // These two flags are never used 44 44 , m_cachedElementsArrayOffset(0) 45 45 , m_cacheTreeVersion(0) -
trunk/Source/WebCore/html/HTMLPropertiesCollection.cpp
r122353 r122498 154 154 } 155 155 156 void HTMLPropertiesCollection::cacheFirstItem() const157 {158 for (unsigned i = 0; i < m_itemRefElements.size(); ++i) {159 if (HTMLElement* element = itemAfter(m_itemRefElements[i], 0))160 return setItemCache(element, 0, i);161 }162 setItemCache(0, 0, 0);163 }164 165 156 void HTMLPropertiesCollection::updateNameCache() const 166 157 { -
trunk/Source/WebCore/html/LabelableElement.cpp
r121335 r122498 48 48 return 0; 49 49 50 return ensureRareData()->ensureNodeLists( this)->addCacheWithAtomicName<LabelsNodeList>(this, DynamicNodeList::LabelsNodeListType, starAtom);50 return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<LabelsNodeList>(this, DynamicNodeList::LabelsNodeListType, starAtom); 51 51 } 52 52 -
trunk/Source/WebCore/html/LabelsNodeList.cpp
r121126 r122498 35 35 36 36 LabelsNodeList::LabelsNodeList(Node* forNode) 37 : DynamicSubtreeNodeList(forNode, RootedAtDocument)37 : DynamicSubtreeNodeList(forNode, InvalidateOnForAttrChange, NodeListIsRootedAtDocument) 38 38 { 39 document()->registerDynamicSubtreeNodeList(this);40 39 } 41 40 … … 43 42 { 44 43 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::LabelsNodeListType, starAtom); 45 document()->unregisterDynamicSubtreeNodeList(this);46 44 } 47 45 -
trunk/Source/WebCore/html/RadioNodeList.cpp
r121126 r122498 39 39 40 40 RadioNodeList::RadioNodeList(Node* rootNode, const AtomicString& name) 41 : DynamicSubtreeNodeList(rootNode, rootNode->hasTagName(formTag) ? RootedAtDocument :RootedAtNode)41 : DynamicSubtreeNodeList(rootNode, InvalidateOnIdNameForAttrChange, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode) 42 42 , m_name(name) 43 43 { 44 document()->registerDynamicSubtreeNodeList(this);45 44 } 46 45 … … 48 47 { 49 48 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::RadioNodeListType, m_name); 50 document()->unregisterDynamicSubtreeNodeList(this);51 49 } 52 50
Note: See TracChangeset
for help on using the changeset viewer.