summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/WeakGCMap.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/WeakGCMap.h')
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h82
1 files changed, 60 insertions, 22 deletions
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index a40e684..5ad1c62 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -34,17 +34,31 @@ namespace JSC {
// A HashMap for GC'd values that removes entries when the associated value
// dies.
-template<typename KeyType, typename MappedType> class WeakGCMap : private Finalizer {
+template <typename KeyType, typename MappedType> struct DefaultWeakGCMapFinalizerCallback {
+ static void* finalizerContextFor(KeyType key)
+ {
+ return reinterpret_cast<void*>(key);
+ }
+
+ static KeyType keyForFinalizer(void* context, typename HandleTypes<MappedType>::ExternalType)
+ {
+ return reinterpret_cast<KeyType>(context);
+ }
+};
+
+template<typename KeyType, typename MappedType, typename FinalizerCallback = DefaultWeakGCMapFinalizerCallback<KeyType, MappedType>, typename HashArg = typename DefaultHash<KeyType>::Hash, typename KeyTraitsArg = HashTraits<KeyType> >
+class WeakGCMap : private WeakHandleOwner {
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(WeakGCMap);
- typedef HashMap<KeyType, HandleSlot> MapType;
+ typedef HashMap<KeyType, HandleSlot, HashArg, KeyTraitsArg> MapType;
typedef typename HandleTypes<MappedType>::ExternalType ExternalType;
typedef typename MapType::iterator map_iterator;
public:
struct iterator {
+ friend class WeakGCMap;
iterator(map_iterator iter)
: m_iterator(iter)
{
@@ -62,7 +76,7 @@ public:
bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; }
private:
- map_iterator m_iterator;
+ map_iterator m_iterator;
};
WeakGCMap()
@@ -78,6 +92,25 @@ public:
m_map.clear();
}
+ bool contains(const KeyType& key) const
+ {
+ return m_map.contains(key);
+ }
+
+ iterator find(const KeyType& key)
+ {
+ return m_map.find(key);
+ }
+
+ void remove(iterator iter)
+ {
+ ASSERT(iter.m_iterator != m_map.end());
+ HandleSlot slot = iter.m_iterator->second;
+ ASSERT(slot);
+ HandleHeap::heapFor(slot)->deallocate(slot);
+ m_map.remove(iter.m_iterator);
+ }
+
ExternalType get(const KeyType& key) const
{
return HandleTypes<MappedType>::getFromSlot(m_map.get(key));
@@ -88,14 +121,35 @@ public:
return m_map.get(key);
}
+ pair<iterator, bool> add(JSGlobalData& globalData, const KeyType& key, ExternalType value)
+ {
+ pair<typename MapType::iterator, bool> iter = m_map.add(key, 0);
+ if (iter.second) {
+ HandleSlot slot = globalData.allocateGlobalHandle();
+ iter.first->second = slot;
+ HandleHeap::heapFor(slot)->makeWeak(slot, this, FinalizerCallback::finalizerContextFor(key));
+ HandleHeap::heapFor(slot)->writeBarrier(slot, value);
+ *slot = value;
+ }
+ return iter;
+ }
+
+ void set(iterator iter, ExternalType value)
+ {
+ HandleSlot slot = iter.m_iterator->second;
+ ASSERT(slot);
+ HandleHeap::heapFor(slot)->writeBarrier(slot, value);
+ *slot = value;
+ }
+
void set(JSGlobalData& globalData, const KeyType& key, ExternalType value)
{
pair<typename MapType::iterator, bool> iter = m_map.add(key, 0);
HandleSlot slot = iter.first->second;
if (iter.second) {
slot = globalData.allocateGlobalHandle();
- iter.first->second = slot;
HandleHeap::heapFor(slot)->makeWeak(slot, this, key);
+ iter.first->second = slot;
}
HandleHeap::heapFor(slot)->writeBarrier(slot, value);
*slot = value;
@@ -113,22 +167,6 @@ public:
size_t size() { return m_map.size(); }
- bool deprecatedRemove(const KeyType& key, ExternalType value)
- {
- // This only exists in order to allow some semblance of correctness to
- // the JSWeakObjectMapClear API
- typename MapType::iterator iter = m_map.find(key);
- if (iter == m_map.end())
- return false;
- HandleSlot slot = iter->second;
- ExternalType inmap = HandleTypes<MappedType>::getFromSlot(slot);
- if (inmap && inmap != value)
- return false;
- m_map.remove(iter);
- HandleHeap::heapFor(slot)->deallocate(slot);
- return true;
- }
-
iterator begin() { return iterator(m_map.begin()); }
iterator end() { return iterator(m_map.end()); }
@@ -138,9 +176,9 @@ public:
}
private:
- virtual void finalize(Handle<Unknown>, void* key)
+ virtual void finalize(Handle<Unknown> handle, void* context)
{
- HandleSlot slot = m_map.take(static_cast<KeyType>(key));
+ HandleSlot slot = m_map.take(FinalizerCallback::keyForFinalizer(context, HandleTypes<MappedType>::getFromSlot(handle.slot())));
ASSERT(slot);
HandleHeap::heapFor(slot)->deallocate(slot);
}