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

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

Issue 228403002: Deque: Add HeapDeque and prevent buggy use of swap and operator= (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix Ians nit Created 6 years, 8 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 | « Source/platform/heap/Heap.h ('k') | Source/wtf/Deque.h » ('j') | 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 a2b22f9bb7fdfc9d2d071960b20b7f5111d67c9c..06306253e1d5bd9a8c048d39062d1d3a68a2d6ab 100644
--- a/Source/platform/heap/HeapTest.cpp
+++ b/Source/platform/heap/HeapTest.cpp
@@ -1862,12 +1862,20 @@ public:
HeapVector<Member<IntWrapper>, 2> vector;
HeapVector<PairWrappedUnwrapped, 2> vectorWU;
HeapVector<PairUnwrappedWrapped, 2> vectorUW;
+ HeapDeque<Member<IntWrapper>, 0> deque;
+ HeapDeque<PairWrappedUnwrapped, 0> dequeWU;
+ HeapDeque<PairUnwrappedWrapped, 0> dequeUW;
void trace(Visitor* visitor)
{
visitor->trace(map);
visitor->trace(set);
visitor->trace(set2);
visitor->trace(vector);
+ visitor->trace(vectorWU);
+ visitor->trace(vectorUW);
+ visitor->trace(deque);
+ visitor->trace(dequeWU);
+ visitor->trace(dequeUW);
}
};
@@ -1997,6 +2005,17 @@ TEST(HeapTest, HeapVectorWithInlineCapacity)
}
}
+template<typename T, size_t inlineCapacity, typename U>
+bool dequeContains(HeapDeque<T, inlineCapacity>& deque, U u)
+{
+ typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
+ for (iterator it = deque.begin(); it != deque.end(); ++it) {
+ if (*it == u)
+ return true;
+ }
+ return false;
+}
+
TEST(HeapTest, HeapCollectionTypes)
{
HeapStats initialHeapSize;
@@ -2009,9 +2028,12 @@ TEST(HeapTest, HeapCollectionTypes)
typedef HeapHashSet<Member<IntWrapper> > MemberSet;
typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
+ typedef HeapDeque<Member<IntWrapper>, 0> MemberDeque;
typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
+ typedef HeapDeque<PairWrappedUnwrapped, 0> DequeWU;
+ typedef HeapDeque<PairUnwrappedWrapped, 0> DequeUW;
Persistent<MemberMember> memberMember = new MemberMember();
Persistent<MemberMember> memberMember2 = new MemberMember();
@@ -2026,6 +2048,12 @@ TEST(HeapTest, HeapCollectionTypes)
Persistent<VectorWU> vectorWU2 = new VectorWU();
Persistent<VectorUW> vectorUW = new VectorUW();
Persistent<VectorUW> vectorUW2 = new VectorUW();
+ Persistent<MemberDeque> deque = new MemberDeque();
+ Persistent<MemberDeque> deque2 = new MemberDeque();
+ Persistent<DequeWU> dequeWU = new DequeWU();
+ Persistent<DequeWU> dequeWU2 = new DequeWU();
+ Persistent<DequeUW> dequeUW = new DequeUW();
+ Persistent<DequeUW> dequeUW2 = new DequeUW();
Persistent<Container> container = Container::create();
clearOutOldGarbage(&initialHeapSize);
@@ -2036,17 +2064,25 @@ TEST(HeapTest, HeapCollectionTypes)
Persistent<IntWrapper> twoB(IntWrapper::create(2));
Persistent<IntWrapper> oneC(IntWrapper::create(1));
Persistent<IntWrapper> oneD(IntWrapper::create(1));
+ Persistent<IntWrapper> oneE(IntWrapper::create(1));
+ Persistent<IntWrapper> oneF(IntWrapper::create(1));
{
- IntWrapper* three(IntWrapper::create(3));
- IntWrapper* four(IntWrapper::create(4));
IntWrapper* threeB(IntWrapper::create(3));
- IntWrapper* fourB(IntWrapper::create(4));
IntWrapper* threeC(IntWrapper::create(3));
- IntWrapper* fourC(IntWrapper::create(4));
- IntWrapper* fiveC(IntWrapper::create(5));
IntWrapper* threeD(IntWrapper::create(3));
+ IntWrapper* threeE(IntWrapper::create(3));
+ IntWrapper* threeF(IntWrapper::create(3));
+ IntWrapper* three(IntWrapper::create(3));
+ IntWrapper* fourB(IntWrapper::create(4));
+ IntWrapper* fourC(IntWrapper::create(4));
IntWrapper* fourD(IntWrapper::create(4));
+ IntWrapper* fourE(IntWrapper::create(4));
+ IntWrapper* fourF(IntWrapper::create(4));
+ IntWrapper* four(IntWrapper::create(4));
+ IntWrapper* fiveC(IntWrapper::create(5));
IntWrapper* fiveD(IntWrapper::create(5));
+ IntWrapper* fiveE(IntWrapper::create(5));
+ IntWrapper* fiveF(IntWrapper::create(5));
// Member Collections.
memberMember2->add(one, two);
@@ -2067,20 +2103,36 @@ TEST(HeapTest, HeapCollectionTypes)
set2->add(four);
set->add(oneB);
vector->append(oneB);
+ deque->append(oneB);
vector2->append(threeB);
vector2->append(fourB);
+ deque2->append(threeE);
+ deque2->append(fourE);
vectorWU->append(PairWrappedUnwrapped(&*oneC, 42));
+ dequeWU->append(PairWrappedUnwrapped(&*oneE, 42));
vectorWU2->append(PairWrappedUnwrapped(&*threeC, 43));
vectorWU2->append(PairWrappedUnwrapped(&*fourC, 44));
vectorWU2->append(PairWrappedUnwrapped(&*fiveC, 45));
+ dequeWU2->append(PairWrappedUnwrapped(&*threeE, 43));
+ dequeWU2->append(PairWrappedUnwrapped(&*fourE, 44));
+ dequeWU2->append(PairWrappedUnwrapped(&*fiveE, 45));
vectorUW->append(PairUnwrappedWrapped(1, &*oneD));
vectorUW2->append(PairUnwrappedWrapped(103, &*threeD));
vectorUW2->append(PairUnwrappedWrapped(104, &*fourD));
vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD));
+ dequeUW->append(PairUnwrappedWrapped(1, &*oneF));
+ dequeUW2->append(PairUnwrappedWrapped(103, &*threeF));
+ dequeUW2->append(PairUnwrappedWrapped(104, &*fourF));
+ dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF));
+
+ EXPECT_TRUE(dequeContains(*deque, oneB));
// Collect garbage. This should change nothing since we are keeping
// alive the IntWrapper objects with on-stack pointers.
Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+
+ EXPECT_TRUE(dequeContains(*deque, oneB));
+
EXPECT_EQ(0u, memberMember->size());
EXPECT_EQ(4u, memberMember2->size());
EXPECT_EQ(4u, primitiveMember->size());
@@ -2093,6 +2145,12 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_EQ(3u, vectorWU2->size());
EXPECT_EQ(1u, vectorUW->size());
EXPECT_EQ(3u, vectorUW2->size());
+ EXPECT_EQ(1u, deque->size());
+ EXPECT_EQ(2u, deque2->size());
+ EXPECT_EQ(1u, dequeWU->size());
+ EXPECT_EQ(3u, dequeWU2->size());
+ EXPECT_EQ(1u, dequeUW->size());
+ EXPECT_EQ(3u, dequeUW2->size());
MemberVector& cvec = container->vector;
cvec.swap(*vector.get());
@@ -2109,6 +2167,21 @@ TEST(HeapTest, HeapCollectionTypes)
vectorUW2->swap(cvecUW);
vectorUW->swap(cvecUW);
+ MemberDeque& cDeque = container->deque;
+ cDeque.swap(*deque.get());
+ deque2->swap(cDeque);
+ deque->swap(cDeque);
+
+ DequeWU& cDequeWU = container->dequeWU;
+ cDequeWU.swap(*dequeWU.get());
+ dequeWU2->swap(cDequeWU);
+ dequeWU->swap(cDequeWU);
+
+ DequeUW& cDequeUW = container->dequeUW;
+ cDequeUW.swap(*dequeUW.get());
+ dequeUW2->swap(cDequeUW);
+ dequeUW->swap(cDequeUW);
+
// Swap set and set2 in a roundabout way.
MemberSet& cset1 = container->set;
MemberSet& cset2 = container->set2;
@@ -2143,8 +2216,12 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_TRUE(set2->contains(oneB));
EXPECT_TRUE(vector->contains(threeB));
EXPECT_TRUE(vector->contains(fourB));
+ EXPECT_TRUE(dequeContains(*deque, threeE));
+ EXPECT_TRUE(dequeContains(*deque, fourE));
EXPECT_TRUE(vector2->contains(oneB));
EXPECT_FALSE(vector2->contains(threeB));
+ EXPECT_TRUE(dequeContains(*deque2, oneB));
+ EXPECT_FALSE(dequeContains(*deque2, threeE));
EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*threeC, 43)));
EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fourC, 44)));
EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fiveC, 45)));
@@ -2155,6 +2232,16 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(105, &*fiveD)));
EXPECT_TRUE(vectorUW2->contains(PairUnwrappedWrapped(1, &*oneD)));
EXPECT_FALSE(vectorUW2->contains(PairUnwrappedWrapped(103, &*threeD)));
+ EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*threeE, 43)));
+ EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fourE, 44)));
+ EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45)));
+ EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42)));
+ EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE, 43)));
+ EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*threeF)));
+ EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*fourF)));
+ EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*fiveF)));
+ EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)));
+ EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*threeF)));
}
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
@@ -2169,6 +2256,10 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_EQ(1u, vector2->size());
EXPECT_EQ(3u, vectorUW->size());
EXPECT_EQ(1u, vector2->size());
+ EXPECT_EQ(2u, deque->size());
+ EXPECT_EQ(1u, deque2->size());
+ EXPECT_EQ(3u, dequeUW->size());
+ EXPECT_EQ(1u, deque2->size());
EXPECT_TRUE(memberMember->get(one) == two);
EXPECT_TRUE(primitiveMember->get(1) == two);
@@ -2181,6 +2272,7 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_TRUE(set2->contains(oneB));
EXPECT_EQ(3, vector->at(0)->value());
EXPECT_EQ(4, vector->at(1)->value());
+ EXPECT_EQ(3, deque->begin()->get()->value());
}
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
@@ -2197,6 +2289,12 @@ TEST(HeapTest, HeapCollectionTypes)
EXPECT_EQ(1u, vectorWU2->size());
EXPECT_EQ(3u, vectorUW->size());
EXPECT_EQ(1u, vectorUW2->size());
+ EXPECT_EQ(2u, deque->size());
+ EXPECT_EQ(1u, deque2->size());
+ EXPECT_EQ(3u, dequeWU->size());
+ EXPECT_EQ(1u, dequeWU2->size());
+ EXPECT_EQ(3u, dequeUW->size());
+ EXPECT_EQ(1u, dequeUW2->size());
}
template<typename T>
@@ -2913,10 +3011,12 @@ TEST(HeapTest, PersistentHeapCollectionTypes)
typedef PersistentHeapVector<Member<IntWrapper> > PVec;
typedef PersistentHeapHashSet<Member<IntWrapper> > PSet;
typedef PersistentHeapHashMap<Member<IntWrapper>, Member<IntWrapper> > PMap;
+ typedef PersistentHeapDeque<Member<IntWrapper> > PDeque;
clearOutOldGarbage(&initialHeapSize);
{
PVec pVec;
+ PDeque pDeque;
PSet pSet;
PMap pMap;
@@ -2926,10 +3026,14 @@ TEST(HeapTest, PersistentHeapCollectionTypes)
IntWrapper* four(IntWrapper::create(4));
IntWrapper* five(IntWrapper::create(5));
IntWrapper* six(IntWrapper::create(6));
+ IntWrapper* seven(IntWrapper::create(7));
pVec.append(one);
pVec.append(two);
+ pDeque.append(seven);
+ pDeque.append(two);
+
Vec* vec = new Vec();
vec->swap(pVec);
@@ -2945,41 +3049,66 @@ TEST(HeapTest, PersistentHeapCollectionTypes)
EXPECT_EQ(1, IntWrapper::s_destructorCalls);
EXPECT_EQ(2u, pVec.size());
- EXPECT_TRUE(pVec.at(0) == two);
- EXPECT_TRUE(pVec.at(1) == three);
+ EXPECT_EQ(two, pVec.at(0));
+ EXPECT_EQ(three, pVec.at(1));
+
+ EXPECT_EQ(2u, pDeque.size());
+ EXPECT_EQ(seven, pDeque.first());
+ EXPECT_EQ(seven, pDeque.takeFirst());
+ EXPECT_EQ(two, pDeque.first());
+
+ EXPECT_EQ(1u, pDeque.size());
EXPECT_EQ(1u, pSet.size());
EXPECT_TRUE(pSet.contains(four));
EXPECT_EQ(1u, pMap.size());
- EXPECT_TRUE(pMap.get(five) == six);
+ EXPECT_EQ(six, pMap.get(five));
}
// Collect previous roots.
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
- EXPECT_EQ(6, IntWrapper::s_destructorCalls);
+ EXPECT_EQ(7, IntWrapper::s_destructorCalls);
}
TEST(HeapTest, CollectionNesting)
{
HeapStats initialStats;
clearOutOldGarbage(&initialStats);
- void* key = &IntWrapper::s_destructorCalls;
+ int* key = &IntWrapper::s_destructorCalls;
IntWrapper::s_destructorCalls = 0;
typedef HeapVector<Member<IntWrapper> > IntVector;
+ typedef HeapDeque<Member<IntWrapper> > IntDeque;
HeapHashMap<void*, IntVector>* map = new HeapHashMap<void*, IntVector>();
+ HeapHashMap<void*, IntDeque>* map2 = new HeapHashMap<void*, IntDeque>();
map->add(key, IntVector());
+ map2->add(key, IntDeque());
HeapHashMap<void*, IntVector>::iterator it = map->find(key);
EXPECT_EQ(0u, map->get(key).size());
+ HeapHashMap<void*, IntDeque>::iterator it2 = map2->find(key);
+ EXPECT_EQ(0u, map2->get(key).size());
+
it->value.append(IntWrapper::create(42));
EXPECT_EQ(1u, map->get(key).size());
+ it2->value.append(IntWrapper::create(42));
+ EXPECT_EQ(1u, map2->get(key).size());
+
Persistent<HeapHashMap<void*, IntVector> > keepAlive(map);
+ Persistent<HeapHashMap<void*, IntDeque> > keepAlive2(map2);
+
+ for (int i = 0; i < 100; i++) {
+ map->add(key + 1 + i, IntVector());
+ map2->add(key + 1 + i, IntDeque());
+ }
+
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
EXPECT_EQ(1u, map->get(key).size());
+ EXPECT_EQ(1u, map2->get(key).size());
EXPECT_EQ(0, IntWrapper::s_destructorCalls);
keepAlive = nullptr;
@@ -3037,19 +3166,28 @@ TEST(HeapTest, CollectionNesting3)
clearOutOldGarbage(&initialStats);
IntWrapper::s_destructorCalls = 0;
typedef HeapVector<Member<IntWrapper> > IntVector;
+ typedef HeapDeque<Member<IntWrapper> > IntDeque;
HeapVector<IntVector>* vector = new HeapVector<IntVector>();
+ HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>();
vector->append(IntVector());
+ deque->append(IntDeque());
HeapVector<IntVector>::iterator it = vector->begin();
+ HeapDeque<IntDeque>::iterator it2 = deque->begin();
EXPECT_EQ(0u, it->size());
+ EXPECT_EQ(0u, it2->size());
it->append(IntWrapper::create(42));
+ it2->append(IntWrapper::create(42));
EXPECT_EQ(1u, it->size());
+ EXPECT_EQ(1u, it2->size());
Persistent<HeapVector<IntVector> > keepAlive(vector);
+ Persistent<HeapDeque<IntDeque> > keepAlive2(deque);
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
EXPECT_EQ(1u, it->size());
+ EXPECT_EQ(1u, it2->size());
EXPECT_EQ(0, IntWrapper::s_destructorCalls);
}
@@ -3093,6 +3231,46 @@ TEST(HeapTest, EmbeddedInVector)
EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
}
+TEST(HeapTest, EmbeddedInDeque)
+{
+ HeapStats initialStats;
+ clearOutOldGarbage(&initialStats);
+ SimpleFinalizedObject::s_destructorCalls = 0;
+ {
+ PersistentHeapDeque<VectorObject, 2> inlineDeque;
+ PersistentHeapDeque<VectorObject> outlineDeque;
+ VectorObject i1, i2;
+ inlineDeque.append(i1);
+ inlineDeque.append(i2);
+
+ VectorObject o1, o2;
+ outlineDeque.append(o1);
+ outlineDeque.append(o2);
+
+ PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace;
+ VectorObjectInheritedTrace it1, it2;
+ dequeInheritedTrace.append(it1);
+ dequeInheritedTrace.append(it2);
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
+
+ // Since VectorObjectNoTrace has no trace method it will
+ // not be traced and hence be collected when doing GC.
+ // We trace items in a collection braced on the item's
+ // having a trace method. This is determined via the
+ // NeedsTracing trait in wtf/TypeTraits.h.
+ PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace;
+ VectorObjectNoTrace n1, n2;
+ dequeNoTrace.append(n1);
+ dequeNoTrace.append(n2);
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
+ }
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
+}
+
TEST(HeapTest, RawPtrInHash)
{
HashSet<RawPtr<int> > set;
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/wtf/Deque.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698