Index: Source/heap/Visitor.h |
diff --git a/Source/heap/Visitor.h b/Source/heap/Visitor.h |
index 4331ccca8e0c1dd5530b2619fb76bcb80f38a268..716dffe2cd43c72b8027959305170220b2a8ce52 100644 |
--- a/Source/heap/Visitor.h |
+++ b/Source/heap/Visitor.h |
@@ -195,6 +195,11 @@ public: |
template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
+template<typename Collection> |
+struct OffHeapCollectionTraceTrait { |
+ static void trace(Visitor*, const Collection&); |
+}; |
+ |
template<typename T> |
struct ObjectAliveTrait { |
static bool isAlive(Visitor*, T); |
@@ -335,6 +340,53 @@ private: |
*cell = 0; |
} |
}; |
+template<typename T, typename HashFunctions, typename Traits> |
+struct OffHeapCollectionTraceTrait<WTF::HashSet<T, WTF::DefaultAllocator, HashFunctions, Traits> > { |
+ typedef WTF::HashSet<T, WTF::DefaultAllocator, HashFunctions, Traits> 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, WTF::DefaultAllocator, HashFunctions, KeyTraits, ValueTraits> > { |
+ typedef WTF::HashMap<Key, Value, WTF::DefaultAllocator, HashFunctions, KeyTraits, ValueTraits> 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); |
+ } |
+}; |
template<typename T, typename Traits = WTF::VectorTraits<T> > |
class HeapVectorBacking; |
@@ -347,37 +399,63 @@ inline void doNothingTrace(Visitor*, void*) { } |
// 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) |
#undef DECLARE_DO_NOTHING_TRAIT |
+// Vectors are simple collections, and it's possible to mark vectors in a more |
+// general way so that collections of objects (not pointers to objects) can be |
+// marked. |
+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)); |
+ } |
+}; |
+ |
+// Fallback definition. |
+template<typename Collection> |
+void OffHeapCollectionTraceTrait<Collection>::trace(Visitor* visitor, const Collection& collection) |
+{ |
+ if (collection.isEmpty()) |
+ return; |
+ for (typename Collection::const_iterator it = collection.begin(), end = collection.end(); it != end; ++it) |
+ visitor->trace(*it); |
+} |
+ |
#ifndef NDEBUG |
template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const T* t) |
{ |