1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WeakIdentifierMap_h
#define WeakIdentifierMap_h
#include "platform/heap/Handle.h"
#include "wtf/Allocator.h"
#include "wtf/HashMap.h"
namespace blink {
// TODO(sof): WeakIdentifierMap<> belongs (out) in wtf/, but
// cannot until GarbageCollected<> can be used from WTF.
template <typename T, typename IdentifierType, bool isGarbageCollected>
class WeakIdentifierMapBase {
USING_FAST_MALLOC(WeakIdentifierMapBase);
protected:
using ObjectToIdentifier = HashMap<T*, IdentifierType>;
using IdentifierToObject = HashMap<IdentifierType, T*>;
ObjectToIdentifier m_objectToIdentifier;
IdentifierToObject m_identifierToObject;
};
template <typename T, typename IdentifierType>
class WeakIdentifierMapBase<T, IdentifierType, true>
: public GarbageCollected<WeakIdentifierMapBase<T, IdentifierType, true>> {
public:
DEFINE_INLINE_TRACE() {
visitor->trace(m_objectToIdentifier);
visitor->trace(m_identifierToObject);
}
protected:
using ObjectToIdentifier = HeapHashMap<WeakMember<T>, IdentifierType>;
using IdentifierToObject = HeapHashMap<IdentifierType, WeakMember<T>>;
ObjectToIdentifier m_objectToIdentifier;
IdentifierToObject m_identifierToObject;
};
template <typename T, typename IdentifierType = int>
class WeakIdentifierMap final
: public WeakIdentifierMapBase<T,
IdentifierType,
IsGarbageCollectedType<T>::value> {
public:
static IdentifierType identifier(T* object) {
IdentifierType result = instance().m_objectToIdentifier.get(object);
if (WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(result)) {
result = next();
instance().put(object, result);
}
return result;
}
static T* lookup(IdentifierType identifier) {
return instance().m_identifierToObject.get(identifier);
}
static void notifyObjectDestroyed(T* object) {
instance().objectDestroyed(object);
}
private:
static WeakIdentifierMap<T, IdentifierType>& instance();
WeakIdentifierMap() {}
static IdentifierType next() {
static IdentifierType s_lastId = 0;
return ++s_lastId;
}
void put(T* object, IdentifierType identifier) {
DCHECK(object && !this->m_objectToIdentifier.contains(object));
this->m_objectToIdentifier.set(object, identifier);
this->m_identifierToObject.set(identifier, object);
}
void objectDestroyed(T* object) {
IdentifierType identifier = this->m_objectToIdentifier.take(object);
if (!WTF::isHashTraitsEmptyValue<HashTraits<IdentifierType>>(identifier))
this->m_identifierToObject.remove(identifier);
}
};
#define DECLARE_WEAK_IDENTIFIER_MAP(T, ...) \
template <> \
WeakIdentifierMap<T, ##__VA_ARGS__>& \
WeakIdentifierMap<T, ##__VA_ARGS__>::instance(); \
extern template class WeakIdentifierMap<T, ##__VA_ARGS__>;
#define DEFINE_WEAK_IDENTIFIER_MAP(T, ...) \
template class WeakIdentifierMap<T, ##__VA_ARGS__>; \
template <> \
WeakIdentifierMap<T, ##__VA_ARGS__>& \
WeakIdentifierMap<T, ##__VA_ARGS__>::instance() { \
using RefType = WeakIdentifierMap<T, ##__VA_ARGS__>; \
DEFINE_STATIC_LOCAL(RefType, mapInstance, \
(new WeakIdentifierMap<T, ##__VA_ARGS__>())); \
return mapInstance; \
}
} // namespace blink
#endif // WeakIdentifierMap_h
|