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

Unified Diff: Source/heap/HeapTest.cpp

Issue 131803005: Add more oilpan collections support (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix OtherType for Windows compielr Created 6 years, 11 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
Index: Source/heap/HeapTest.cpp
diff --git a/Source/heap/HeapTest.cpp b/Source/heap/HeapTest.cpp
index 1d31ad61d7c1c99394f25468f1b38e4e5a5fcf34..062eb50d4004fb2f9e46043e3900cc92b17a8259 100644
--- a/Source/heap/HeapTest.cpp
+++ b/Source/heap/HeapTest.cpp
@@ -1073,8 +1073,10 @@ TEST(HeapTest, BasicFunctionality)
if (testPagesAllocated)
EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
- for (size_t i = 0; i < persistentCount; i++)
- persistents[i]->release();
+ for (size_t i = 0; i < persistentCount; i++) {
+ delete persistents[i];
+ persistents[i] = 0;
+ }
uint8_t* address = Heap::reallocate<uint8_t>(0, 100);
for (int i = 0; i < 100; i++)
@@ -1415,6 +1417,490 @@ TEST(HeapTest, LargeObjects)
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
}
+class Container : public GarbageCollected<Container> {
+ DECLARE_GC_INFO
+public:
+ static Container* create() { return new Container(); }
+ HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > map;
+ HeapHashSet<Member<IntWrapper> > set;
+ HeapHashSet<Member<IntWrapper> > set2;
+ HeapVector<Member<IntWrapper>, 2> vector;
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(map);
+ visitor->trace(set);
+ visitor->trace(set2);
+ visitor->trace(vector);
+ }
+};
+
+TEST(HeapTest, HeapVectorWithInlineCapacity)
+{
+ IntWrapper* one = IntWrapper::create(1);
+ IntWrapper* two = IntWrapper::create(2);
+ IntWrapper* three = IntWrapper::create(3);
+ IntWrapper* four = IntWrapper::create(4);
+ IntWrapper* five = IntWrapper::create(5);
+ IntWrapper* six = IntWrapper::create(6);
+ {
+ HeapVector<Member<IntWrapper>, 2> vector;
+ vector.append(one);
+ vector.append(two);
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(vector.contains(one));
+ EXPECT_TRUE(vector.contains(two));
+
+ vector.append(three);
+ vector.append(four);
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(vector.contains(one));
+ EXPECT_TRUE(vector.contains(two));
+ EXPECT_TRUE(vector.contains(three));
+ EXPECT_TRUE(vector.contains(four));
+
+ vector.shrink(1);
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(vector.contains(one));
+ EXPECT_FALSE(vector.contains(two));
+ EXPECT_FALSE(vector.contains(three));
+ EXPECT_FALSE(vector.contains(four));
+ }
+ {
+ HeapVector<Member<IntWrapper>, 2> vector1;
+ HeapVector<Member<IntWrapper>, 2> vector2;
+
+ vector1.append(one);
+ vector2.append(two);
+ vector1.swap(vector2);
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(vector1.contains(two));
+ EXPECT_TRUE(vector2.contains(one));
+ }
+ {
+ HeapVector<Member<IntWrapper>, 2> vector1;
+ HeapVector<Member<IntWrapper>, 2> vector2;
+
+ vector1.append(one);
+ vector1.append(two);
+ vector2.append(three);
+ vector2.append(four);
+ vector2.append(five);
+ vector2.append(six);
+ vector1.swap(vector2);
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(vector1.contains(three));
+ EXPECT_TRUE(vector1.contains(four));
+ EXPECT_TRUE(vector1.contains(five));
+ EXPECT_TRUE(vector1.contains(six));
+ EXPECT_TRUE(vector2.contains(one));
+ EXPECT_TRUE(vector2.contains(two));
+ }
+}
+
+TEST(HeapTest, HeapCollectionTypes)
+{
+ HeapStats initialHeapSize;
+ IntWrapper::s_destructorCalls = 0;
+
+ typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > MemberMember;
+ typedef HeapHashMap<Member<IntWrapper>, int> MemberPrimitive;
+ typedef HeapHashMap<int, Member<IntWrapper> > PrimitiveMember;
+
+ typedef HeapHashSet<Member<IntWrapper> > MemberSet;
+ typedef HeapHashSet<WeakMember<IntWrapper> > WeakMemberSet;
+
+ typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
+
+ Persistent<MemberMember> memberMember = new MemberMember();
+ Persistent<MemberMember> memberMember2 = new MemberMember();
+ Persistent<MemberMember> memberMember3 = new MemberMember();
+ Persistent<MemberPrimitive> memberPrimitive = new MemberPrimitive();
+ Persistent<PrimitiveMember> primitiveMember = new PrimitiveMember();
+ Persistent<MemberSet> set = new MemberSet();
+ Persistent<MemberSet> set2 = new MemberSet();
+ Persistent<MemberVector> vector = new MemberVector();
+ Persistent<MemberVector> vector2 = new MemberVector();
+ Persistent<Container> container = Container::create();
+
+ clearOutOldGarbage(&initialHeapSize);
+ {
+ Persistent<IntWrapper> one(IntWrapper::create(1));
+ Persistent<IntWrapper> two(IntWrapper::create(2));
+ Persistent<IntWrapper> oneB(IntWrapper::create(1));
+ Persistent<IntWrapper> twoB(IntWrapper::create(2));
+ Persistent<IntWrapper> oneC(IntWrapper::create(1));
+ Persistent<IntWrapper> twoC(IntWrapper::create(2));
+ {
+ IntWrapper* three(IntWrapper::create(3));
+ IntWrapper* four(IntWrapper::create(4));
+ IntWrapper* threeB(IntWrapper::create(3));
+ IntWrapper* fourB(IntWrapper::create(4));
+
+ // Member Collections.
+ memberMember2->add(one, two);
+ memberMember2->add(two, three);
+ memberMember2->add(three, four);
+ memberMember2->add(four, one);
+ primitiveMember->add(1, two);
+ primitiveMember->add(2, three);
+ primitiveMember->add(3, four);
+ primitiveMember->add(4, one);
+ memberPrimitive->add(one, 2);
+ memberPrimitive->add(two, 3);
+ memberPrimitive->add(three, 4);
+ memberPrimitive->add(four, 1);
+ set2->add(one);
+ set2->add(two);
+ set2->add(three);
+ set2->add(four);
+ set->add(oneB);
+ vector->append(oneB);
+ vector2->append(threeB);
+ vector2->append(fourB);
+
+ // Collect garbage. This should change nothing since we are keeping
+ // alive the IntWrapper objects with on-stack pointers.
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ EXPECT_EQ(0u, memberMember->size());
+ EXPECT_EQ(4u, memberMember2->size());
+ EXPECT_EQ(4u, primitiveMember->size());
+ EXPECT_EQ(4u, memberPrimitive->size());
+ EXPECT_EQ(1u, set->size());
+ EXPECT_EQ(4u, set2->size());
+ EXPECT_EQ(1u, vector->size());
+ EXPECT_EQ(2u, vector2->size());
+
+ MemberVector& cvec = container->vector;
+ cvec.swap(*vector.get());
+ vector2->swap(cvec);
+ vector->swap(cvec);
+
+ // Swap set and set2 in a roundabout way.
+ MemberSet& cset1 = container->set;
+ MemberSet& cset2 = container->set2;
+ set->swap(cset1);
+ set2->swap(cset2);
+ set->swap(cset2);
+ cset1.swap(cset2);
+ cset2.swap(set2);
+
+ // Triple swap.
+ container->map.swap(memberMember2);
+ MemberMember& containedMap = container->map;
+ memberMember3->swap(containedMap);
+ memberMember3->swap(memberMember);
+
+ EXPECT_TRUE(memberMember->get(one) == two);
+ EXPECT_TRUE(memberMember->get(two) == three);
+ EXPECT_TRUE(memberMember->get(three) == four);
+ EXPECT_TRUE(memberMember->get(four) == one);
+ EXPECT_TRUE(primitiveMember->get(1) == two);
+ EXPECT_TRUE(primitiveMember->get(2) == three);
+ EXPECT_TRUE(primitiveMember->get(3) == four);
+ EXPECT_TRUE(primitiveMember->get(4) == one);
+ EXPECT_EQ(1, memberPrimitive->get(four));
+ EXPECT_EQ(2, memberPrimitive->get(one));
+ EXPECT_EQ(3, memberPrimitive->get(two));
+ EXPECT_EQ(4, memberPrimitive->get(three));
+ EXPECT_TRUE(set->contains(one));
+ EXPECT_TRUE(set->contains(two));
+ EXPECT_TRUE(set->contains(three));
+ EXPECT_TRUE(set->contains(four));
+ EXPECT_TRUE(set2->contains(oneB));
+ EXPECT_TRUE(vector->contains(threeB));
+ EXPECT_TRUE(vector->contains(fourB));
+ EXPECT_TRUE(vector2->contains(oneB));
+ EXPECT_FALSE(vector2->contains(threeB));
+ }
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
+ EXPECT_EQ(4u, memberMember->size());
+ EXPECT_EQ(0u, memberMember2->size());
+ EXPECT_EQ(4u, primitiveMember->size());
+ EXPECT_EQ(4u, memberPrimitive->size());
+ EXPECT_EQ(4u, set->size());
+ EXPECT_EQ(1u, set2->size());
+ EXPECT_EQ(2u, vector->size());
+ EXPECT_EQ(1u, vector2->size());
+
+ EXPECT_TRUE(memberMember->get(one) == two);
+ EXPECT_TRUE(primitiveMember->get(1) == two);
+ EXPECT_TRUE(primitiveMember->get(4) == one);
+ EXPECT_EQ(2, memberPrimitive->get(one));
+ EXPECT_EQ(3, memberPrimitive->get(two));
+ EXPECT_TRUE(set->contains(one));
+ EXPECT_TRUE(set->contains(two));
+ EXPECT_FALSE(set->contains(oneB));
+ EXPECT_TRUE(set2->contains(oneB));
+ EXPECT_EQ(3, vector->at(0)->value());
+ EXPECT_EQ(4, vector->at(1)->value());
+ }
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
+ EXPECT_EQ(4u, memberMember->size());
+ EXPECT_EQ(4u, primitiveMember->size());
+ EXPECT_EQ(4u, memberPrimitive->size());
+ EXPECT_EQ(4u, set->size());
+ EXPECT_EQ(1u, set2->size());
+ EXPECT_EQ(2u, vector->size());
+ EXPECT_EQ(1u, vector2->size());
+ EXPECT_EQ(2u, vector->size());
+ EXPECT_EQ(1u, vector2->size());
+}
+
+template<typename T>
+void MapIteratorCheck(T& it, const T& end, int expected)
+{
+ int found = 0;
+ while (it != end) {
+ found++;
+ int key = it->key->value();
+ int value = it->value->value();
+ EXPECT_TRUE(key >= 0 && key < 1100);
+ EXPECT_TRUE(value >= 0 && value < 1100);
+ ++it;
+ }
+ EXPECT_EQ(expected, found);
+}
+
+template<typename T>
+void SetIteratorCheck(T& it, const T& end, int expected)
+{
+ int found = 0;
+ while (it != end) {
+ found++;
+ int value = (*it)->value();
+ EXPECT_TRUE(value >= 0 && value < 1100);
+ ++it;
+ }
+ EXPECT_EQ(expected, found);
+}
+
+TEST(HeapTest, HeapWeakCollectionSimple)
+{
+
+ IntWrapper::s_destructorCalls = 0;
+
+ CollectionPersistent<Vector<Member<IntWrapper> > > keepNumbersAlive;
+
+ typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
+ typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
+ typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
+ typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
+
+ Persistent<WeakStrong> weakStrong = new WeakStrong();
+ Persistent<StrongWeak> strongWeak = new StrongWeak();
+ Persistent<WeakWeak> weakWeak = new WeakWeak();
+ Persistent<WeakSet> weakSet = new WeakSet();
+
+ Persistent<IntWrapper> two = IntWrapper::create(2);
+
+ keepNumbersAlive->append(IntWrapper::create(103));
+ keepNumbersAlive->append(IntWrapper::create(10));
+
+ {
+ weakStrong->add(IntWrapper::create(1), two);
+ strongWeak->add(two, IntWrapper::create(1));
+ weakWeak->add(two, IntWrapper::create(42));
+ weakWeak->add(IntWrapper::create(42), two);
+ weakSet->add(IntWrapper::create(0));
+ weakSet->add(two);
+ weakSet->add(keepNumbersAlive[0]);
+ weakSet->add(keepNumbersAlive[1]);
+ EXPECT_EQ(1u, weakStrong->size());
+ EXPECT_EQ(1u, strongWeak->size());
+ EXPECT_EQ(2u, weakWeak->size());
+ EXPECT_EQ(4u, weakSet->size());
+ }
+
+ keepNumbersAlive[0] = nullptr;
+
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
+ EXPECT_EQ(0u, weakStrong->size());
+ EXPECT_EQ(0u, strongWeak->size());
+ EXPECT_EQ(0u, weakWeak->size());
+ EXPECT_EQ(2u, weakSet->size());
+}
+
+TEST(HeapTest, HeapWeakCollectionTypes)
+{
+ HeapStats initialHeapSize;
+ IntWrapper::s_destructorCalls = 0;
+
+ typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
+ typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
+ typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
+ typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
+
+ clearOutOldGarbage(&initialHeapSize);
+
+ const int weakStrongIndex = 0;
+ const int strongWeakIndex = 1;
+ const int weakWeakIndex = 2;
+ const int numberOfMapIndices = 3;
+ const int weakSetIndex = 3;
+ const int numberOfCollections = 4;
+
+ for (int testRun = 0; testRun < 4; testRun++) {
+ for (int collectionNumber = 0; collectionNumber < numberOfCollections; collectionNumber++) {
+ bool testThatIteratorsMakeStrong = (testRun == weakSetIndex);
+ bool deleteAfterwards = (testRun == 1);
+ bool addAfterwards = (testRun == weakWeakIndex);
+
+ // The test doesn't work for strongWeak with deleting because we lost
+ // the key from the keepNumbersAlive array, so we can't do the lookup.
+ if (deleteAfterwards && collectionNumber == strongWeakIndex)
+ continue;
+
+ unsigned added = addAfterwards ? 100 : 0;
+
+ Persistent<WeakStrong> weakStrong = new WeakStrong();
+ Persistent<StrongWeak> strongWeak = new StrongWeak();
+ Persistent<WeakWeak> weakWeak = new WeakWeak();
+
+ Persistent<WeakSet> weakSet = new WeakSet();
+
+ CollectionPersistent<Vector<Member<IntWrapper> > > keepNumbersAlive;
+ for (int i = 0; i < 128; i += 2) {
+ IntWrapper* wrapped = IntWrapper::create(i);
+ IntWrapper* wrapped2 = IntWrapper::create(i + 1);
+ keepNumbersAlive->append(wrapped);
+ keepNumbersAlive->append(wrapped2);
+ weakStrong->add(wrapped, wrapped2);
+ strongWeak->add(wrapped2, wrapped);
+ weakWeak->add(wrapped, wrapped2);
+ weakSet->add(wrapped);
+ }
+
+ EXPECT_EQ(64u, weakStrong->size());
+ EXPECT_EQ(64u, strongWeak->size());
+ EXPECT_EQ(64u, weakWeak->size());
+ EXPECT_EQ(64u, weakSet->size());
+
+ // Collect garbage. This should change nothing since we are keeping
+ // alive the IntWrapper objects.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
+ EXPECT_EQ(64u, weakStrong->size());
+ EXPECT_EQ(64u, strongWeak->size());
+ EXPECT_EQ(64u, weakWeak->size());
+ EXPECT_EQ(64u, weakSet->size());
+
+ for (int i = 0; i < 128; i += 2) {
+ IntWrapper* wrapped = keepNumbersAlive[i];
+ IntWrapper* wrapped2 = keepNumbersAlive[i + 1];
+ EXPECT_EQ(wrapped2, weakStrong->get(wrapped));
+ EXPECT_EQ(wrapped, strongWeak->get(wrapped2));
+ EXPECT_EQ(wrapped2, weakWeak->get(wrapped));
+ EXPECT_TRUE(weakSet->contains(wrapped));
+ }
+
+ for (int i = 0; i < 128; i += 3)
+ keepNumbersAlive[i] = nullptr;
+
+ if (collectionNumber != weakStrongIndex)
+ weakStrong->clear();
+ if (collectionNumber != strongWeakIndex)
+ strongWeak->clear();
+ if (collectionNumber != weakWeakIndex)
+ weakWeak->clear();
+ if (collectionNumber != weakSetIndex)
+ weakSet->clear();
+
+ if (testThatIteratorsMakeStrong) {
+ WeakStrong::iterator it1 = weakStrong->begin();
+ StrongWeak::iterator it2 = strongWeak->begin();
+ WeakWeak::iterator it3 = weakWeak->begin();
+ WeakSet::iterator it4 = weakSet->begin();
+ // Collect garbage. This should change nothing since the
+ // iterators make the collections strong.
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+ if (collectionNumber == weakStrongIndex) {
+ EXPECT_EQ(64u, weakStrong->size());
+ MapIteratorCheck(it1, weakStrong->end(), 64);
+ } else if (collectionNumber == strongWeakIndex) {
+ EXPECT_EQ(64u, strongWeak->size());
+ MapIteratorCheck(it2, strongWeak->end(), 64);
+ } else if (collectionNumber == weakWeakIndex) {
+ EXPECT_EQ(64u, weakWeak->size());
+ MapIteratorCheck(it3, weakWeak->end(), 64);
+ } else if (collectionNumber == weakSetIndex) {
+ EXPECT_EQ(64u, weakSet->size());
+ SetIteratorCheck(it4, weakSet->end(), 64);
+ }
+ } else {
+ // Collect garbage. This causes weak processing to remove
+ // things from the collections.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ unsigned count = 0;
+ for (int i = 0; i < 128; i += 2) {
+ bool firstAlive = keepNumbersAlive[i];
+ bool secondAlive = keepNumbersAlive[i + 1];
+ if (firstAlive && (collectionNumber == weakStrongIndex || collectionNumber == strongWeakIndex))
+ secondAlive = true;
+ if (firstAlive && secondAlive && collectionNumber < numberOfMapIndices) {
+ if (collectionNumber == weakStrongIndex) {
+ if (deleteAfterwards)
+ EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAlive[i])->value());
+ } else if (collectionNumber == strongWeakIndex) {
+ if (deleteAfterwards)
+ EXPECT_EQ(i, strongWeak->take(keepNumbersAlive[i + 1])->value());
+ } else if (collectionNumber == weakWeakIndex) {
+ if (deleteAfterwards)
+ EXPECT_EQ(i + 1, weakWeak->take(keepNumbersAlive[i])->value());
+ }
+ if (!deleteAfterwards)
+ count++;
+ } else if (collectionNumber == weakSetIndex && firstAlive) {
+ ASSERT_TRUE(weakSet->contains(keepNumbersAlive[i]));
+ if (deleteAfterwards)
+ weakSet->remove(keepNumbersAlive[i]);
+ else
+ count++;
+ }
+ }
+ if (addAfterwards) {
+ for (int i = 1000; i < 1100; i++) {
+ IntWrapper* wrapped = IntWrapper::create(i);
+ keepNumbersAlive->append(wrapped);
+ weakStrong->add(wrapped, wrapped);
+ strongWeak->add(wrapped, wrapped);
+ weakWeak->add(wrapped, wrapped);
+ weakSet->add(wrapped);
+ }
+ }
+ if (collectionNumber == weakStrongIndex)
+ EXPECT_EQ(count + added, weakStrong->size());
+ else if (collectionNumber == strongWeakIndex)
+ EXPECT_EQ(count + added, strongWeak->size());
+ else if (collectionNumber == weakWeakIndex)
+ EXPECT_EQ(count + added, weakWeak->size());
+ else if (collectionNumber == weakSetIndex)
+ EXPECT_EQ(count + added, weakSet->size());
+ WeakStrong::iterator it1 = weakStrong->begin();
+ StrongWeak::iterator it2 = strongWeak->begin();
+ WeakWeak::iterator it3 = weakWeak->begin();
+ WeakSet::iterator it4 = weakSet->begin();
+ MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == weakStrongIndex ? count : 0) + added);
+ MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == strongWeakIndex ? count : 0) + added);
+ MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weakWeakIndex ? count : 0) + added);
+ SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakSetIndex ? count : 0) + added);
+ }
+ for (unsigned i = 0; i < 128 + added; i++)
+ keepNumbersAlive[i] = nullptr;
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(added, weakStrong->size());
+ EXPECT_EQ(added, strongWeak->size());
+ EXPECT_EQ(added, weakWeak->size());
+ EXPECT_EQ(added, weakSet->size());
+ }
+ }
+}
+
TEST(HeapTest, RefCountedGarbageCollected)
{
RefCountedAndGarbageCollected::s_destructorCalls = 0;
@@ -1610,6 +2096,7 @@ DEFINE_GC_INFO(Bar);
DEFINE_GC_INFO(Baz);
DEFINE_GC_INFO(ClassWithMember);
DEFINE_GC_INFO(ConstructorAllocation);
+DEFINE_GC_INFO(Container);
DEFINE_GC_INFO(HeapAllocatedArray);
DEFINE_GC_INFO(HeapTestSuperClass);
DEFINE_GC_INFO(IntWrapper);
« Source/heap/Heap.h ('K') | « Source/heap/Heap.h ('k') | Source/heap/Visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698