| 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 |