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
3 // found in the LICENSE file.
5 #ifndef WeakIdentifierMap_h
6 #define WeakIdentifierMap_h
8 #include "platform/heap/Handle.h"
9 #include "wtf/Allocator.h"
10 #include "wtf/HashMap.h"
11 #include "wtf/Vector.h"
15 template<typename T
> struct IdentifierGenerator
;
17 template<> struct IdentifierGenerator
<int> {
18 STATIC_ONLY(IdentifierGenerator
);
19 using IdentifierType
= int;
20 static IdentifierType
next()
22 static int s_lastId
= 0;
27 template<typename T
> struct WeakIdentifierMapTraits
{
28 STATIC_ONLY(WeakIdentifierMapTraits
);
29 static void removedFromIdentifierMap(T
*) { }
30 static void addedToIdentifierMap(T
*) { }
34 typename Generator
= IdentifierGenerator
<int>,
35 typename Traits
= WeakIdentifierMapTraits
<T
>,
36 bool isGarbageCollected
= IsGarbageCollectedType
<T
>::value
> class WeakIdentifierMap
;
38 template<typename T
, typename Generator
, typename Traits
> class WeakIdentifierMap
<T
, Generator
, Traits
, false> {
39 WTF_MAKE_FAST_ALLOCATED(WeakIdentifierMap
);
41 using IdentifierType
= typename
Generator::IdentifierType
;
42 using ReferenceType
= RawPtr
<WeakIdentifierMap
<T
, Generator
, Traits
, false>>;
44 static IdentifierType
identifier(T
* object
)
46 IdentifierType result
= instance().m_objectToIdentifier
.get(object
);
48 if (WTF::isHashTraitsEmptyValue
<HashTraits
<IdentifierType
>>(result
)) {
49 result
= Generator::next();
50 instance().put(object
, result
);
55 static T
* lookup(IdentifierType identifier
)
57 return instance().m_identifierToObject
.get(identifier
);
60 static void notifyObjectDestroyed(T
* object
)
62 instance().objectDestroyed(object
);
66 static WeakIdentifierMap
<T
, Generator
, Traits
>& instance();
67 WeakIdentifierMap() { }
70 void put(T
* object
, IdentifierType identifier
)
72 ASSERT(object
&& !m_objectToIdentifier
.contains(object
));
73 m_objectToIdentifier
.set(object
, identifier
);
74 m_identifierToObject
.set(identifier
, object
);
75 Traits::addedToIdentifierMap(object
);
78 void objectDestroyed(T
* object
)
80 IdentifierType identifier
= m_objectToIdentifier
.take(object
);
81 if (!WTF::isHashTraitsEmptyValue
<HashTraits
<IdentifierType
>>(identifier
))
82 m_identifierToObject
.remove(identifier
);
85 using ObjectToIdentifier
= HashMap
<T
*, IdentifierType
>;
86 using IdentifierToObject
= HashMap
<IdentifierType
, T
*>;
88 ObjectToIdentifier m_objectToIdentifier
;
89 IdentifierToObject m_identifierToObject
;
92 template<typename T
, typename Generator
, typename Traits
> class WeakIdentifierMap
<T
, Generator
, Traits
, true>
93 : public GarbageCollected
<WeakIdentifierMap
<T
, Generator
, Traits
, true>> {
95 using IdentifierType
= typename
Generator::IdentifierType
;
96 using ReferenceType
= Persistent
<WeakIdentifierMap
<T
, Generator
, Traits
, true>>;
98 static IdentifierType
identifier(T
* object
)
100 IdentifierType result
= instance().m_objectToIdentifier
->get(object
);
102 if (WTF::isHashTraitsEmptyValue
<HashTraits
<IdentifierType
>>(result
)) {
103 result
= Generator::next();
104 instance().put(object
, result
);
109 static T
* lookup(IdentifierType identifier
)
111 return instance().m_identifierToObject
->get(identifier
);
114 static void notifyObjectDestroyed(T
* object
) { }
116 DEFINE_INLINE_TRACE()
118 visitor
->trace(m_objectToIdentifier
);
119 visitor
->trace(m_identifierToObject
);
123 static WeakIdentifierMap
<T
, Generator
, Traits
>& instance();
126 : m_objectToIdentifier(new ObjectToIdentifier())
127 , m_identifierToObject(new IdentifierToObject())
131 void put(T
* object
, IdentifierType identifier
)
133 ASSERT(object
&& !m_objectToIdentifier
->contains(object
));
134 m_objectToIdentifier
->set(object
, identifier
);
135 m_identifierToObject
->set(identifier
, object
);
138 using ObjectToIdentifier
= HeapHashMap
<WeakMember
<T
>, IdentifierType
>;
139 using IdentifierToObject
= HeapHashMap
<IdentifierType
, WeakMember
<T
>>;
141 Member
<ObjectToIdentifier
> m_objectToIdentifier
;
142 Member
<IdentifierToObject
> m_identifierToObject
;
145 #define DECLARE_WEAK_IDENTIFIER_MAP(T, ...) \
146 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_ARGS__>::instance(); \
147 extern template class WeakIdentifierMap<T, ##__VA_ARGS__>;
149 #define DEFINE_WEAK_IDENTIFIER_MAP(T, ...) \
150 template class WeakIdentifierMap<T, ##__VA_ARGS__>; \
151 template<> WeakIdentifierMap<T, ##__VA_ARGS__>& WeakIdentifierMap<T, ##__VA_ARGS__>::instance() \
153 using RefType = WeakIdentifierMap<T, ##__VA_ARGS__>::ReferenceType; \
154 DEFINE_STATIC_LOCAL(RefType, mapInstance, (new WeakIdentifierMap<T, ##__VA_ARGS__>())); \
155 return *mapInstance; \
159 #endif // WeakIdentifierMap_h