| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef WeakIdentifierMap_h | 5 #ifndef WeakIdentifierMap_h |
| 6 #define WeakIdentifierMap_h | 6 #define WeakIdentifierMap_h |
| 7 | 7 |
| 8 #include "platform/heap/Handle.h" | 8 #include "platform/heap/Handle.h" |
| 9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
| 10 #include "wtf/HashMap.h" | 10 #include "wtf/HashMap.h" |
| 11 #include "wtf/Vector.h" | |
| 12 | 11 |
| 13 namespace blink { | 12 namespace blink { |
| 14 | 13 |
| 15 template<typename T> struct IdentifierGenerator; | 14 // TODO(sof): WeakIdentifierMap<> belongs (out) in wtf/, but |
| 15 // cannot until GarbageCollected<> can be used from WTF. |
| 16 | 16 |
| 17 template<> struct IdentifierGenerator<int> { | 17 template<typename T, typename IdentifierType, bool isGarbageCollected> |
| 18 STATIC_ONLY(IdentifierGenerator); | 18 class WeakIdentifierMapBase { |
| 19 using IdentifierType = int; | 19 USING_FAST_MALLOC(WeakIdentifierMapBase); |
| 20 static IdentifierType next() | 20 protected: |
| 21 { | |
| 22 static int s_lastId = 0; | |
| 23 return ++s_lastId; | |
| 24 } | |
| 25 }; | |
| 26 | |
| 27 template<typename T> struct WeakIdentifierMapTraits { | |
| 28 STATIC_ONLY(WeakIdentifierMapTraits); | |
| 29 static void removedFromIdentifierMap(T*) { } | |
| 30 static void addedToIdentifierMap(T*) { } | |
| 31 }; | |
| 32 | |
| 33 template<typename T, | |
| 34 typename Generator = IdentifierGenerator<int>, | |
| 35 typename Traits = WeakIdentifierMapTraits<T>, | |
| 36 bool isGarbageCollected = IsGarbageCollectedType<T>::value> class WeakIdenti
fierMap; | |
| 37 | |
| 38 template<typename T, typename Generator, typename Traits> class WeakIdentifierMa
p<T, Generator, Traits, false> { | |
| 39 USING_FAST_MALLOC(WeakIdentifierMap); | |
| 40 public: | |
| 41 using IdentifierType = typename Generator::IdentifierType; | |
| 42 | |
| 43 static IdentifierType identifier(T* object) | |
| 44 { | |
| 45 IdentifierType result = instance().m_objectToIdentifier.get(object); | |
| 46 | |
| 47 if (WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(result)) { | |
| 48 result = Generator::next(); | |
| 49 instance().put(object, result); | |
| 50 } | |
| 51 return result; | |
| 52 } | |
| 53 | |
| 54 static T* lookup(IdentifierType identifier) | |
| 55 { | |
| 56 return instance().m_identifierToObject.get(identifier); | |
| 57 } | |
| 58 | |
| 59 static void notifyObjectDestroyed(T* object) | |
| 60 { | |
| 61 instance().objectDestroyed(object); | |
| 62 } | |
| 63 | |
| 64 private: | |
| 65 static WeakIdentifierMap<T, Generator, Traits>& instance(); | |
| 66 WeakIdentifierMap() { } | |
| 67 ~WeakIdentifierMap(); | |
| 68 | |
| 69 void put(T* object, IdentifierType identifier) | |
| 70 { | |
| 71 DCHECK(object && !m_objectToIdentifier.contains(object)); | |
| 72 m_objectToIdentifier.set(object, identifier); | |
| 73 m_identifierToObject.set(identifier, object); | |
| 74 Traits::addedToIdentifierMap(object); | |
| 75 } | |
| 76 | |
| 77 void objectDestroyed(T* object) | |
| 78 { | |
| 79 IdentifierType identifier = m_objectToIdentifier.take(object); | |
| 80 if (!WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(identifier)
) | |
| 81 m_identifierToObject.remove(identifier); | |
| 82 } | |
| 83 | |
| 84 using ObjectToIdentifier = HashMap<T*, IdentifierType>; | 21 using ObjectToIdentifier = HashMap<T*, IdentifierType>; |
| 85 using IdentifierToObject = HashMap<IdentifierType, T*>; | 22 using IdentifierToObject = HashMap<IdentifierType, T*>; |
| 86 | 23 |
| 87 ObjectToIdentifier m_objectToIdentifier; | 24 ObjectToIdentifier m_objectToIdentifier; |
| 88 IdentifierToObject m_identifierToObject; | 25 IdentifierToObject m_identifierToObject; |
| 89 }; | 26 }; |
| 90 | 27 |
| 91 template<typename T, typename Generator, typename Traits> class WeakIdentifierMa
p<T, Generator, Traits, true> | 28 template<typename T, typename IdentifierType> |
| 92 : public GarbageCollected<WeakIdentifierMap<T, Generator, Traits, true>> { | 29 class WeakIdentifierMapBase<T, IdentifierType, true> : public GarbageCollected<W
eakIdentifierMapBase<T, IdentifierType, true>> { |
| 93 public: | 30 public: |
| 94 using IdentifierType = typename Generator::IdentifierType; | 31 DEFINE_INLINE_TRACE() |
| 32 { |
| 33 visitor->trace(m_objectToIdentifier); |
| 34 visitor->trace(m_identifierToObject); |
| 35 } |
| 36 protected: |
| 37 using ObjectToIdentifier = HeapHashMap<WeakMember<T>, IdentifierType>; |
| 38 using IdentifierToObject = HeapHashMap<IdentifierType, WeakMember<T>>; |
| 95 | 39 |
| 40 ObjectToIdentifier m_objectToIdentifier; |
| 41 IdentifierToObject m_identifierToObject; |
| 42 }; |
| 43 |
| 44 template<typename T, typename IdentifierType = int> |
| 45 class WeakIdentifierMap final : public WeakIdentifierMapBase<T, IdentifierType,
IsGarbageCollectedType<T>::value> { |
| 46 public: |
| 96 static IdentifierType identifier(T* object) | 47 static IdentifierType identifier(T* object) |
| 97 { | 48 { |
| 98 IdentifierType result = instance().m_objectToIdentifier->get(object); | 49 IdentifierType result = instance().m_objectToIdentifier.get(object); |
| 99 | 50 |
| 100 if (WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(result)) { | 51 if (WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(result)) { |
| 101 result = Generator::next(); | 52 result = next(); |
| 102 instance().put(object, result); | 53 instance().put(object, result); |
| 103 } | 54 } |
| 104 return result; | 55 return result; |
| 105 } | 56 } |
| 106 | 57 |
| 107 static T* lookup(IdentifierType identifier) | 58 static T* lookup(IdentifierType identifier) |
| 108 { | 59 { |
| 109 return instance().m_identifierToObject->get(identifier); | 60 return instance().m_identifierToObject.get(identifier); |
| 110 } | 61 } |
| 111 | 62 |
| 112 static void notifyObjectDestroyed(T* object) { } | 63 static void notifyObjectDestroyed(T* object) |
| 113 | |
| 114 DEFINE_INLINE_TRACE() | |
| 115 { | 64 { |
| 116 visitor->trace(m_objectToIdentifier); | 65 instance().objectDestroyed(object); |
| 117 visitor->trace(m_identifierToObject); | |
| 118 } | 66 } |
| 119 | 67 |
| 120 private: | 68 private: |
| 121 static WeakIdentifierMap<T, Generator, Traits>& instance(); | 69 static WeakIdentifierMap<T, IdentifierType>& instance(); |
| 122 | 70 |
| 123 WeakIdentifierMap() | 71 WeakIdentifierMap() { } |
| 124 : m_objectToIdentifier(new ObjectToIdentifier()) | 72 |
| 125 , m_identifierToObject(new IdentifierToObject()) | 73 static IdentifierType next() |
| 126 { | 74 { |
| 75 static IdentifierType s_lastId = 0; |
| 76 return ++s_lastId; |
| 127 } | 77 } |
| 128 | 78 |
| 129 void put(T* object, IdentifierType identifier) | 79 void put(T* object, IdentifierType identifier) |
| 130 { | 80 { |
| 131 DCHECK(object && !m_objectToIdentifier->contains(object)); | 81 DCHECK(object && !this->m_objectToIdentifier.contains(object)); |
| 132 m_objectToIdentifier->set(object, identifier); | 82 this->m_objectToIdentifier.set(object, identifier); |
| 133 m_identifierToObject->set(identifier, object); | 83 this->m_identifierToObject.set(identifier, object); |
| 134 } | 84 } |
| 135 | 85 |
| 136 using ObjectToIdentifier = HeapHashMap<WeakMember<T>, IdentifierType>; | 86 void objectDestroyed(T* object) |
| 137 using IdentifierToObject = HeapHashMap<IdentifierType, WeakMember<T>>; | 87 { |
| 138 | 88 IdentifierType identifier = this->m_objectToIdentifier.take(object); |
| 139 Member<ObjectToIdentifier> m_objectToIdentifier; | 89 if (!WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(identifier)
) |
| 140 Member<IdentifierToObject> m_identifierToObject; | 90 this->m_identifierToObject.remove(identifier); |
| 91 } |
| 141 }; | 92 }; |
| 142 | 93 |
| 143 #define DECLARE_WEAK_IDENTIFIER_MAP(T, ...) \ | 94 #define DECLARE_WEAK_IDENTIFIER_MAP(T, ...) \ |
| 144 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_
ARGS__>::instance(); \ | 95 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_
ARGS__>::instance(); \ |
| 145 extern template class WeakIdentifierMap<T, ##__VA_ARGS__>; | 96 extern template class WeakIdentifierMap<T, ##__VA_ARGS__>; |
| 146 | 97 |
| 147 #define DEFINE_WEAK_IDENTIFIER_MAP(T, ...) \ | 98 #define DEFINE_WEAK_IDENTIFIER_MAP(T, ...) \ |
| 148 template class WeakIdentifierMap<T, ##__VA_ARGS__>; \ | 99 template class WeakIdentifierMap<T, ##__VA_ARGS__>; \ |
| 149 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_
ARGS__>::instance() \ | 100 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_
ARGS__>::instance() \ |
| 150 { \ | 101 { \ |
| 151 using RefType = WeakIdentifierMap<T, ##__VA_ARGS__>; \ | 102 using RefType = WeakIdentifierMap<T, ##__VA_ARGS__>; \ |
| 152 DEFINE_STATIC_LOCAL(RefType, mapInstance, (new WeakIdentifierMap<T, ##__
VA_ARGS__>())); \ | 103 DEFINE_STATIC_LOCAL(RefType, mapInstance, (new WeakIdentifierMap<T, ##__
VA_ARGS__>())); \ |
| 153 return mapInstance; \ | 104 return mapInstance; \ |
| 154 } | 105 } |
| 155 | 106 |
| 156 } // namespace blink | 107 } // namespace blink |
| 157 | 108 |
| 158 #endif // WeakIdentifierMap_h | 109 #endif // WeakIdentifierMap_h |
| OLD | NEW |