From d441d6f39bb846989d95bcf5caf387b42414718d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 13 Sep 2013 12:51:20 +0200 Subject: Import Qt5x2 branch of QtWebkit for Qt 5.2 Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen --- Source/JavaScriptCore/runtime/WeakGCMap.h | 118 +++++++++++++++++------------- 1 file changed, 67 insertions(+), 51 deletions(-) (limited to 'Source/JavaScriptCore/runtime/WeakGCMap.h') 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 +#include #include namespace JSC { -// A HashMap for GC'd values that removes entries when the associated value -// dies. -template struct DefaultWeakGCMapFinalizerCallback { - static void* finalizerContextFor(KeyType key) - { - return reinterpret_cast(key); - } +// A HashMap with Weak values, which automatically removes values once they're garbage collected. - static KeyType keyForFinalizer(void* context, typename HandleTypes::ExternalType) - { - return reinterpret_cast(context); - } -}; - -template, typename HashArg = typename DefaultHash::Hash, typename KeyTraitsArg = HashTraits > -class WeakGCMap : private WeakHandleOwner { - WTF_MAKE_FAST_ALLOCATED; - WTF_MAKE_NONCOPYABLE(WeakGCMap); - - typedef HashMap MapType; - typedef typename HandleTypes::ExternalType ExternalType; +template::Hash, + typename KeyTraitsArg = HashTraits > +class WeakGCMap : public HashMap, HashArg, KeyTraitsArg> { + typedef Weak MappedType; + typedef HashMap Base; + typedef WeakGCMap Self; + typedef HashTraits 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::getFromSlot(const_cast(&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(this)->find(key); } - ~WeakGCMap() + bool contains(const KeyType& key) const { - clear(); + return find(key) != end(); } - + private: - virtual void finalize(Handle handle, void* context) + static const int minGCThreshold = 3; + + void gcMap() + { + Vector 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::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 +const int WeakGCMap::minGCThreshold; + } // namespace JSC #endif // WeakGCMap_h -- cgit v1.2.1