OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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; |
haraken
2014/05/19 09:19:50
Shouldn't this be a weak member? I think NodeRareD
sof
2014/05/19 21:36:45
Good catch, do want to refer to the NodeList weakl
| |
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 Loading... | |
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 explicit NodeRareData(RenderObject* renderer) |
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/19 09:19:50
I still have a question on this. (Sorry if you've
sof
2014/05/19 21:36:45
Thanks for persisting in getting an answer :) I ha
| |
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 |
OLD | NEW |