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

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

Issue 280123002: Oilpan: move LiveNodeList collections to the heap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Make NodeListsNodeData::m_owner a strong ref Created 6 years, 7 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
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 24 matching lines...) Expand all
35 #include "wtf/PassOwnPtr.h" 35 #include "wtf/PassOwnPtr.h"
36 #include "wtf/text/AtomicString.h" 36 #include "wtf/text/AtomicString.h"
37 #include "wtf/text/StringHash.h" 37 #include "wtf/text/StringHash.h"
38 38
39 namespace WebCore { 39 namespace WebCore {
40 40
41 class LabelsNodeList; 41 class LabelsNodeList;
42 class RadioNodeList; 42 class RadioNodeList;
43 class TreeScope; 43 class TreeScope;
44 44
45 class NodeListsNodeData { 45 class NodeListsNodeData FINAL : public NoBaseWillBeGarbageCollectedFinalized<Nod eListsNodeData> {
46 WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED; 46 WTF_MAKE_NONCOPYABLE(NodeListsNodeData);
47 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
47 public: 48 public:
48 void clearChildNodeListCache() 49 void clearChildNodeListCache()
49 { 50 {
50 if (m_childNodeList && m_childNodeList->isChildNodeList()) 51 if (m_childNodeList && m_childNodeList->isChildNodeList())
51 toChildNodeList(m_childNodeList)->invalidateCache(); 52 toChildNodeList(m_childNodeList)->invalidateCache();
52 } 53 }
53 54
54 PassRefPtr<ChildNodeList> ensureChildNodeList(ContainerNode& node) 55 PassRefPtrWillBeRawPtr<ChildNodeList> ensureChildNodeList(ContainerNode& nod e)
55 { 56 {
56 if (m_childNodeList) 57 if (m_childNodeList)
57 return toChildNodeList(m_childNodeList); 58 return toChildNodeList(m_childNodeList);
58 RefPtr<ChildNodeList> list = ChildNodeList::create(node); 59 RefPtrWillBeRawPtr<ChildNodeList> list = ChildNodeList::create(node);
59 m_childNodeList = list.get(); 60 m_childNodeList = list.get();
60 return list.release(); 61 return list.release();
61 } 62 }
62 63
63 PassRefPtr<EmptyNodeList> ensureEmptyChildNodeList(Node& node) 64 PassRefPtrWillBeRawPtr<EmptyNodeList> ensureEmptyChildNodeList(Node& node)
64 { 65 {
65 if (m_childNodeList) 66 if (m_childNodeList)
66 return toEmptyNodeList(m_childNodeList); 67 return toEmptyNodeList(m_childNodeList);
67 RefPtr<EmptyNodeList> list = EmptyNodeList::create(node); 68 RefPtrWillBeRawPtr<EmptyNodeList> list = EmptyNodeList::create(node);
68 m_childNodeList = list.get(); 69 m_childNodeList = list.get();
69 return list.release(); 70 return list.release();
70 } 71 }
71 72
73 #if !ENABLE(OILPAN)
72 void removeChildNodeList(ChildNodeList* list) 74 void removeChildNodeList(ChildNodeList* list)
73 { 75 {
74 ASSERT(m_childNodeList == list); 76 ASSERT(m_childNodeList == list);
75 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 77 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
76 return; 78 return;
77 m_childNodeList = 0; 79 m_childNodeList = nullptr;
78 } 80 }
79 81
80 void removeEmptyChildNodeList(EmptyNodeList* list) 82 void removeEmptyChildNodeList(EmptyNodeList* list)
81 { 83 {
82 ASSERT(m_childNodeList == list); 84 ASSERT(m_childNodeList == list);
83 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 85 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
84 return; 86 return;
85 m_childNodeList = 0; 87 m_childNodeList = nullptr;
86 } 88 }
89 #endif
87 90
88 struct NodeListAtomicCacheMapEntryHash { 91 struct NodeListAtomicCacheMapEntryHash {
89 static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry) 92 static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry)
90 { 93 {
91 return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.fi rst; 94 return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.fi rst;
92 } 95 }
93 static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; } 96 static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; }
94 static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl *>::Hash::safeToCompareToEmptyOrDeleted; 97 static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl *>::Hash::safeToCompareToEmptyOrDeleted;
95 }; 98 };
96 99
97 typedef HashMap<std::pair<unsigned char, StringImpl*>, LiveNodeListBase*, No deListAtomicCacheMapEntryHash> NodeListAtomicNameCacheMap; 100 // Oilpan: keep a weak reference to the collection objects.
98 typedef HashMap<QualifiedName, TagCollection*> TagCollectionCacheNS; 101 // Explicit object unregistration in a non-Oilpan setting
102 // on object destruction is replaced by the garbage collector
103 // clearing out their weak reference.
104 typedef WillBeHeapHashMap<std::pair<unsigned char, StringImpl*>, RawPtrWillB eWeakMember<LiveNodeListBase>, NodeListAtomicCacheMapEntryHash> NodeListAtomicNa meCacheMap;
105 typedef WillBeHeapHashMap<QualifiedName, RawPtrWillBeWeakMember<TagCollectio n> > TagCollectionCacheNS;
99 106
100 template<typename T> 107 template<typename T>
101 PassRefPtr<T> addCache(ContainerNode& node, CollectionType collectionType, c onst AtomicString& name) 108 PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType colle ctionType, const AtomicString& name)
102 { 109 {
103 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, name), 0); 110 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, name), nullptr);
104 if (!result.isNewEntry) 111 if (!result.isNewEntry)
105 return static_cast<T*>(result.storedValue->value); 112 return static_cast<T*>(result.storedValue->value.get());
106 113
107 RefPtr<T> list = T::create(node, collectionType, name); 114 RefPtrWillBeRawPtr<T> list = T::create(node, collectionType, name);
108 result.storedValue->value = list.get(); 115 result.storedValue->value = list.get();
109 return list.release(); 116 return list.release();
110 } 117 }
111 118
112 template<typename T> 119 template<typename T>
113 PassRefPtr<T> addCache(ContainerNode& node, CollectionType collectionType) 120 PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType colle ctionType)
114 { 121 {
115 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, starAtom), 0); 122 NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(na medNodeListKey(collectionType, starAtom), nullptr);
116 if (!result.isNewEntry) 123 if (!result.isNewEntry)
117 return static_cast<T*>(result.storedValue->value); 124 return static_cast<T*>(result.storedValue->value.get());
118 125
119 RefPtr<T> list = T::create(node, collectionType); 126 RefPtrWillBeRawPtr<T> list = T::create(node, collectionType);
120 result.storedValue->value = list.get(); 127 result.storedValue->value = list.get();
121 return list.release(); 128 return list.release();
122 } 129 }
123 130
124 template<typename T> 131 template<typename T>
125 T* cached(CollectionType collectionType) 132 T* cached(CollectionType collectionType)
126 { 133 {
134 #if ENABLE(OILPAN)
135 // FIXME: Oilpan: unify, if possible. The lookup resolves to a T& with O ilpan,
136 // whereas non-Oilpan resolves to RawPtr<T>.
127 return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectio nType, starAtom))); 137 return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectio nType, starAtom)));
138 #else
139 return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectio nType, starAtom)).get());
140 #endif
128 } 141 }
129 142
130 PassRefPtr<TagCollection> addCache(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName) 143 PassRefPtrWillBeRawPtr<TagCollection> addCache(ContainerNode& node, const At omicString& namespaceURI, const AtomicString& localName)
131 { 144 {
132 QualifiedName name(nullAtom, localName, namespaceURI); 145 QualifiedName name(nullAtom, localName, namespaceURI);
133 TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name , 0); 146 TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name , nullptr);
134 if (!result.isNewEntry) 147 if (!result.isNewEntry)
135 return result.storedValue->value; 148 return result.storedValue->value;
136 149
137 RefPtr<TagCollection> list = TagCollection::create(node, namespaceURI, l ocalName); 150 RefPtrWillBeRawPtr<TagCollection> list = TagCollection::create(node, nam espaceURI, localName);
138 result.storedValue->value = list.get(); 151 result.storedValue->value = list.get();
139 return list.release(); 152 return list.release();
140 } 153 }
141 154
155 #if !ENABLE(OILPAN)
142 void removeCache(LiveNodeListBase* list, CollectionType collectionType, cons t AtomicString& name = starAtom) 156 void removeCache(LiveNodeListBase* list, CollectionType collectionType, cons t AtomicString& name = starAtom)
143 { 157 {
144 ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, n ame))); 158 ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, n ame)));
145 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 159 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
146 return; 160 return;
147 m_atomicNameCaches.remove(namedNodeListKey(collectionType, name)); 161 m_atomicNameCaches.remove(namedNodeListKey(collectionType, name));
148 } 162 }
149 163
150 void removeCache(LiveNodeListBase* list, const AtomicString& namespaceURI, c onst AtomicString& localName) 164 void removeCache(LiveNodeListBase* list, const AtomicString& namespaceURI, c onst AtomicString& localName)
151 { 165 {
152 QualifiedName name(nullAtom, localName, namespaceURI); 166 QualifiedName name(nullAtom, localName, namespaceURI);
153 ASSERT(list == m_tagCollectionCacheNS.get(name)); 167 ASSERT(list == m_tagCollectionCacheNS.get(name));
154 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de())) 168 if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNo de()))
155 return; 169 return;
156 m_tagCollectionCacheNS.remove(name); 170 m_tagCollectionCacheNS.remove(name);
157 } 171 }
172 #endif
158 173
174 #if ENABLE(OILPAN)
175 static RawPtr<NodeListsNodeData> create(NodeRareData* owner)
176 {
177 return new NodeListsNodeData(owner);
178 }
179 #else
159 static PassOwnPtr<NodeListsNodeData> create() 180 static PassOwnPtr<NodeListsNodeData> create()
160 { 181 {
161 return adoptPtr(new NodeListsNodeData); 182 return adoptPtr(new NodeListsNodeData);
162 } 183 }
184 #endif
163 185
164 void invalidateCaches(const QualifiedName* attrName = 0); 186 void invalidateCaches(const QualifiedName* attrName = 0);
165 bool isEmpty() const 187 bool isEmpty() const
166 { 188 {
167 return m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty(); 189 return m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty();
168 } 190 }
169 191
170 void adoptTreeScope() 192 void adoptTreeScope()
171 { 193 {
172 invalidateCaches(); 194 invalidateCaches();
(...skipping 10 matching lines...) Expand all
183 } 205 }
184 206
185 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end (); 207 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end ();
186 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.be gin(); it != tagEnd; ++it) { 208 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.be gin(); it != tagEnd; ++it) {
187 LiveNodeListBase* list = it->value; 209 LiveNodeListBase* list = it->value;
188 ASSERT(!list->isRootedAtDocument()); 210 ASSERT(!list->isRootedAtDocument());
189 list->didMoveToDocument(oldDocument, newDocument); 211 list->didMoveToDocument(oldDocument, newDocument);
190 } 212 }
191 } 213 }
192 214
215 #if ENABLE(OILPAN)
216 void clearWeakMembers(Visitor*);
217 #endif
218 void trace(Visitor*);
219
193 private: 220 private:
221 #if ENABLE(OILPAN)
222 explicit NodeListsNodeData(NodeRareData* owner)
223 #else
194 NodeListsNodeData() 224 NodeListsNodeData()
195 : m_childNodeList(0) 225 #endif
226 : m_childNodeList(nullptr)
227 #if ENABLE(OILPAN)
228 , m_owner(owner)
229 #endif
196 { } 230 { }
197 231
198 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name) 232 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name)
199 { 233 {
200 // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList 234 // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList
201 // is reponsible for removing itself from the cache on deletion. 235 // is reponsible for removing itself from the cache on deletion.
202 return std::pair<unsigned char, StringImpl*>(type, name.impl()); 236 return std::pair<unsigned char, StringImpl*>(type, name.impl());
203 } 237 }
204 238
239 #if !ENABLE(OILPAN)
205 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&); 240 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&);
241 #endif
206 242
207 // Can be a ChildNodeList or an EmptyNodeList. 243 // Can be a ChildNodeList or an EmptyNodeList.
208 NodeList* m_childNodeList; 244 RawPtrWillBeWeakMember<NodeList> m_childNodeList;
209 NodeListAtomicNameCacheMap m_atomicNameCaches; 245 NodeListAtomicNameCacheMap m_atomicNameCaches;
210 TagCollectionCacheNS m_tagCollectionCacheNS; 246 TagCollectionCacheNS m_tagCollectionCacheNS;
247 #if ENABLE(OILPAN)
248 Member<NodeRareData> m_owner;
249 #endif
211 }; 250 };
212 251
213 class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeM utationObserverData> { 252 class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeM utationObserverData> {
214 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); 253 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData);
215 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 254 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
216 public: 255 public:
217 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry ; 256 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry ;
218 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transie ntRegistry; 257 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transie ntRegistry;
219 258
220 static PassOwnPtrWillBeRawPtr<NodeMutationObserverData> create() 259 static PassOwnPtrWillBeRawPtr<NodeMutationObserverData> create()
(...skipping 17 matching lines...) Expand all
238 public: 277 public:
239 static NodeRareData* create(RenderObject* renderer) 278 static NodeRareData* create(RenderObject* renderer)
240 { 279 {
241 return new NodeRareData(renderer); 280 return new NodeRareData(renderer);
242 } 281 }
243 282
244 void clearNodeLists() { m_nodeLists.clear(); } 283 void clearNodeLists() { m_nodeLists.clear(); }
245 NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); } 284 NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
246 NodeListsNodeData& ensureNodeLists() 285 NodeListsNodeData& ensureNodeLists()
247 { 286 {
248 if (!m_nodeLists) 287 if (!m_nodeLists) {
288 #if ENABLE(OILPAN)
289 m_nodeLists = NodeListsNodeData::create(this);
290 #else
249 m_nodeLists = NodeListsNodeData::create(); 291 m_nodeLists = NodeListsNodeData::create();
292 #endif
293 }
250 return *m_nodeLists; 294 return *m_nodeLists;
251 } 295 }
252 296
253 NodeMutationObserverData* mutationObserverData() { return m_mutationObserver Data.get(); } 297 NodeMutationObserverData* mutationObserverData() { return m_mutationObserver Data.get(); }
254 NodeMutationObserverData& ensureMutationObserverData() 298 NodeMutationObserverData& ensureMutationObserverData()
255 { 299 {
256 if (!m_mutationObserverData) 300 if (!m_mutationObserverData)
257 m_mutationObserverData = NodeMutationObserverData::create(); 301 m_mutationObserverData = NodeMutationObserverData::create();
258 return *m_mutationObserverData; 302 return *m_mutationObserverData;
259 } 303 }
(...skipping 22 matching lines...) Expand all
282 enum { 326 enum {
283 ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames. 327 ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
284 }; 328 };
285 329
286 void trace(Visitor*); 330 void trace(Visitor*);
287 331
288 void traceAfterDispatch(Visitor*); 332 void traceAfterDispatch(Visitor*);
289 void finalizeGarbageCollectedObject(); 333 void finalizeGarbageCollectedObject();
290 334
291 protected: 335 protected:
292 NodeRareData(RenderObject* renderer) 336 explicit NodeRareData(RenderObject* renderer)
293 : NodeRareDataBase(renderer) 337 : NodeRareDataBase(renderer)
294 , m_connectedFrameCount(0) 338 , m_connectedFrameCount(0)
295 , m_elementFlags(0) 339 , m_elementFlags(0)
296 , m_restyleFlags(0) 340 , m_restyleFlags(0)
297 , m_isElementRareData(false) 341 , m_isElementRareData(false)
298 { } 342 { }
299 343
300 private: 344 private:
301 OwnPtr<NodeListsNodeData> m_nodeLists; 345 OwnPtrWillBeMember<NodeListsNodeData> m_nodeLists;
302 OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData; 346 OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
303 347
304 unsigned m_connectedFrameCount : ConnectedFrameCountBits; 348 unsigned m_connectedFrameCount : ConnectedFrameCountBits;
305 unsigned m_elementFlags : NumberOfElementFlags; 349 unsigned m_elementFlags : NumberOfElementFlags;
306 unsigned m_restyleFlags : NumberOfDynamicRestyleFlags; 350 unsigned m_restyleFlags : NumberOfDynamicRestyleFlags;
307 protected: 351 protected:
308 unsigned m_isElementRareData : 1; 352 unsigned m_isElementRareData : 1;
309 }; 353 };
310 354
355 #if !ENABLE(OILPAN)
311 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node& ownerNode) 356 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node& ownerNode)
312 { 357 {
313 ASSERT(ownerNode.nodeLists() == this); 358 ASSERT(ownerNode.nodeLists() == this);
314 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionC acheNS.size() != 1) 359 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionC acheNS.size() != 1)
315 return false; 360 return false;
316 ownerNode.clearNodeLists(); 361 ownerNode.clearNodeLists();
317 return true; 362 return true;
318 } 363 }
364 #endif
319 365
320 } // namespace WebCore 366 } // namespace WebCore
321 367
322 #endif // NodeRareData_h 368 #endif // NodeRareData_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698