Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2280)

Unified Diff: Source/platform/heap/HeapTest.cpp

Issue 327323008: Oilpan: Test/example showing how to get the GC to remove empty sets from a map (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/HeapTest.cpp
diff --git a/Source/platform/heap/HeapTest.cpp b/Source/platform/heap/HeapTest.cpp
index 114078c1032f37b661463e63e1bc6217b08bcf4f..567c0483f0244acff44cb219fc278328149d885f 100644
--- a/Source/platform/heap/HeapTest.cpp
+++ b/Source/platform/heap/HeapTest.cpp
@@ -4272,4 +4272,78 @@ TEST(HeapTest, Bind)
EXPECT_EQ(1, UseMixin::s_traceCount);
}
+typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
+
+// These special traits will remove a set from a map when the set is empty.
+struct EmptyClearingHastSetTraits : HashTraits<WeakSet> {
+ static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCollections;
+ static bool shouldRemoveFromCollection(Visitor* visitor, WeakSet& set)
+ {
+ return set.isEmpty(); // Remove this set from any maps it is in.
+ }
+ static void traceInCollection(Visitor* visitor, WeakSet& set, WebCore::ShouldWeakPointersBeMarkedStrongly strongify)
+ {
+ // We just trace normally, which will invoke the normal weak handling
+ // of the set, removing individual items.
+ set.trace(visitor);
+ }
+};
+
+// This is an example to show how you can remove entries from a T->WeakSet map
+// when the weak sets become empty. For this example we are using a type that
+// is given to use (HeapHashSet) rather than a type of our own. This means:
+// 1) We can't just override the HashTrait for the type since this would affect
+// all collections that use this kind of weak set. Instead we have our own
+// traits and use a map with custom traits for the value type. These traits
+// are the 5th template parameter, so we have to supply default values for
+// the 3rd and 4th template parameters
+// 2) We can't just inherit from WeakHandlingHashTraits, since that trait
+// assumes we can add methods to the type, but we can't add methods to
+// HeapHashSet.
+TEST(HeapTest, RemoveEmptySets)
+{
+ HeapStats initialHeapSize;
+ clearOutOldGarbage(&initialHeapSize);
+ OffHeapInt::s_destructorCalls = 0;
+
+ Persistent<IntWrapper> livingInt(IntWrapper::create(42));
+
+ typedef RefPtr<OffHeapInt> Key;
+ typedef HeapHashMap<Key, WeakSet, WTF::DefaultHash<Key>::Hash, HashTraits<Key>, EmptyClearingHastSetTraits> Map;
+ Persistent<Map> map(new Map());
+ map->add(OffHeapInt::create(1), WeakSet());
+ {
+ WeakSet& set = map->begin()->value;
+ set.add(IntWrapper::create(103)); // Weak set can't hold this long.
+ set.add(livingInt); // This prevents the set from being emptied.
+ EXPECT_EQ(2u, set.size());
+ }
+
+ // The set we add here is empty, so the entry will be removed from the map
+ // at the next GC.
+ map->add(OffHeapInt::create(2), WeakSet());
+ EXPECT_EQ(2u, map->size());
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(1u, map->size()); // The one with key 2 was removed.
+ EXPECT_EQ(1, OffHeapInt::s_destructorCalls);
+ {
+ WeakSet& set = map->begin()->value;
+ EXPECT_EQ(1u, set.size());
+ }
+
+ livingInt.clear(); // The weak set can no longer keep the '42' alive now.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ if (map->size() == 1u) {
+ // If the weak processing for the set ran after the weak processing for
+ // the map, then the set was not empty, and so the entry in the map was
+ // not removed yet.
+ WeakSet& set = map->begin()->value;
+ EXPECT_EQ(0u, set.size());
+ }
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(0u, map->size());
+}
+
} // WebCore namespace
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698