| 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;
|
|
|