Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: Source/core/dom/NodeRareData.h

Issue 146973007: Kill NodeListNameCacheMap cache in NodeListsNodeData (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/dom/Node.cpp ('k') | Source/core/dom/NodeRareData.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 David Smith <catfish.man@gmail.com> 3 * Copyright (C) 2008 David Smith <catfish.man@gmail.com>
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 77 }
78 78
79 void removeEmptyChildNodeList(EmptyNodeList* list) 79 void removeEmptyChildNodeList(EmptyNodeList* list)
80 { 80 {
81 ASSERT(m_childNodeList == list); 81 ASSERT(m_childNodeList == list);
82 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 82 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
83 return; 83 return;
84 m_childNodeList = 0; 84 m_childNodeList = 0;
85 } 85 }
86 86
87 template <typename StringType>
88 struct NodeListCacheMapEntryHash {
89 static unsigned hash(const std::pair<unsigned char, StringType>& entry)
90 {
91 return DefaultHash<StringType>::Hash::hash(entry.second) + entry.fir st;
92 }
93 static bool equal(const std::pair<unsigned char, StringType>& a, const s td::pair<unsigned char, StringType>& b) { return a == b; }
94 static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringType >::Hash::safeToCompareToEmptyOrDeleted;
95 };
96
97 struct NodeListAtomicCacheMapEntryHash { 87 struct NodeListAtomicCacheMapEntryHash {
98 static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry) 88 static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry)
99 { 89 {
100 return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.fi rst; 90 return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.fi rst;
101 } 91 }
102 static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; } 92 static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; }
103 static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl *>::Hash::safeToCompareToEmptyOrDeleted; 93 static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl *>::Hash::safeToCompareToEmptyOrDeleted;
104 }; 94 };
105 95
106 typedef HashMap<std::pair<unsigned char, StringImpl*>, LiveNodeListBase*, No deListAtomicCacheMapEntryHash> NodeListAtomicNameCacheMap; 96 typedef HashMap<std::pair<unsigned char, StringImpl*>, LiveNodeListBase*, No deListAtomicCacheMapEntryHash> NodeListAtomicNameCacheMap;
107 typedef HashMap<std::pair<unsigned char, String>, LiveNodeListBase*, NodeLis tCacheMapEntryHash<String> > NodeListNameCacheMap;
108 typedef HashMap<QualifiedName, TagCollection*> TagCollectionCacheNS; 97 typedef HashMap<QualifiedName, TagCollection*> TagCollectionCacheNS;
109 98
110 template<typename T> 99 template<typename T>
111 PassRefPtr<T> addCacheWithAtomicName(ContainerNode* node, CollectionType col lectionType, const AtomicString& name) 100 PassRefPtr<T> addCacheWithAtomicName(ContainerNode* node, CollectionType col lectionType, const AtomicString& name)
112 { 101 {
113 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, name), 0); 102 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, name), 0);
114 if (!result.isNewEntry) 103 if (!result.isNewEntry)
115 return static_cast<T*>(result.iterator->value); 104 return static_cast<T*>(result.iterator->value);
116 105
117 RefPtr<T> list = T::create(node, collectionType, name); 106 RefPtr<T> list = T::create(node, collectionType, name);
(...skipping 13 matching lines...) Expand all
131 result.iterator->value = list.get(); 120 result.iterator->value = list.get();
132 return list.release(); 121 return list.release();
133 } 122 }
134 123
135 template<typename T> 124 template<typename T>
136 T* cacheWithAtomicName(CollectionType collectionType) 125 T* cacheWithAtomicName(CollectionType collectionType)
137 { 126 {
138 return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectio nType, starAtom))); 127 return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectio nType, starAtom)));
139 } 128 }
140 129
141 template<typename T>
142 PassRefPtr<T> addCacheWithName(Node* node, CollectionType collectionType, co nst String& name)
143 {
144 NodeListNameCacheMap::AddResult result = m_nameCaches.add(namedNodeListK ey(collectionType, name), 0);
145 if (!result.isNewEntry)
146 return static_cast<T*>(result.iterator->value);
147
148 RefPtr<T> list = T::create(node, name);
149 result.iterator->value = list.get();
150 return list.release();
151 }
152
153 PassRefPtr<TagCollection> addCacheWithQualifiedName(ContainerNode* node, con st AtomicString& namespaceURI, const AtomicString& localName) 130 PassRefPtr<TagCollection> addCacheWithQualifiedName(ContainerNode* node, con st AtomicString& namespaceURI, const AtomicString& localName)
154 { 131 {
155 QualifiedName name(nullAtom, localName, namespaceURI); 132 QualifiedName name(nullAtom, localName, namespaceURI);
156 TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name , 0); 133 TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name , 0);
157 if (!result.isNewEntry) 134 if (!result.isNewEntry)
158 return result.iterator->value; 135 return result.iterator->value;
159 136
160 RefPtr<TagCollection> list = TagCollection::create(node, namespaceURI, l ocalName); 137 RefPtr<TagCollection> list = TagCollection::create(node, namespaceURI, l ocalName);
161 result.iterator->value = list.get(); 138 result.iterator->value = list.get();
162 return list.release(); 139 return list.release();
163 } 140 }
164 141
165 void removeCacheWithAtomicName(LiveNodeListBase* list, CollectionType collec tionType, const AtomicString& name = starAtom) 142 void removeCacheWithAtomicName(LiveNodeListBase* list, CollectionType collec tionType, const AtomicString& name = starAtom)
166 { 143 {
167 ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, n ame))); 144 ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, n ame)));
168 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 145 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
169 return; 146 return;
170 m_atomicNameCaches.remove(namedNodeListKey(collectionType, name)); 147 m_atomicNameCaches.remove(namedNodeListKey(collectionType, name));
171 } 148 }
172 149
173 void removeCacheWithName(LiveNodeListBase* list, CollectionType collectionTy pe, const String& name)
174 {
175 ASSERT(list == m_nameCaches.get(namedNodeListKey(collectionType, name))) ;
176 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
177 return;
178 m_nameCaches.remove(namedNodeListKey(collectionType, name));
179 }
180
181 void removeCacheWithQualifiedName(LiveNodeListBase* list, const AtomicString & namespaceURI, const AtomicString& localName) 150 void removeCacheWithQualifiedName(LiveNodeListBase* list, const AtomicString & namespaceURI, const AtomicString& localName)
182 { 151 {
183 QualifiedName name(nullAtom, localName, namespaceURI); 152 QualifiedName name(nullAtom, localName, namespaceURI);
184 ASSERT(list == m_tagCollectionCacheNS.get(name)); 153 ASSERT(list == m_tagCollectionCacheNS.get(name));
185 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 154 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
186 return; 155 return;
187 m_tagCollectionCacheNS.remove(name); 156 m_tagCollectionCacheNS.remove(name);
188 } 157 }
189 158
190 static PassOwnPtr<NodeListsNodeData> create() 159 static PassOwnPtr<NodeListsNodeData> create()
191 { 160 {
192 return adoptPtr(new NodeListsNodeData); 161 return adoptPtr(new NodeListsNodeData);
193 } 162 }
194 163
195 void invalidateCaches(const QualifiedName* attrName = 0); 164 void invalidateCaches(const QualifiedName* attrName = 0);
196 bool isEmpty() const 165 bool isEmpty() const
197 { 166 {
198 return m_atomicNameCaches.isEmpty() && m_nameCaches.isEmpty() && m_tagCo llectionCacheNS.isEmpty(); 167 return m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty();
199 } 168 }
200 169
201 void adoptTreeScope() 170 void adoptTreeScope()
202 { 171 {
203 invalidateCaches(); 172 invalidateCaches();
204 } 173 }
205 174
206 void adoptDocument(Document& oldDocument, Document& newDocument) 175 void adoptDocument(Document& oldDocument, Document& newDocument)
207 { 176 {
208 invalidateCaches(); 177 invalidateCaches();
209 178
210 if (oldDocument != newDocument) { 179 if (oldDocument != newDocument) {
211 NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_at omicNameCaches.end(); 180 NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_at omicNameCaches.end();
212 for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCac hes.begin(); it != atomicNameCacheEnd; ++it) { 181 for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCac hes.begin(); it != atomicNameCacheEnd; ++it) {
213 LiveNodeListBase* list = it->value; 182 LiveNodeListBase* list = it->value;
214 oldDocument.unregisterNodeList(list); 183 oldDocument.unregisterNodeList(list);
215 newDocument.registerNodeList(list); 184 newDocument.registerNodeList(list);
216 } 185 }
217 186
218 NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end ();
219 for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
220 LiveNodeListBase* list = it->value;
221 oldDocument.unregisterNodeList(list);
222 newDocument.registerNodeList(list);
223 }
224
225 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS .end(); 187 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS .end();
226 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheN S.begin(); it != tagEnd; ++it) { 188 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheN S.begin(); it != tagEnd; ++it) {
227 LiveNodeListBase* list = it->value; 189 LiveNodeListBase* list = it->value;
228 ASSERT(!list->isRootedAtDocument()); 190 ASSERT(!list->isRootedAtDocument());
229 oldDocument.unregisterNodeList(list); 191 oldDocument.unregisterNodeList(list);
230 newDocument.registerNodeList(list); 192 newDocument.registerNodeList(list);
231 } 193 }
232 } 194 }
233 } 195 }
234 196
235 private: 197 private:
236 NodeListsNodeData() 198 NodeListsNodeData()
237 : m_childNodeList(0) 199 : m_childNodeList(0)
238 { } 200 { }
239 201
240 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name) 202 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name)
241 { 203 {
242 // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList 204 // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList
243 // is reponsible for removing itself from the cache on deletion. 205 // is reponsible for removing itself from the cache on deletion.
244 return std::pair<unsigned char, StringImpl*>(type, name.impl()); 206 return std::pair<unsigned char, StringImpl*>(type, name.impl());
245 } 207 }
246 208
247 std::pair<unsigned char, String> namedNodeListKey(CollectionType type, const String& name)
248 {
249 return std::pair<unsigned char, String>(type, name);
250 }
251
252 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node*); 209 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node*);
253 210
254 // Can be a ChildNodeList or an EmptyNodeList. 211 // Can be a ChildNodeList or an EmptyNodeList.
255 NodeList* m_childNodeList; 212 NodeList* m_childNodeList;
256 NodeListAtomicNameCacheMap m_atomicNameCaches; 213 NodeListAtomicNameCacheMap m_atomicNameCaches;
257 NodeListNameCacheMap m_nameCaches;
258 TagCollectionCacheNS m_tagCollectionCacheNS; 214 TagCollectionCacheNS m_tagCollectionCacheNS;
259 }; 215 };
260 216
261 class NodeMutationObserverData { 217 class NodeMutationObserverData {
262 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); WTF_MAKE_FAST_ALLOCATED; 218 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); WTF_MAKE_FAST_ALLOCATED;
263 public: 219 public:
264 Vector<OwnPtr<MutationObserverRegistration> > registry; 220 Vector<OwnPtr<MutationObserverRegistration> > registry;
265 HashSet<MutationObserverRegistration*> transientRegistry; 221 HashSet<MutationObserverRegistration*> transientRegistry;
266 222
267 static PassOwnPtr<NodeMutationObserverData> create() { return adoptPtr(new N odeMutationObserverData); } 223 static PassOwnPtr<NodeMutationObserverData> create() { return adoptPtr(new N odeMutationObserverData); }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 unsigned m_connectedFrameCount : 10; // Must fit Page::maxNumberOfFrames. 270 unsigned m_connectedFrameCount : 10; // Must fit Page::maxNumberOfFrames.
315 271
316 OwnPtr<NodeListsNodeData> m_nodeLists; 272 OwnPtr<NodeListsNodeData> m_nodeLists;
317 OwnPtr<NodeMutationObserverData> m_mutationObserverData; 273 OwnPtr<NodeMutationObserverData> m_mutationObserverData;
318 }; 274 };
319 275
320 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node* ownerNode) 276 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node* ownerNode)
321 { 277 {
322 ASSERT(ownerNode); 278 ASSERT(ownerNode);
323 ASSERT(ownerNode->nodeLists() == this); 279 ASSERT(ownerNode->nodeLists() == this);
324 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_nameCaches.siz e() + m_tagCollectionCacheNS.size() != 1) 280 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionC acheNS.size() != 1)
325 return false; 281 return false;
326 ownerNode->clearNodeLists(); 282 ownerNode->clearNodeLists();
327 return true; 283 return true;
328 } 284 }
329 285
330 // Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow 286 // Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
331 COMPILE_ASSERT(Page::maxNumberOfFrames < 1024, Frame_limit_should_fit_in_rare_da ta_count); 287 COMPILE_ASSERT(Page::maxNumberOfFrames < 1024, Frame_limit_should_fit_in_rare_da ta_count);
332 288
333 } // namespace WebCore 289 } // namespace WebCore
334 290
335 #endif // NodeRareData_h 291 #endif // NodeRareData_h
OLDNEW
« no previous file with comments | « Source/core/dom/Node.cpp ('k') | Source/core/dom/NodeRareData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698