diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/JavaScriptCore/runtime/WeakGCMap.h | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/runtime/WeakGCMap.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/WeakGCMap.h | 118 |
1 files changed, 67 insertions, 51 deletions
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h index 52e5e2946..f741fa4c4 100644 --- a/Source/JavaScriptCore/runtime/WeakGCMap.h +++ b/Source/JavaScriptCore/runtime/WeakGCMap.h @@ -26,88 +26,104 @@ #ifndef WeakGCMap_h #define WeakGCMap_h -#include "Handle.h" -#include "JSGlobalData.h" +#include <heap/Weak.h> +#include <heap/WeakInlines.h> #include <wtf/HashMap.h> namespace JSC { -// A HashMap for GC'd values that removes entries when the associated value -// dies. -template <typename KeyType, typename MappedType> struct DefaultWeakGCMapFinalizerCallback { - static void* finalizerContextFor(KeyType key) - { - return reinterpret_cast<void*>(key); - } +// A HashMap with Weak<JSCell> values, which automatically removes values once they're garbage collected. - 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, WeakImpl*, HashArg, KeyTraitsArg> MapType; - typedef typename HandleTypes<MappedType>::ExternalType ExternalType; +template<typename KeyArg, typename RawMappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash, + typename KeyTraitsArg = HashTraits<KeyArg> > +class WeakGCMap : public HashMap<KeyArg, Weak<RawMappedArg>, HashArg, KeyTraitsArg> { + typedef Weak<RawMappedArg> MappedType; + typedef HashMap<KeyArg, MappedType, HashArg, KeyTraitsArg> Base; + typedef WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg> Self; + typedef HashTraits<MappedType> MappedTraits; + typedef typename MappedTraits::PassInType MappedPassInType; public: + typedef typename Base::KeyType KeyType; + typedef typename Base::AddResult AddResult; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + using Base::begin; + using Base::end; + using Base::size; + using Base::remove; + WeakGCMap() + : m_gcThreshold(minGCThreshold) { } - void clear() + AddResult set(const KeyType& key, MappedPassInType value) { - typename MapType::iterator end = m_map.end(); - for (typename MapType::iterator ptr = m_map.begin(); ptr != end; ++ptr) - WeakSet::deallocate(ptr->value); - m_map.clear(); + gcMapIfNeeded(); + return Base::set(key, value); } - ExternalType get(const KeyType& key) const + AddResult add(const KeyType& key, MappedPassInType value) { - WeakImpl* impl = m_map.get(key); - if (!impl || impl->state() != WeakImpl::Live) - return ExternalType(); - return HandleTypes<MappedType>::getFromSlot(const_cast<JSValue*>(&impl->jsValue())); + gcMapIfNeeded(); + AddResult addResult = Base::add(key, nullptr); + if (!addResult.iterator->value) { // New value or found a zombie value. + addResult.isNewEntry = true; + addResult.iterator->value = value; + } + return addResult; } - void set(JSGlobalData& globalData, const KeyType& key, ExternalType value) + iterator find(const KeyType& key) { - ASSERT_UNUSED(globalData, globalData.apiLock().currentThreadIsHoldingLock()); - typename MapType::AddResult result = m_map.add(key, 0); - if (!result.isNewEntry) - WeakSet::deallocate(result.iterator->value); - result.iterator->value = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key)); + iterator it = Base::find(key); + iterator end = Base::end(); + if (it != end && !it->value) // Found a zombie value. + return end; + return it; } - void remove(const KeyType& key) + const_iterator find(const KeyType& key) const { - WeakImpl* impl = m_map.take(key); - if (!impl) - return; - WeakSet::deallocate(impl); + return const_cast<Self*>(this)->find(key); } - ~WeakGCMap() + bool contains(const KeyType& key) const { - clear(); + return find(key) != end(); } - + private: - virtual void finalize(Handle<Unknown> handle, void* context) + static const int minGCThreshold = 3; + + void gcMap() + { + Vector<KeyType, 4> zombies; + iterator end = this->end(); + for (iterator it = begin(); it != end; ++it) { + if (!it->value) + zombies.append(it->key); + } + for (size_t i = 0; i < zombies.size(); ++i) + remove(zombies[i]); + } + + void gcMapIfNeeded() { - WeakImpl* impl = m_map.take(FinalizerCallback::keyForFinalizer(context, HandleTypes<MappedType>::getFromSlot(handle.slot()))); - ASSERT(impl); - WeakSet::deallocate(impl); + if (size() < m_gcThreshold) + return; + + gcMap(); + m_gcThreshold = std::max(minGCThreshold, size() * 2 - 1); } - MapType m_map; + int m_gcThreshold; }; +template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg> +const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold; + } // namespace JSC #endif // WeakGCMap_h |