diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/Weak.h')
-rw-r--r-- | Source/JavaScriptCore/heap/Weak.h | 190 |
1 files changed, 37 insertions, 153 deletions
diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h index efb2a9a56..5c901df22 100644 --- a/Source/JavaScriptCore/heap/Weak.h +++ b/Source/JavaScriptCore/heap/Weak.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,22 +26,32 @@ #ifndef Weak_h #define Weak_h -#include "PassWeak.h" -#include "WeakSetInlines.h" -#include <wtf/Assertions.h> -#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/NullPtr.h> namespace JSC { -template<typename T> class Weak : public WeakImplAccessor<Weak<T>, T> { +template<typename T> class PassWeak; +class WeakImpl; +class WeakHandleOwner; + +// This is a free function rather than a Weak<T> member function so we can put it in Weak.cpp. +JS_EXPORT_PRIVATE void weakClearSlowCase(WeakImpl*&); + +template<typename T> class Weak { WTF_MAKE_NONCOPYABLE(Weak); public: - friend class WeakImplAccessor<Weak<T>, T>; - typedef typename WeakImplAccessor<Weak<T>, T>::GetType GetType; + Weak() + : m_impl(0) + { + } - Weak(); - Weak(std::nullptr_t); - Weak(GetType, WeakHandleOwner* = 0, void* context = 0); + explicit Weak(std::nullptr_t) + : m_impl(0) + { + } + + explicit Weak(T*, WeakHandleOwner* = 0, void* context = 0); enum HashTableDeletedValueTag { HashTableDeletedValue }; bool isHashTableDeletedValue() const; @@ -49,19 +59,32 @@ public: template<typename U> Weak(const PassWeak<U>&); - ~Weak(); + ~Weak() + { + clear(); + } void swap(Weak&); Weak& operator=(const PassWeak<T>&); bool operator!() const; + T* operator->() const; + T& operator*() const; + T* get() const; + + bool was(T*) const; // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef JSValue (HandleBase::*UnspecifiedBoolType); + typedef void* (Weak::*UnspecifiedBoolType); operator UnspecifiedBoolType*() const; PassWeak<T> release(); - void clear(); + void clear() + { + if (!m_impl) + return; + weakClearSlowCase(m_impl); + } private: static WeakImpl* hashTableDeletedValue(); @@ -69,145 +92,6 @@ private: WeakImpl* m_impl; }; -template<typename T> inline Weak<T>::Weak() - : m_impl(0) -{ -} - -template<typename T> inline Weak<T>::Weak(std::nullptr_t) - : m_impl(0) -{ -} - -template<typename T> inline Weak<T>::Weak(typename Weak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context) - : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0) -{ -} - -template<typename T> inline bool Weak<T>::isHashTableDeletedValue() const -{ - return m_impl == hashTableDeletedValue(); -} - -template<typename T> inline Weak<T>::Weak(typename Weak<T>::HashTableDeletedValueTag) - : m_impl(hashTableDeletedValue()) -{ -} - -template<typename T> template<typename U> inline Weak<T>::Weak(const PassWeak<U>& other) - : m_impl(other.leakImpl()) -{ -} - -template<typename T> inline Weak<T>::~Weak() -{ - clear(); -} - -template<class T> inline void swap(Weak<T>& a, Weak<T>& b) -{ - a.swap(b); -} - -template<typename T> inline void Weak<T>::swap(Weak& other) -{ - std::swap(m_impl, other.m_impl); -} - -template<typename T> inline Weak<T>& Weak<T>::operator=(const PassWeak<T>& o) -{ - clear(); - m_impl = o.leakImpl(); - return *this; -} - -template<typename T> inline bool Weak<T>::operator!() const -{ - return !m_impl || !m_impl->jsValue() || m_impl->state() != WeakImpl::Live; -} - -template<typename T> inline Weak<T>::operator UnspecifiedBoolType*() const -{ - return reinterpret_cast<UnspecifiedBoolType*>(!!*this); -} - -template<typename T> inline PassWeak<T> Weak<T>::release() -{ - PassWeak<T> tmp = adoptWeak<T>(m_impl); - m_impl = 0; - return tmp; -} - -template<typename T> inline void Weak<T>::clear() -{ - if (!m_impl) - return; - WeakSet::deallocate(m_impl); - m_impl = 0; -} - -template<typename T> inline WeakImpl* Weak<T>::hashTableDeletedValue() -{ - return reinterpret_cast<WeakImpl*>(-1); -} - -template <typename T> inline bool operator==(const Weak<T>& lhs, const Weak<T>& rhs) -{ - return lhs.get() == rhs.get(); -} - -// This function helps avoid modifying a weak table while holding an iterator into it. (Object allocation -// can run a finalizer that modifies the table. We avoid that by requiring a pre-constructed object as our value.) -template<typename Map, typename Key, typename Value> inline void weakAdd(Map& map, const Key& key, Value value) -{ - ASSERT(!map.get(key)); - map.set(key, value); // The table may still have a zombie for value. -} - -template<typename Map, typename Key, typename Value> inline void weakRemove(Map& map, const Key& key, Value value) -{ - typename Map::iterator it = map.find(key); - ASSERT_UNUSED(value, value); - ASSERT(it != map.end()); - ASSERT(it->value.was(value)); - ASSERT(!it->value); - map.remove(it); -} - -template<typename T> inline void weakClear(Weak<T>& weak, typename Weak<T>::GetType value) -{ - ASSERT_UNUSED(value, value); - ASSERT(weak.was(value)); - ASSERT(!weak); - weak.clear(); -} - } // namespace JSC -namespace WTF { - -template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits { - static const bool canCompareWithMemcmp = false; -}; - -template<typename T> struct HashTraits<JSC::Weak<T> > : SimpleClassHashTraits<JSC::Weak<T> > { - typedef JSC::Weak<T> StorageType; - - typedef std::nullptr_t EmptyValueType; - static EmptyValueType emptyValue() { return nullptr; } - - typedef JSC::PassWeak<T> PassInType; - static void store(PassInType value, StorageType& storage) { storage = value; } - - typedef JSC::PassWeak<T> PassOutType; - static PassOutType passOut(StorageType& value) { return value.release(); } - static PassOutType passOut(EmptyValueType) { return PassOutType(); } - - typedef typename StorageType::GetType PeekType; - static PeekType peek(const StorageType& value) { return value.get(); } - static PeekType peek(EmptyValueType) { return PeekType(); } -}; - -} - #endif // Weak_h |