#include "wtf/HashTraits.h"
#include "wtf/ListHashSet.h"
#include "wtf/OwnPtr.h"
+#include "wtf/RefPtr.h"
#ifndef NDEBUG
#define DEBUG_ONLY(x) x
template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
+template<typename Collection>
+struct OffHeapCollectionTraceTrait;
+
template<typename T>
struct ObjectAliveTrait {
static bool isAlive(Visitor*, T);
mark(t.get());
}
+ // Fallback method used only when we need to trace raw pointers of T.
+ // This is the case when a member is a union where we do not support members.
+ template<typename T>
+ void trace(T* t)
+ {
+ mark(t);
+ }
+
// WeakMember version of the templated trace method. It doesn't keep
// the traced thing alive, but will write null to the WeakMember later
// if the pointed-to object is dead.
const_cast<T&>(t).trace(this);
}
+ // The following mark methods are for off-heap collections.
+ template<typename T, size_t inlineCapacity>
+ void trace(const Vector<T, inlineCapacity, WTF::DefaultAllocator>& vector)
+ {
+ OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::DefaultAllocator> >::trace(this, vector);
+ }
+
+ template<typename T, typename U, typename V>
+ void trace(const HashSet<T, U, V, WTF::DefaultAllocator>& hashSet)
+ {
+ OffHeapCollectionTraceTrait<HashSet<T, U, V, WTF::DefaultAllocator> >::trace(this, hashSet);
+ }
+
+ template<typename T, size_t inlineCapacity, typename U>
+ void trace(const ListHashSet<T, inlineCapacity, U>& hashSet)
+ {
+ OffHeapCollectionTraceTrait<ListHashSet<T, inlineCapacity, U> >::trace(this, hashSet);
+ }
+
+ template<typename T, size_t N>
+ void trace(const Deque<T, N>& deque)
+ {
+ OffHeapCollectionTraceTrait<Deque<T, N> >::trace(this, deque);
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
+ void trace(const HashMap<T, U, V, W, X, WTF::DefaultAllocator>& map)
+ {
+ OffHeapCollectionTraceTrait<HashMap<T, U, V, W, X, WTF::DefaultAllocator> >::trace(this, map);
+ }
+
// OwnPtrs that are traced are treated as part objects and the
// trace method of the owned object is called.
template<typename T>
t->trace(this);
}
+ // This trace method is to trace a RefPtrWillBeMember when ENABLE(OILPAN)
+ // is not enabled.
+ // Remove this once we remove RefPtrWillBeMember.
+ template<typename T>
+ void trace(const RefPtr<T>&)
+ {
+#if ENABLE(OILPAN)
+ // RefPtrs should never be traced.
+ ASSERT_NOT_REACHED();
+#endif
+ }
+
+#if !ENABLE(OILPAN)
+ // Similarly, this trace method is to trace a RawPtrWillBeMember
+ // when ENABLE(OILPAN) is not enabled.
+ // Remove this once we remove RawPtrWillBeMember.
+ template<typename T>
+ void trace(const RawPtr<T>&)
+ {
+ }
+#endif
+
// This method marks an object and adds it to the set of objects
// that should have their trace method called. Since not all
// objects have vtables we have to have the callback as an
}
};
+template<typename T, typename HashFunctions, typename Traits>
+struct OffHeapCollectionTraceTrait<WTF::HashSet<T, HashFunctions, Traits, WTF::DefaultAllocator> > {
+ typedef WTF::HashSet<T, HashFunctions, Traits, WTF::DefaultAllocator> HashSet;
+
+ static void trace(Visitor* visitor, const HashSet& set)
+ {
+ if (set.isEmpty())
+ return;
+ if (WTF::NeedsTracing<T>::value) {
+ for (typename HashSet::const_iterator it = set.begin(), end = set.end(); it != end; ++it)
+ CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, false, T, Traits>::mark(visitor, *it);
+ }
+ COMPILE_ASSERT(!Traits::isWeak, WeakOffHeapCollectionsConsideredDangerous0);
+ }
+};
+
+template<typename T, size_t inlineCapacity, typename HashFunctions>
+struct OffHeapCollectionTraceTrait<WTF::ListHashSet<T, inlineCapacity, HashFunctions> > {
+ typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet;
+
+ static void trace(Visitor* visitor, const ListHashSet& set)
+ {
+ if (set.isEmpty())
+ return;
+ for (typename ListHashSet::const_iterator it = set.begin(), end = set.end(); it != end; ++it)
+ visitor->trace(*it);
+ }
+};
+
+template<typename Key, typename Value, typename HashFunctions, typename KeyTraits, typename ValueTraits>
+struct OffHeapCollectionTraceTrait<WTF::HashMap<Key, Value, HashFunctions, KeyTraits, ValueTraits, WTF::DefaultAllocator> > {
+ typedef WTF::HashMap<Key, Value, HashFunctions, KeyTraits, ValueTraits, WTF::DefaultAllocator> HashMap;
+
+ static void trace(Visitor* visitor, const HashMap& map)
+ {
+ if (map.isEmpty())
+ return;
+ if (WTF::NeedsTracing<Key>::value || WTF::NeedsTracing<Value>::value) {
+ for (typename HashMap::const_iterator it = map.begin(), end = map.end(); it != end; ++it) {
+ CollectionBackingTraceTrait<KeyTraits::needsTracing, KeyTraits::isWeak, false, Key, KeyTraits>::mark(visitor, it->key);
+ CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTraits::isWeak, false, Value, ValueTraits>::mark(visitor, it->value);
+ }
+ }
+ COMPILE_ASSERT(!KeyTraits::isWeak, WeakOffHeapCollectionsConsideredDangerous1);
+ COMPILE_ASSERT(!ValueTraits::isWeak, WeakOffHeapCollectionsConsideredDangerous2);
+ }
+};
+
+// We trace vectors by using the trace trait on each element, which means you
+// can have vectors of general objects (not just pointers to objects) that can
+// be traced.
+template<typename T, size_t N>
+struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > {
+ typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector;
+
+ static void trace(Visitor* visitor, const Vector& vector)
+ {
+ if (vector.isEmpty())
+ return;
+ for (typename Vector::const_iterator it = vector.begin(), end = vector.end(); it != end; ++it)
+ TraceTrait<T>::trace(visitor, const_cast<T*>(it));
+ }
+};
+
+template<typename T, size_t N>
+struct OffHeapCollectionTraceTrait<WTF::Deque<T, N> > {
+ typedef WTF::Deque<T, N> Deque;
+
+ static void trace(Visitor* visitor, const Deque& deque)
+ {
+ if (deque.isEmpty())
+ return;
+ for (typename Deque::const_iterator it = deque.begin(), end = deque.end(); it != end; ++it)
+ TraceTrait<T>::trace(visitor, const_cast<T*>(&(*it)));
+ }
+};
+
template<typename T, typename Traits = WTF::VectorTraits<T> >
class HeapVectorBacking;
template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
// specialized template instantiation here that will be selected in preference
// to the default. Most of them do nothing, since the type in question cannot
// point to other heap allocated objects.
-#define ITERATE_DO_NOTHING_TYPES(f) \
- f(uint8_t) \
+#define ITERATE_DO_NOTHING_TYPES(f) \
+ f(uint8_t) \
f(void)
-#define DECLARE_DO_NOTHING_TRAIT(type) \
- template<> \
- class TraceTrait<type> { \
- public: \
- static void checkTypeMarker(Visitor*, const void*) { } \
- static void mark(Visitor* v, const type* p) { \
- v->mark(p, reinterpret_cast<TraceCallback>(0)); \
- } \
- }; \
- template<> \
- struct FinalizerTrait<type> { \
- static void finalize(void*) { } \
- static const bool nonTrivialFinalizer = false; \
- }; \
- template<> \
- struct HEAP_EXPORT GCInfoTrait<type> { \
- static const GCInfo* get() \
- { \
- return &info; \
- } \
- static const GCInfo info; \
+#define DECLARE_DO_NOTHING_TRAIT(type) \
+ template<> \
+ class TraceTrait<type> { \
+ public: \
+ static void checkTypeMarker(Visitor*, const void*) { } \
+ static void mark(Visitor* visitor, const type* p) { \
+ visitor->mark(p, reinterpret_cast<TraceCallback>(0)); \
+ } \
+ }; \
+ template<> \
+ struct FinalizerTrait<type> { \
+ static void finalize(void*) { } \
+ static const bool nonTrivialFinalizer = false; \
+ }; \
+ template<> \
+ struct HEAP_EXPORT GCInfoTrait<type> { \
+ static const GCInfo* get() \
+ { \
+ return &info; \
+ } \
+ static const GCInfo info; \
};
ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT)