Index: Source/heap/Visitor.h |
diff --git a/Source/heap/Visitor.h b/Source/heap/Visitor.h |
index 4ddaea3aa4f1f620cc347102b94bb200dd604cf4..40e75b5cca872f4d22359bd12ee40dfc02f76ffc 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 mark(Visitor*, const Collection&); |
haraken
2014/01/15 04:48:35
Shouldn't this be "trace" instead of "mark"?
Erik Corry
2014/01/15 09:27:32
Done.
|
+}; |
+ |
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 mark(Visitor* v, const HashSet& set) |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
|
+ { |
+ 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(v, *it); |
+ } |
+ COMPILE_ASSERT(!Traits::isWeak, WeakOffHeapCollectionsConsideredDangerous); |
+ } |
+}; |
+ |
+template<typename T, size_t inlineCapacity, typename HashFunctions> |
+struct OffHeapCollectionTraceTrait<WTF::ListHashSet<T, inlineCapacity, HashFunctions> > { |
+ typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; |
+ |
+ static void mark(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 mark(Visitor* v, const HashMap& map) |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
|
+ { |
+ 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(v, it->key); |
+ CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTraits::isWeak, false, Value, ValueTraits>::mark(v, it->value); |
+ } |
+ } |
haraken
2014/01/15 04:48:35
Shouldn't this be:
for (typename HashMap::const_i
Erik Corry
2014/01/15 09:27:32
This would go through the loop even if nothing nee
|
+ COMPILE_ASSERT(!KeyTraits::isWeak, WeakOffHeapCollectionsConsideredDangerous); |
+ COMPILE_ASSERT(!ValueTraits::isWeak, WeakOffHeapCollectionsConsideredDangerous); |
+ } |
+}; |
template<typename T, typename Traits = WTF::VectorTraits<T> > |
class HeapVectorBacking; |
@@ -376,6 +428,31 @@ 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 mark(Visitor* v, const Vector& vector) |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
|
+ { |
+ if (vector.isEmpty()) |
+ return; |
+ for (typename Vector::const_iterator it = vector.begin(), end = vector.end(); it != end; ++it) |
+ TraceTrait<T>::trace(v, const_cast<T*>(it)); |
+ } |
+}; |
+ |
+// Fallback definition. |
+template<typename Collection> void OffHeapCollectionTraceTrait<Collection>::mark(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) |
{ |