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

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: Pre-emptively GC a long runnning test 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
159 static PassOwnPtr<NodeListsNodeData> create() 174 static PassOwnPtrWillBeRawPtr<NodeListsNodeData> create()
160 { 175 {
161 return adoptPtr(new NodeListsNodeData); 176 return adoptPtrWillBeNoop(new NodeListsNodeData);
162 } 177 }
163 178
164 void invalidateCaches(const QualifiedName* attrName = 0); 179 void invalidateCaches(const QualifiedName* attrName = 0);
165 bool isEmpty() const 180 bool isEmpty() const
166 { 181 {
167 return m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty(); 182 return m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty();
168 } 183 }
169 184
170 void adoptTreeScope() 185 void adoptTreeScope()
171 { 186 {
(...skipping 11 matching lines...) Expand all
183 } 198 }
184 199
185 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end (); 200 TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end ();
186 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.be gin(); it != tagEnd; ++it) { 201 for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.be gin(); it != tagEnd; ++it) {
187 LiveNodeListBase* list = it->value; 202 LiveNodeListBase* list = it->value;
188 ASSERT(!list->isRootedAtDocument()); 203 ASSERT(!list->isRootedAtDocument());
189 list->didMoveToDocument(oldDocument, newDocument); 204 list->didMoveToDocument(oldDocument, newDocument);
190 } 205 }
191 } 206 }
192 207
208 void trace(Visitor* visitor)
209 {
210 visitor->trace(m_childNodeList);
211 visitor->trace(m_atomicNameCaches);
212 visitor->trace(m_tagCollectionCacheNS);
213 }
214
193 private: 215 private:
194 NodeListsNodeData() 216 NodeListsNodeData()
195 : m_childNodeList(0) 217 : m_childNodeList(nullptr)
196 { } 218 { }
197 219
198 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name) 220 std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name)
199 { 221 {
200 // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList 222 // 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. 223 // is reponsible for removing itself from the cache on deletion.
202 return std::pair<unsigned char, StringImpl*>(type, name.impl()); 224 return std::pair<unsigned char, StringImpl*>(type, name.impl());
203 } 225 }
204 226
227 #if !ENABLE(OILPAN)
205 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&); 228 bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&);
229 #endif
206 230
207 // Can be a ChildNodeList or an EmptyNodeList. 231 // Can be a ChildNodeList or an EmptyNodeList.
208 NodeList* m_childNodeList; 232 RawPtrWillBeMember<NodeList> m_childNodeList;
209 NodeListAtomicNameCacheMap m_atomicNameCaches; 233 NodeListAtomicNameCacheMap m_atomicNameCaches;
210 TagCollectionCacheNS m_tagCollectionCacheNS; 234 TagCollectionCacheNS m_tagCollectionCacheNS;
211 }; 235 };
212 236
213 class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeM utationObserverData> { 237 class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeM utationObserverData> {
214 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); 238 WTF_MAKE_NONCOPYABLE(NodeMutationObserverData);
215 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 239 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
216 public: 240 public:
217 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry ; 241 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry ;
218 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transie ntRegistry; 242 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transie ntRegistry;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 enum { 306 enum {
283 ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames. 307 ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
284 }; 308 };
285 309
286 void trace(Visitor*); 310 void trace(Visitor*);
287 311
288 void traceAfterDispatch(Visitor*); 312 void traceAfterDispatch(Visitor*);
289 void finalizeGarbageCollectedObject(); 313 void finalizeGarbageCollectedObject();
290 314
291 protected: 315 protected:
292 NodeRareData(RenderObject* renderer) 316 NodeRareData(RenderObject* renderer)
haraken 2014/05/12 12:04:13 Add explicit.
sof 2014/05/15 22:15:57 Done.
293 : NodeRareDataBase(renderer) 317 : NodeRareDataBase(renderer)
294 , m_connectedFrameCount(0) 318 , m_connectedFrameCount(0)
295 , m_elementFlags(0) 319 , m_elementFlags(0)
296 , m_restyleFlags(0) 320 , m_restyleFlags(0)
297 , m_isElementRareData(false) 321 , m_isElementRareData(false)
298 { } 322 { }
299 323
300 private: 324 private:
301 OwnPtr<NodeListsNodeData> m_nodeLists; 325 OwnPtrWillBeMember<NodeListsNodeData> m_nodeLists;
302 OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData; 326 OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
303 327
304 unsigned m_connectedFrameCount : ConnectedFrameCountBits; 328 unsigned m_connectedFrameCount : ConnectedFrameCountBits;
305 unsigned m_elementFlags : NumberOfElementFlags; 329 unsigned m_elementFlags : NumberOfElementFlags;
306 unsigned m_restyleFlags : NumberOfDynamicRestyleFlags; 330 unsigned m_restyleFlags : NumberOfDynamicRestyleFlags;
307 protected: 331 protected:
308 unsigned m_isElementRareData : 1; 332 unsigned m_isElementRareData : 1;
309 }; 333 };
310 334
335 #if !ENABLE(OILPAN)
311 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node& ownerNode) 336 inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas tList(Node& ownerNode)
312 { 337 {
313 ASSERT(ownerNode.nodeLists() == this); 338 ASSERT(ownerNode.nodeLists() == this);
314 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionC acheNS.size() != 1) 339 if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionC acheNS.size() != 1)
315 return false; 340 return false;
316 ownerNode.clearNodeLists(); 341 ownerNode.clearNodeLists();
haraken 2014/05/12 12:04:13 When the last cached list is removed from the Node
317 return true; 342 return true;
318 } 343 }
344 #endif
319 345
320 } // namespace WebCore 346 } // namespace WebCore
321 347
322 #endif // NodeRareData_h 348 #endif // NodeRareData_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698