summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/WeakGCMap.h
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/JavaScriptCore/runtime/WeakGCMap.h
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/JavaScriptCore/runtime/WeakGCMap.h')
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h187
1 files changed, 102 insertions, 85 deletions
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index 7bf4503..a40e684 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -26,110 +26,127 @@
#ifndef WeakGCMap_h
#define WeakGCMap_h
-#include "Heap.h"
+#include "Handle.h"
+#include "JSGlobalData.h"
#include <wtf/HashMap.h>
namespace JSC {
-class JSCell;
-
-// A HashMap whose get() function returns emptyValue() for cells awaiting destruction.
-template<typename KeyType, typename MappedType>
-class WeakGCMap {
+// A HashMap for GC'd values that removes entries when the associated value
+// dies.
+template<typename KeyType, typename MappedType> class WeakGCMap : private Finalizer {
WTF_MAKE_FAST_ALLOCATED;
- /*
- Invariants:
- * A value enters the WeakGCMap marked. (Guaranteed by set().)
- * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.)
- * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.)
- * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.)
- */
+ WTF_MAKE_NONCOPYABLE(WeakGCMap);
+
+ typedef HashMap<KeyType, HandleSlot> MapType;
+ typedef typename HandleTypes<MappedType>::ExternalType ExternalType;
+ typedef typename MapType::iterator map_iterator;
public:
- typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::iterator iterator;
- typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::const_iterator const_iterator;
-
+
+ struct iterator {
+ iterator(map_iterator iter)
+ : m_iterator(iter)
+ {
+ }
+
+ std::pair<KeyType, ExternalType> get() const { return std::make_pair(m_iterator->first, HandleTypes<MappedType>::getFromSlot(m_iterator->second)); }
+ std::pair<KeyType, HandleSlot> getSlot() const { return *m_iterator; }
+
+ iterator& operator++() { ++m_iterator; return *this; }
+
+ // postfix ++ intentionally omitted
+
+ // Comparison.
+ bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; }
+ bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; }
+
+ private:
+ map_iterator m_iterator;
+ };
+
+ WeakGCMap()
+ {
+ }
+
bool isEmpty() { return m_map.isEmpty(); }
- void clear() { m_map.clear(); }
+ void clear()
+ {
+ map_iterator end = m_map.end();
+ for (map_iterator ptr = m_map.begin(); ptr != end; ++ptr)
+ HandleHeap::heapFor(ptr->second)->deallocate(ptr->second);
+ m_map.clear();
+ }
- MappedType* get(const KeyType&) const;
- pair<iterator, bool> set(const KeyType&, MappedType*);
- MappedType* take(const KeyType&);
+ ExternalType get(const KeyType& key) const
+ {
+ return HandleTypes<MappedType>::getFromSlot(m_map.get(key));
+ }
- // These unchecked functions provide access to a value even if the value's
- // mark bit is not set. This is used, among other things, to retrieve values
- // during the GC mark phase, which begins by clearing all mark bits.
-
- size_t uncheckedSize() { return m_map.size(); }
+ HandleSlot getSlot(const KeyType& key) const
+ {
+ return m_map.get(key);
+ }
- MappedType* uncheckedGet(const KeyType& key) const { return m_map.get(key).get(); }
- DeprecatedPtr<MappedType>* uncheckedGetSlot(const KeyType& key)
+ void set(JSGlobalData& globalData, const KeyType& key, ExternalType value)
{
- iterator iter = m_map.find(key);
- if (iter == m_map.end())
- return 0;
- return &iter->second;
+ 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);
+ }
+ HandleHeap::heapFor(slot)->writeBarrier(slot, value);
+ *slot = value;
}
- bool uncheckedRemove(const KeyType&, MappedType*);
- iterator uncheckedBegin() { return m_map.begin(); }
- iterator uncheckedEnd() { return m_map.end(); }
+ ExternalType take(const KeyType& key)
+ {
+ HandleSlot slot = m_map.take(key);
+ if (!slot)
+ return HashTraits<ExternalType>::emptyValue();
+ ExternalType result = HandleTypes<MappedType>::getFromSlot(slot);
+ HandleHeap::heapFor(slot)->deallocate(slot);
+ return result;
+ }
- const_iterator uncheckedBegin() const { return m_map.begin(); }
- const_iterator uncheckedEnd() const { return m_map.end(); }
+ size_t size() { return m_map.size(); }
- bool isValid(iterator it) const { return Heap::isMarked(it->second.get()); }
- bool isValid(const_iterator it) const { return Heap::isMarked(it->second.get()); }
+ 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()); }
+
+ ~WeakGCMap()
+ {
+ clear();
+ }
+
private:
- HashMap<KeyType, DeprecatedPtr<MappedType> > m_map;
-};
-
-template<typename KeyType, typename MappedType>
-inline MappedType* WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const
-{
- MappedType* result = m_map.get(key).get();
- if (result == HashTraits<MappedType*>::emptyValue())
- return result;
- if (!Heap::isMarked(result))
- return HashTraits<MappedType*>::emptyValue();
- return result;
-}
-
-template<typename KeyType, typename MappedType>
-MappedType* WeakGCMap<KeyType, MappedType>::take(const KeyType& key)
-{
- MappedType* result = m_map.take(key).get();
- if (result == HashTraits<MappedType*>::emptyValue())
- return result;
- if (!Heap::isMarked(result))
- return HashTraits<MappedType*>::emptyValue();
- return result;
-}
-
-template<typename KeyType, typename MappedType>
-pair<typename WeakGCMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, MappedType* value)
-{
- Heap::setMarked(value); // If value is newly allocated, it's not marked, so mark it now.
- pair<iterator, bool> result = m_map.add(key, value);
- if (!result.second) { // pre-existing entry
- result.second = !Heap::isMarked(result.first->second.get());
- result.first->second = value;
+ virtual void finalize(Handle<Unknown>, void* key)
+ {
+ HandleSlot slot = m_map.take(static_cast<KeyType>(key));
+ ASSERT(slot);
+ HandleHeap::heapFor(slot)->deallocate(slot);
}
- return result;
-}
-
-template<typename KeyType, typename MappedType>
-bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, MappedType* value)
-{
- iterator it = m_map.find(key);
- if (it == m_map.end())
- return false;
- if (it->second.get() != value)
- return false;
- m_map.remove(it);
- return true;
-}
+
+ MapType m_map;
+};
} // namespace JSC