Changeset 79616 in webkit for trunk/Source/JavaScriptCore/runtime/WeakGCMap.h
- Timestamp:
- Feb 24, 2011, 1:59:57 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/WeakGCMap.h
r77391 r79616 27 27 #define WeakGCMap_h 28 28 29 #include "Heap.h" 29 #include "Handle.h" 30 #include "JSGlobalData.h" 30 31 #include <wtf/HashMap.h> 31 32 32 33 namespace JSC { 33 34 34 class JSCell; 35 // A HashMap for GC'd values that removes entries when the associated value 36 // dies. 37 template<typename KeyType, typename MappedType> class WeakGCMap : private Finalizer { 38 WTF_MAKE_FAST_ALLOCATED; 39 WTF_MAKE_NONCOPYABLE(WeakGCMap); 35 40 36 // A HashMap whose get() function returns emptyValue() for cells awaiting destruction. 37 template<typename KeyType, typename MappedType> 38 class WeakGCMap { 39 WTF_MAKE_FAST_ALLOCATED; 40 /* 41 Invariants: 42 * A value enters the WeakGCMap marked. (Guaranteed by set().) 43 * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.) 44 * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.) 45 * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.) 46 */ 41 typedef HashMap<KeyType, HandleSlot> MapType; 42 typedef typename HandleTypes<MappedType>::ExternalType ExternalType; 43 typedef typename MapType::iterator map_iterator; 47 44 48 45 public: 49 typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::iterator iterator; 50 typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::const_iterator const_iterator; 46 47 struct iterator { 48 iterator(map_iterator iter) 49 : m_iterator(iter) 50 { 51 } 52 53 std::pair<KeyType, ExternalType> get() const { return std::make_pair(m_iterator->first, HandleTypes<MappedType>::getFromSlot(m_iterator->second)); } 54 std::pair<KeyType, HandleSlot> getSlot() const { return *m_iterator; } 55 56 iterator& operator++() { ++m_iterator; return *this; } 57 58 // postfix ++ intentionally omitted 59 60 // Comparison. 61 bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; } 62 bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; } 63 64 private: 65 map_iterator m_iterator; 66 }; 67 68 WeakGCMap() 69 { 70 } 71 72 bool isEmpty() { return m_map.isEmpty(); } 73 void clear() 74 { 75 map_iterator end = m_map.end(); 76 for (map_iterator ptr = m_map.begin(); ptr != end; ++ptr) 77 HandleHeap::heapFor(ptr->second)->deallocate(ptr->second); 78 m_map.clear(); 79 } 80 81 ExternalType get(const KeyType& key) const 82 { 83 return HandleTypes<MappedType>::getFromSlot(m_map.get(key)); 84 } 85 86 HandleSlot getSlot(const KeyType& key) const 87 { 88 return m_map.get(key); 89 } 90 91 void set(JSGlobalData& globalData, const KeyType& key, ExternalType value) 92 { 93 pair<typename MapType::iterator, bool> iter = m_map.add(key, 0); 94 HandleSlot slot = iter.first->second; 95 if (iter.second) { 96 slot = globalData.allocateGlobalHandle(); 97 iter.first->second = slot; 98 HandleHeap::heapFor(slot)->makeWeak(slot, this, key); 99 } 100 HandleHeap::heapFor(slot)->writeBarrier(slot, value); 101 *slot = value; 102 } 103 104 ExternalType take(const KeyType& key) 105 { 106 HandleSlot slot = m_map.take(key); 107 if (!slot) 108 return HashTraits<ExternalType>::emptyValue(); 109 ExternalType result = HandleTypes<MappedType>::getFromSlot(slot); 110 HandleHeap::heapFor(slot)->deallocate(slot); 111 return result; 112 } 113 114 size_t size() { return m_map.size(); } 115 116 bool deprecatedRemove(const KeyType& key, ExternalType value) 117 { 118 // This only exists in order to allow some semblance of correctness to 119 // the JSWeakObjectMapClear API 120 typename MapType::iterator iter = m_map.find(key); 121 if (iter == m_map.end()) 122 return false; 123 HandleSlot slot = iter->second; 124 ExternalType inmap = HandleTypes<MappedType>::getFromSlot(slot); 125 if (inmap && inmap != value) 126 return false; 127 m_map.remove(iter); 128 HandleHeap::heapFor(slot)->deallocate(slot); 129 return true; 130 } 131 132 iterator begin() { return iterator(m_map.begin()); } 133 iterator end() { return iterator(m_map.end()); } 51 134 52 bool isEmpty() { return m_map.isEmpty(); } 53 void clear() { m_map.clear(); } 135 ~WeakGCMap() 136 { 137 clear(); 138 } 139 140 private: 141 virtual void finalize(Handle<Unknown>, void* key) 142 { 143 HandleSlot slot = m_map.take(static_cast<KeyType>(key)); 144 ASSERT(slot); 145 HandleHeap::heapFor(slot)->deallocate(slot); 146 } 54 147 55 MappedType* get(const KeyType&) const; 56 pair<iterator, bool> set(const KeyType&, MappedType*); 57 MappedType* take(const KeyType&); 58 59 // These unchecked functions provide access to a value even if the value's 60 // mark bit is not set. This is used, among other things, to retrieve values 61 // during the GC mark phase, which begins by clearing all mark bits. 62 63 size_t uncheckedSize() { return m_map.size(); } 64 65 MappedType* uncheckedGet(const KeyType& key) const { return m_map.get(key).get(); } 66 DeprecatedPtr<MappedType>* uncheckedGetSlot(const KeyType& key) 67 { 68 iterator iter = m_map.find(key); 69 if (iter == m_map.end()) 70 return 0; 71 return &iter->second; 72 } 73 bool uncheckedRemove(const KeyType&, MappedType*); 74 75 iterator uncheckedBegin() { return m_map.begin(); } 76 iterator uncheckedEnd() { return m_map.end(); } 77 78 const_iterator uncheckedBegin() const { return m_map.begin(); } 79 const_iterator uncheckedEnd() const { return m_map.end(); } 80 81 bool isValid(iterator it) const { return Heap::isMarked(it->second.get()); } 82 bool isValid(const_iterator it) const { return Heap::isMarked(it->second.get()); } 83 84 private: 85 HashMap<KeyType, DeprecatedPtr<MappedType> > m_map; 148 MapType m_map; 86 149 }; 87 88 template<typename KeyType, typename MappedType>89 inline MappedType* WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const90 {91 MappedType* result = m_map.get(key).get();92 if (result == HashTraits<MappedType*>::emptyValue())93 return result;94 if (!Heap::isMarked(result))95 return HashTraits<MappedType*>::emptyValue();96 return result;97 }98 99 template<typename KeyType, typename MappedType>100 MappedType* WeakGCMap<KeyType, MappedType>::take(const KeyType& key)101 {102 MappedType* result = m_map.take(key).get();103 if (result == HashTraits<MappedType*>::emptyValue())104 return result;105 if (!Heap::isMarked(result))106 return HashTraits<MappedType*>::emptyValue();107 return result;108 }109 110 template<typename KeyType, typename MappedType>111 pair<typename WeakGCMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, MappedType* value)112 {113 Heap::setMarked(value); // If value is newly allocated, it's not marked, so mark it now.114 pair<iterator, bool> result = m_map.add(key, value);115 if (!result.second) { // pre-existing entry116 result.second = !Heap::isMarked(result.first->second.get());117 result.first->second = value;118 }119 return result;120 }121 122 template<typename KeyType, typename MappedType>123 bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, MappedType* value)124 {125 iterator it = m_map.find(key);126 if (it == m_map.end())127 return false;128 if (it->second.get() != value)129 return false;130 m_map.remove(it);131 return true;132 }133 150 134 151 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.