Chromium Code Reviews| Index: Source/heap/HeapTest.cpp |
| diff --git a/Source/heap/HeapTest.cpp b/Source/heap/HeapTest.cpp |
| index a9922c199fdb7c3a3baa1ba074a99632bcf1b69a..7786e06ed864523d841a36ef26b4ed64ac77ff65 100644 |
| --- a/Source/heap/HeapTest.cpp |
| +++ b/Source/heap/HeapTest.cpp |
| @@ -926,6 +926,519 @@ TEST(HeapTest, LargeObjects) |
| Heap::shutdown(); |
| } |
| +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) |
| +{ |
| + // FIXME: init and shutdown should be called via Blink |
| + // initialization in the test runner. |
| + Heap::init(); |
|
haraken
2014/01/15 04:48:35
This was removed by wibling's CL.
|
| + |
| + { |
| + 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)); |
| + } |
| + } |
| + |
| + Heap::shutdown(); |
| +} |
| + |
| +TEST(HeapTest, HeapCollectionTypes) |
| +{ |
| + // FIXME: init and shutdown should be called via Blink |
| + // initialization in the test runner. |
| + Heap::init(); |
|
haraken
2014/01/15 04:48:35
Ditto.
|
| + |
| + { |
| + 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.raw()); |
| + 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()); |
| + } |
| + |
| + Heap::shutdown(); |
| +} |
| + |
| +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) |
| +{ |
| + // FIXME: init and shutdown should be called via Blink |
| + // initialization in the test runner. |
| + Heap::init(); |
|
haraken
2014/01/15 04:48:35
Ditto.
|
| + { |
| + |
| + 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()); |
| + } |
| + |
| + Heap::shutdown(); |
| +} |
| + |
| +TEST(HeapTest, HeapWeakCollectionTypes) |
| +{ |
| + // FIXME: init and shutdown should be called via Blink |
| + // initialization in the test runner. |
| + Heap::init(); |
|
haraken
2014/01/15 04:48:35
Ditto.
|
| + |
| + 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()); |
| + } |
| + } |
| + |
| + Heap::shutdown(); |
| +} |
| + |
| TEST(HeapTest, RefCountedGarbageCollected) |
| { |
| // FIXME: init and shutdown should be called via Blink |
| @@ -1012,6 +1525,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(IntWrapper); |
| DEFINE_GC_INFO(LargeObject); |