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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 static const bool safe_to_compare_to_empty_or_deleted = | 76 static const bool safe_to_compare_to_empty_or_deleted = |
77 DefaultHash<StringImpl*>::Hash::safe_to_compare_to_empty_or_deleted; | 77 DefaultHash<StringImpl*>::Hash::safe_to_compare_to_empty_or_deleted; |
78 }; | 78 }; |
79 | 79 |
80 // Oilpan: keep a weak reference to the collection objects. | 80 // Oilpan: keep a weak reference to the collection objects. |
81 // Object unregistration is handled by GC's weak processing. | 81 // Object unregistration is handled by GC's weak processing. |
82 typedef HeapHashMap<std::pair<unsigned char, StringImpl*>, | 82 typedef HeapHashMap<std::pair<unsigned char, StringImpl*>, |
83 WeakMember<LiveNodeListBase>, | 83 WeakMember<LiveNodeListBase>, |
84 NodeListAtomicCacheMapEntryHash> | 84 NodeListAtomicCacheMapEntryHash> |
85 NodeListAtomicNameCacheMap; | 85 NodeListAtomicNameCacheMap; |
86 typedef HeapHashMap<QualifiedName, WeakMember<TagCollection>> | 86 typedef HeapHashMap<QualifiedName, WeakMember<TagCollectionNS>> |
87 TagCollectionCacheNS; | 87 TagCollectionNSCache; |
88 | 88 |
89 template <typename T> | 89 template <typename T> |
90 T* AddCache(ContainerNode& node, | 90 T* AddCache(ContainerNode& node, |
91 CollectionType collection_type, | 91 CollectionType collection_type, |
92 const AtomicString& name) { | 92 const AtomicString& name) { |
93 DCHECK(ThreadState::Current()->IsGCForbidden()); | 93 DCHECK(ThreadState::Current()->IsGCForbidden()); |
94 NodeListAtomicNameCacheMap::AddResult result = atomic_name_caches_.insert( | 94 NodeListAtomicNameCacheMap::AddResult result = atomic_name_caches_.insert( |
95 NamedNodeListKey(collection_type, name), nullptr); | 95 NamedNodeListKey(collection_type, name), nullptr); |
96 if (!result.is_new_entry) { | 96 if (!result.is_new_entry) { |
97 return static_cast<T*>(result.stored_value->value.Get()); | 97 return static_cast<T*>(result.stored_value->value.Get()); |
(...skipping 19 matching lines...) Expand all Loading... |
117 ScriptWrappableVisitor::WriteBarrier(this, list); | 117 ScriptWrappableVisitor::WriteBarrier(this, list); |
118 return list; | 118 return list; |
119 } | 119 } |
120 | 120 |
121 template <typename T> | 121 template <typename T> |
122 T* Cached(CollectionType collection_type) { | 122 T* Cached(CollectionType collection_type) { |
123 return static_cast<T*>( | 123 return static_cast<T*>( |
124 atomic_name_caches_.at(NamedNodeListKey(collection_type, g_star_atom))); | 124 atomic_name_caches_.at(NamedNodeListKey(collection_type, g_star_atom))); |
125 } | 125 } |
126 | 126 |
127 TagCollection* AddCache(ContainerNode& node, | 127 TagCollectionNS* AddCache(ContainerNode& node, |
128 const AtomicString& namespace_uri, | 128 const AtomicString& namespace_uri, |
129 const AtomicString& local_name) { | 129 const AtomicString& local_name) { |
130 DCHECK(ThreadState::Current()->IsGCForbidden()); | 130 DCHECK(ThreadState::Current()->IsGCForbidden()); |
131 QualifiedName name(g_null_atom, local_name, namespace_uri); | 131 QualifiedName name(g_null_atom, local_name, namespace_uri); |
132 TagCollectionCacheNS::AddResult result = | 132 TagCollectionNSCache::AddResult result = |
133 tag_collection_cache_ns_.insert(name, nullptr); | 133 tag_collection_ns_caches_.insert(name, nullptr); |
134 if (!result.is_new_entry) | 134 if (!result.is_new_entry) |
135 return result.stored_value->value; | 135 return result.stored_value->value; |
136 | 136 |
137 TagCollection* list = | 137 TagCollectionNS* list = |
138 TagCollection::Create(node, namespace_uri, local_name); | 138 TagCollectionNS::Create(node, namespace_uri, local_name); |
139 result.stored_value->value = list; | 139 result.stored_value->value = list; |
140 ScriptWrappableVisitor::WriteBarrier(this, list); | 140 ScriptWrappableVisitor::WriteBarrier(this, list); |
141 return list; | 141 return list; |
142 } | 142 } |
143 | 143 |
144 static NodeListsNodeData* Create() { return new NodeListsNodeData; } | 144 static NodeListsNodeData* Create() { return new NodeListsNodeData; } |
145 | 145 |
146 void InvalidateCaches(const QualifiedName* attr_name = 0); | 146 void InvalidateCaches(const QualifiedName* attr_name = 0); |
147 | 147 |
148 bool IsEmpty() const { | 148 bool IsEmpty() const { |
149 return !child_node_list_ && atomic_name_caches_.IsEmpty() && | 149 return !child_node_list_ && atomic_name_caches_.IsEmpty() && |
150 tag_collection_cache_ns_.IsEmpty(); | 150 tag_collection_ns_caches_.IsEmpty(); |
151 } | 151 } |
152 | 152 |
153 void AdoptTreeScope() { InvalidateCaches(); } | 153 void AdoptTreeScope() { InvalidateCaches(); } |
154 | 154 |
155 void AdoptDocument(Document& old_document, Document& new_document) { | 155 void AdoptDocument(Document& old_document, Document& new_document) { |
156 DCHECK_NE(old_document, new_document); | 156 DCHECK_NE(old_document, new_document); |
157 | 157 |
158 NodeListAtomicNameCacheMap::const_iterator atomic_name_cache_end = | 158 NodeListAtomicNameCacheMap::const_iterator atomic_name_cache_end = |
159 atomic_name_caches_.end(); | 159 atomic_name_caches_.end(); |
160 for (NodeListAtomicNameCacheMap::const_iterator it = | 160 for (NodeListAtomicNameCacheMap::const_iterator it = |
161 atomic_name_caches_.begin(); | 161 atomic_name_caches_.begin(); |
162 it != atomic_name_cache_end; ++it) { | 162 it != atomic_name_cache_end; ++it) { |
163 LiveNodeListBase* list = it->value; | 163 LiveNodeListBase* list = it->value; |
164 list->DidMoveToDocument(old_document, new_document); | 164 list->DidMoveToDocument(old_document, new_document); |
165 } | 165 } |
166 | 166 |
167 TagCollectionCacheNS::const_iterator tag_end = | 167 TagCollectionNSCache::const_iterator tag_end = |
168 tag_collection_cache_ns_.end(); | 168 tag_collection_ns_caches_.end(); |
169 for (TagCollectionCacheNS::const_iterator it = | 169 for (TagCollectionNSCache::const_iterator it = |
170 tag_collection_cache_ns_.begin(); | 170 tag_collection_ns_caches_.begin(); |
171 it != tag_end; ++it) { | 171 it != tag_end; ++it) { |
172 LiveNodeListBase* list = it->value; | 172 LiveNodeListBase* list = it->value; |
173 DCHECK(!list->IsRootedAtTreeScope()); | 173 DCHECK(!list->IsRootedAtTreeScope()); |
174 list->DidMoveToDocument(old_document, new_document); | 174 list->DidMoveToDocument(old_document, new_document); |
175 } | 175 } |
176 } | 176 } |
177 DECLARE_TRACE(); | 177 DECLARE_TRACE(); |
178 | 178 |
179 DECLARE_TRACE_WRAPPERS(); | 179 DECLARE_TRACE_WRAPPERS(); |
180 | 180 |
181 private: | 181 private: |
182 NodeListsNodeData() : child_node_list_(nullptr) {} | 182 NodeListsNodeData() : child_node_list_(nullptr) {} |
183 | 183 |
184 std::pair<unsigned char, StringImpl*> NamedNodeListKey( | 184 std::pair<unsigned char, StringImpl*> NamedNodeListKey( |
185 CollectionType type, | 185 CollectionType type, |
186 const AtomicString& name) { | 186 const AtomicString& name) { |
187 // Holding the raw StringImpl is safe because |name| is retained by the | 187 // Holding the raw StringImpl is safe because |name| is retained by the |
188 // NodeList and the NodeList is reponsible for removing itself from the | 188 // NodeList and the NodeList is reponsible for removing itself from the |
189 // cache on deletion. | 189 // cache on deletion. |
190 return std::pair<unsigned char, StringImpl*>(type, name.Impl()); | 190 return std::pair<unsigned char, StringImpl*>(type, name.Impl()); |
191 } | 191 } |
192 | 192 |
193 // Can be a ChildNodeList or an EmptyNodeList. | 193 // Can be a ChildNodeList or an EmptyNodeList. |
194 WeakMember<NodeList> child_node_list_; | 194 WeakMember<NodeList> child_node_list_; |
195 NodeListAtomicNameCacheMap atomic_name_caches_; | 195 NodeListAtomicNameCacheMap atomic_name_caches_; |
196 TagCollectionCacheNS tag_collection_cache_ns_; | 196 TagCollectionNSCache tag_collection_ns_caches_; |
197 }; | 197 }; |
198 | 198 |
199 DEFINE_TRAIT_FOR_TRACE_WRAPPERS(NodeListsNodeData); | 199 DEFINE_TRAIT_FOR_TRACE_WRAPPERS(NodeListsNodeData); |
200 | 200 |
201 template <typename Collection> | 201 template <typename Collection> |
202 inline Collection* ContainerNode::EnsureCachedCollection(CollectionType type) { | 202 inline Collection* ContainerNode::EnsureCachedCollection(CollectionType type) { |
203 ThreadState::MainThreadGCForbiddenScope gc_forbidden; | 203 ThreadState::MainThreadGCForbiddenScope gc_forbidden; |
204 return EnsureNodeLists().AddCache<Collection>(*this, type); | 204 return EnsureNodeLists().AddCache<Collection>(*this, type); |
205 } | 205 } |
206 | 206 |
207 template <typename Collection> | 207 template <typename Collection> |
208 inline Collection* ContainerNode::EnsureCachedCollection( | 208 inline Collection* ContainerNode::EnsureCachedCollection( |
209 CollectionType type, | 209 CollectionType type, |
210 const AtomicString& name) { | 210 const AtomicString& name) { |
211 ThreadState::MainThreadGCForbiddenScope gc_forbidden; | 211 ThreadState::MainThreadGCForbiddenScope gc_forbidden; |
212 return EnsureNodeLists().AddCache<Collection>(*this, type, name); | 212 return EnsureNodeLists().AddCache<Collection>(*this, type, name); |
213 } | 213 } |
214 | 214 |
215 template <typename Collection> | 215 template <typename Collection> |
216 inline Collection* ContainerNode::EnsureCachedCollection( | 216 inline Collection* ContainerNode::EnsureCachedCollection( |
217 CollectionType type, | 217 CollectionType type, |
218 const AtomicString& namespace_uri, | 218 const AtomicString& namespace_uri, |
219 const AtomicString& local_name) { | 219 const AtomicString& local_name) { |
220 DCHECK_EQ(type, kTagCollectionType); | 220 DCHECK_EQ(type, kTagCollectionNSType); |
221 ThreadState::MainThreadGCForbiddenScope gc_forbidden; | 221 ThreadState::MainThreadGCForbiddenScope gc_forbidden; |
222 return EnsureNodeLists().AddCache(*this, namespace_uri, local_name); | 222 return EnsureNodeLists().AddCache(*this, namespace_uri, local_name); |
223 } | 223 } |
224 | 224 |
225 template <typename Collection> | 225 template <typename Collection> |
226 inline Collection* ContainerNode::CachedCollection(CollectionType type) { | 226 inline Collection* ContainerNode::CachedCollection(CollectionType type) { |
227 NodeListsNodeData* node_lists = this->NodeLists(); | 227 NodeListsNodeData* node_lists = this->NodeLists(); |
228 return node_lists ? node_lists->Cached<Collection>(type) : 0; | 228 return node_lists ? node_lists->Cached<Collection>(type) : 0; |
229 } | 229 } |
230 | 230 |
231 } // namespace blink | 231 } // namespace blink |
232 | 232 |
233 #endif // NodeListsNodeData_h | 233 #endif // NodeListsNodeData_h |
OLD | NEW |