2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "heap/Handle.h"
34 #include "heap/Heap.h"
35 #include "heap/ThreadState.h"
36 #include "heap/Visitor.h"
38 #include <gtest/gtest.h>
44 explicit TestGCScope(ThreadState::StackState state)
45 : m_state(ThreadState::current())
46 , m_safePointScope(state)
48 m_state->checkThread();
49 ASSERT(!m_state->isInGC());
50 ThreadState::stopThreads();
57 ASSERT(!m_state->isInGC());
58 ThreadState::resumeThreads();
63 ThreadState::SafePointScope m_safePointScope;
66 static void getHeapStats(HeapStats* stats)
68 TestGCScope scope(ThreadState::NoHeapPointersOnStack);
69 Heap::getStats(stats);
72 #define DEFINE_VISITOR_METHODS(Type) \
73 virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
78 virtual bool isMarked(const Type*) OVERRIDE { return false; }
80 class CountingVisitor : public Visitor {
87 virtual void mark(const void* object, TraceCallback) OVERRIDE
93 virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
95 ASSERT(header->payload());
99 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
101 ASSERT(header->payload());
105 virtual void registerWeakMembers(const void*, WeakPointerCallback) OVERRIDE { }
106 virtual bool isMarked(const void*) OVERRIDE { return false; }
108 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
110 size_t count() { return m_count; }
111 void reset() { m_count = 0; }
117 class SimpleObject : public GarbageCollected<SimpleObject> {
120 static SimpleObject* create() { return new SimpleObject(); }
121 void trace(Visitor*) { }
122 char getPayload(int i) { return payload[i]; }
128 #undef DEFINE_VISITOR_METHODS
130 class HeapTestSuperClass : public GarbageCollectedFinalized<HeapTestSuperClass> {
133 static HeapTestSuperClass* create()
135 return new HeapTestSuperClass();
138 virtual ~HeapTestSuperClass()
143 static int s_destructorCalls;
144 void trace(Visitor*) { }
147 HeapTestSuperClass() { }
150 int HeapTestSuperClass::s_destructorCalls = 0;
152 class HeapTestOtherSuperClass {
157 static const size_t classMagic = 0xABCDDBCA;
159 class HeapTestSubClass : public HeapTestOtherSuperClass, public HeapTestSuperClass {
161 static HeapTestSubClass* create()
163 return new HeapTestSubClass();
166 virtual ~HeapTestSubClass()
168 EXPECT_EQ(classMagic, m_magic);
172 static int s_destructorCalls;
176 HeapTestSubClass() : m_magic(classMagic) { }
178 const size_t m_magic;
181 int HeapTestSubClass::s_destructorCalls = 0;
183 class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
188 for (int i = 0; i < s_arraySize; ++i) {
189 m_array[i] = i % 128;
193 int8_t at(size_t i) { return m_array[i]; }
194 void trace(Visitor*) { }
196 static const int s_arraySize = 1000;
197 int8_t m_array[s_arraySize];
200 // Do several GCs to make sure that later GCs don't free up old memory from
201 // previously run tests in this process.
202 static void clearOutOldGarbage(HeapStats* heapStats)
205 getHeapStats(heapStats);
206 size_t used = heapStats->totalObjectSpace();
207 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
208 getHeapStats(heapStats);
209 if (heapStats->totalObjectSpace() >= used)
214 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> {
217 static IntWrapper* create(int x)
219 return new IntWrapper(x);
222 virtual ~IntWrapper()
227 static int s_destructorCalls;
228 static void trace(Visitor*) { }
230 int value() const { return m_x; }
232 bool operator==(const IntWrapper& other) const { return other.value() == value(); }
234 unsigned hash() { return IntHash<int>::hash(m_x); }
237 IntWrapper(int x) : m_x(x) { }
244 USED_FROM_MULTIPLE_THREADS(IntWrapper);
246 int IntWrapper::s_destructorCalls = 0;
248 class ThreadedHeapTester {
252 ThreadedHeapTester* tester = new ThreadedHeapTester();
253 for (int i = 0; i < numberOfThreads; i++)
254 createThread(&threadFunc, tester, "testing thread");
255 while (tester->m_threadsToFinish) {
256 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
262 static const int numberOfThreads = 10;
263 static const int gcPerThread = 5;
264 static const int numberOfAllocations = 50;
266 inline bool done() const { return m_gcCount >= numberOfThreads * gcPerThread; }
268 ThreadedHeapTester() : m_gcCount(0), m_threadsToFinish(numberOfThreads)
272 static void threadFunc(void* data)
274 reinterpret_cast<ThreadedHeapTester*>(data)->runThread();
279 ThreadState::attach();
283 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
287 for (int i = 0; i < numberOfAllocations; i++) {
288 wrapper = IntWrapper::create(0x0bbac0de);
290 ThreadState::current()->safePoint(ThreadState::HeapPointersOnStack);
294 if (gcCount < gcPerThread) {
295 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
297 atomicIncrement(&m_gcCount);
300 EXPECT_EQ(wrapper->value(), 0x0bbac0de);
304 ThreadState::detach();
305 atomicDecrement(&m_threadsToFinish);
308 volatile int m_gcCount;
309 volatile int m_threadsToFinish;
312 // The accounting for memory includes the memory used by rounding up object
313 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
314 // have some slack in the tests.
316 void CheckWithSlack(T expected, T actual, int slack)
318 EXPECT_LE(expected, actual);
319 EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
322 class TraceCounter : public GarbageCollectedFinalized<TraceCounter> {
325 static TraceCounter* create()
327 return new TraceCounter();
330 void trace(Visitor*) { m_traceCount++; }
332 int traceCount() { return m_traceCount; }
343 class ClassWithMember : public GarbageCollected<ClassWithMember> {
346 static ClassWithMember* create()
348 return new ClassWithMember();
351 void trace(Visitor* visitor)
353 EXPECT_TRUE(visitor->isMarked(this));
355 EXPECT_FALSE(visitor->isMarked(m_traceCounter));
357 EXPECT_TRUE(visitor->isMarked(m_traceCounter));
359 visitor->trace(m_traceCounter);
362 int traceCount() { return m_traceCounter->traceCount(); }
366 : m_traceCounter(TraceCounter::create())
369 Member<TraceCounter> m_traceCounter;
372 class SimpleFinalizedObject : public GarbageCollectedFinalized<SimpleFinalizedObject> {
375 static SimpleFinalizedObject* create()
377 return new SimpleFinalizedObject();
380 ~SimpleFinalizedObject()
385 static int s_destructorCalls;
387 void trace(Visitor*) { }
390 SimpleFinalizedObject() { }
393 int SimpleFinalizedObject::s_destructorCalls = 0;
395 class TestTypedHeapClass : public GarbageCollected<TestTypedHeapClass> {
398 static TestTypedHeapClass* create()
400 return new TestTypedHeapClass();
403 void trace(Visitor*) { }
406 TestTypedHeapClass() { }
409 class Bar : public GarbageCollectedFinalized<Bar> {
419 EXPECT_TRUE(m_magic == magic);
424 virtual void trace(Visitor* visitor) { }
425 static unsigned s_live;
428 static const int magic = 1337;
438 unsigned Bar::s_live = 0;
440 class Baz : public GarbageCollected<Baz> {
443 static Baz* create(Bar* bar)
448 void trace(Visitor* visitor)
450 visitor->trace(m_bar);
453 void clear() { m_bar.release(); }
456 explicit Baz(Bar* bar)
464 class Foo : public Bar {
466 static Foo* create(Bar* bar)
471 static Foo* create(Foo* foo)
476 virtual void trace(Visitor* visitor) OVERRIDE
479 visitor->mark(static_cast<Foo*>(m_bar));
481 visitor->mark(m_bar);
488 , m_pointsToFoo(false)
495 , m_pointsToFoo(true)
503 class Bars : public Bar {
505 static Bars* create()
510 virtual void trace(Visitor* visitor) OVERRIDE
512 for (unsigned i = 0; i < m_width; i++)
513 visitor->trace(m_bars[i]);
516 unsigned getWidth() const
521 static const unsigned width = 7500;
525 for (unsigned i = 0; i < width; i++) {
526 m_bars[i] = Bar::create();
532 Member<Bar> m_bars[width];
535 class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
538 static ConstructorAllocation* create() { return new ConstructorAllocation(); }
540 void trace(Visitor* visitor) { visitor->trace(m_intWrapper); }
543 ConstructorAllocation()
545 m_intWrapper = IntWrapper::create(42);
548 Member<IntWrapper> m_intWrapper;
551 class LargeObject : public GarbageCollectedFinalized<LargeObject> {
558 static LargeObject* create() { return new LargeObject(); }
559 char get(size_t i) { return m_data[i]; }
560 void set(size_t i, char c) { m_data[i] = c; }
561 size_t length() { return s_length; }
562 void trace(Visitor* visitor)
564 visitor->trace(m_intWrapper);
566 static int s_destructorCalls;
569 static const size_t s_length = 1024*1024;
572 m_intWrapper = IntWrapper::create(23);
574 Member<IntWrapper> m_intWrapper;
575 char m_data[s_length];
578 int LargeObject::s_destructorCalls = 0;
580 class RefCountedAndGarbageCollected : public RefCountedGarbageCollected<RefCountedAndGarbageCollected> {
583 static PassRefPtr<RefCountedAndGarbageCollected> create()
585 return adoptRef(new RefCountedAndGarbageCollected());
588 ~RefCountedAndGarbageCollected()
593 void trace(Visitor*) { }
595 static int s_destructorCalls;
598 RefCountedAndGarbageCollected()
603 int RefCountedAndGarbageCollected::s_destructorCalls = 0;
605 class RefCountedAndGarbageCollected2 : public HeapTestOtherSuperClass, public RefCountedGarbageCollected<RefCountedAndGarbageCollected2> {
608 static PassRefPtr<RefCountedAndGarbageCollected2> create()
610 return adoptRef(new RefCountedAndGarbageCollected2());
613 ~RefCountedAndGarbageCollected2()
618 void trace(Visitor*) { }
620 static int s_destructorCalls;
623 RefCountedAndGarbageCollected2()
628 int RefCountedAndGarbageCollected2::s_destructorCalls = 0;
630 #define DEFINE_VISITOR_METHODS(Type) \
631 virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
636 class RefCountedGarbageCollectedVisitor : public CountingVisitor {
638 RefCountedGarbageCollectedVisitor(int expected, void** objects)
640 , m_expectedCount(expected)
641 , m_expectedObjects(objects)
645 void mark(const void* ptr) { markNoTrace(ptr); }
647 virtual void markNoTrace(const void* ptr)
651 if (m_count < m_expectedCount)
652 EXPECT_TRUE(expectedObject(ptr));
654 EXPECT_FALSE(expectedObject(ptr));
658 virtual void mark(const void* ptr, TraceCallback) OVERRIDE
663 virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
665 mark(header->payload());
668 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
670 mark(header->payload());
673 bool validate() { return m_count >= m_expectedCount; }
674 void reset() { m_count = 0; }
676 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
679 bool expectedObject(const void* ptr)
681 for (int i = 0; i < m_expectedCount; i++) {
682 if (m_expectedObjects[i] == ptr)
690 void** m_expectedObjects;
693 #undef DEFINE_VISITOR_METHODS
695 class Weak : public Bar {
697 static Weak* create(Bar* strong, Bar* weak)
699 return new Weak(strong, weak);
702 virtual void trace(Visitor* visitor) OVERRIDE
704 visitor->trace(m_strongBar);
705 visitor->registerWeakMembers(this, zapWeakMembers);
708 static void zapWeakMembers(Visitor* visitor, void* self)
710 reinterpret_cast<Weak*>(self)->zapWeakMembers(visitor);
713 bool strongIsThere() { return !!m_strongBar; }
714 bool weakIsThere() { return !!m_weakBar; }
717 Weak(Bar* strongBar, Bar* weakBar)
719 , m_strongBar(strongBar)
724 void zapWeakMembers(Visitor* visitor)
726 if (m_weakBar && !visitor->isAlive(m_weakBar))
730 Member<Bar> m_strongBar;
734 class WithWeakMember : public Bar {
736 static WithWeakMember* create(Bar* strong, Bar* weak)
738 return new WithWeakMember(strong, weak);
741 virtual void trace(Visitor* visitor) OVERRIDE
743 visitor->trace(m_strongBar);
744 visitor->trace(m_weakBar);
747 bool strongIsThere() { return !!m_strongBar; }
748 bool weakIsThere() { return !!m_weakBar; }
751 WithWeakMember(Bar* strongBar, Bar* weakBar)
753 , m_strongBar(strongBar)
758 Member<Bar> m_strongBar;
759 WeakMember<Bar> m_weakBar;
765 class PointsBack : public RefCountedWillBeGarbageCollectedFinalized<PointsBack> {
768 static PassRefPtrWillBePtr<PointsBack> create()
770 return adoptRefWillBeNoop(new PointsBack());
778 void setBackPointer(SuperClass* backPointer)
780 m_backPointer = backPointer;
783 SuperClass* backPointer() const { return m_backPointer; }
785 void trace(Visitor* visitor)
788 visitor->trace(m_backPointer);
792 static int s_aliveCount;
794 PointsBack() : m_backPointer(nullptr)
799 PtrWillBeWeakMember<SuperClass> m_backPointer;
802 int PointsBack::s_aliveCount = 0;
804 class SuperClass : public RefCountedWillBeGarbageCollectedFinalized<SuperClass> {
807 static PassRefPtrWillBePtr<SuperClass> create(PassRefPtrWillBePtr<PointsBack> pointsBack)
809 return adoptRefWillBeNoop(new SuperClass(pointsBack));
812 virtual ~SuperClass()
815 m_pointsBack->setBackPointer(0);
820 void doStuff(PassRefPtrWillBePtr<SuperClass> targetPass, PointsBack* pointsBack, int superClassCount)
822 RefPtrWillBePtr<SuperClass> target = targetPass;
823 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
824 EXPECT_EQ(pointsBack, target->pointsBack());
825 EXPECT_EQ(superClassCount, SuperClass::s_aliveCount);
828 virtual void trace(Visitor* visitor)
831 visitor->trace(m_pointsBack);
835 PointsBack* pointsBack() const { return m_pointsBack.get(); }
837 static int s_aliveCount;
839 explicit SuperClass(PassRefPtrWillBePtr<PointsBack> pointsBack)
840 : m_pointsBack(pointsBack)
842 m_pointsBack->setBackPointer(this);
847 RefPtrWillBeMember<PointsBack> m_pointsBack;
850 int SuperClass::s_aliveCount = 0;
851 class SubData : public NoBaseWillBeGarbageCollectedFinalized<SubData> {
854 SubData() { ++s_aliveCount; }
855 ~SubData() { --s_aliveCount; }
857 void trace(Visitor*) { }
859 static int s_aliveCount;
862 int SubData::s_aliveCount = 0;
864 class SubClass : public SuperClass {
866 static PassRefPtrWillBePtr<SubClass> create(PassRefPtrWillBePtr<PointsBack> pointsBack)
868 return adoptRefWillBeNoop(new SubClass(pointsBack));
876 virtual void trace(Visitor* visitor)
879 SuperClass::trace(visitor);
880 visitor->trace(m_data);
884 static int s_aliveCount;
886 explicit SubClass(PassRefPtrWillBePtr<PointsBack> pointsBack)
887 : SuperClass(pointsBack)
888 , m_data(adoptPtrWillBeNoop(new SubData()))
894 OwnPtrWillBeMember<SubData> m_data;
897 int SubClass::s_aliveCount = 0;
899 TEST(HeapTest, Transition)
901 RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create();
902 RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create();
903 RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBack1);
904 RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2);
905 EXPECT_EQ(2, PointsBack::s_aliveCount);
906 EXPECT_EQ(2, SuperClass::s_aliveCount);
907 EXPECT_EQ(1, SubClass::s_aliveCount);
908 EXPECT_EQ(1, SubData::s_aliveCount);
910 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
911 EXPECT_EQ(2, PointsBack::s_aliveCount);
912 EXPECT_EQ(2, SuperClass::s_aliveCount);
913 EXPECT_EQ(1, SubClass::s_aliveCount);
914 EXPECT_EQ(1, SubData::s_aliveCount);
916 superClass->doStuff(superClass.release(), pointsBack1.get(), 2);
917 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
918 EXPECT_EQ(2, PointsBack::s_aliveCount);
919 EXPECT_EQ(1, SuperClass::s_aliveCount);
920 EXPECT_EQ(1, SubClass::s_aliveCount);
921 EXPECT_EQ(1, SubData::s_aliveCount);
922 EXPECT_EQ(0, pointsBack1->backPointer());
924 pointsBack1.release();
925 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
926 EXPECT_EQ(1, PointsBack::s_aliveCount);
927 EXPECT_EQ(1, SuperClass::s_aliveCount);
928 EXPECT_EQ(1, SubClass::s_aliveCount);
929 EXPECT_EQ(1, SubData::s_aliveCount);
931 subClass->doStuff(subClass.release(), pointsBack2.get(), 1);
932 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
933 EXPECT_EQ(1, PointsBack::s_aliveCount);
934 EXPECT_EQ(0, SuperClass::s_aliveCount);
935 EXPECT_EQ(0, SubClass::s_aliveCount);
936 EXPECT_EQ(0, SubData::s_aliveCount);
937 EXPECT_EQ(0, pointsBack2->backPointer());
939 pointsBack2.release();
940 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
941 EXPECT_EQ(0, PointsBack::s_aliveCount);
942 EXPECT_EQ(0, SuperClass::s_aliveCount);
943 EXPECT_EQ(0, SubClass::s_aliveCount);
944 EXPECT_EQ(0, SubData::s_aliveCount);
946 EXPECT_TRUE(superClass == subClass);
949 TEST(HeapTest, Threading)
951 ThreadedHeapTester::test();
954 TEST(HeapTest, BasicFunctionality)
957 clearOutOldGarbage(&heapStats);
961 // When the test starts there may already have been leaked some memory
962 // on the heap, so we establish a base line.
963 size_t baseLevel = heapStats.totalObjectSpace();
964 bool testPagesAllocated = !baseLevel;
965 if (testPagesAllocated)
966 EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
968 // This allocates objects on the general heap which should add a page of memory.
969 uint8_t* alloc32(Heap::allocate<uint8_t>(32));
971 memset(alloc32, 40, 32);
972 uint8_t* alloc64(Heap::allocate<uint8_t>(64));
974 memset(alloc64, 27, 64);
978 getHeapStats(&heapStats);
979 CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
980 if (testPagesAllocated)
981 EXPECT_EQ(heapStats.totalAllocatedSpace(), blinkPageSize);
983 CheckWithSlack(alloc32 + 32 + sizeof(HeapObjectHeader), alloc64, slack);
985 EXPECT_EQ(alloc32[0], 40);
986 EXPECT_EQ(alloc32[31], 40);
987 EXPECT_EQ(alloc64[0], 27);
988 EXPECT_EQ(alloc64[63], 27);
990 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
992 EXPECT_EQ(alloc32[0], 40);
993 EXPECT_EQ(alloc32[31], 40);
994 EXPECT_EQ(alloc64[0], 27);
995 EXPECT_EQ(alloc64[63], 27);
998 clearOutOldGarbage(&heapStats);
1001 size_t baseLevel = heapStats.totalObjectSpace();
1002 bool testPagesAllocated = !baseLevel;
1003 if (testPagesAllocated)
1004 EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
1006 const size_t big = 1008;
1007 Persistent<uint8_t> bigArea = Heap::allocate<uint8_t>(big);
1011 size_t persistentCount = 0;
1012 const size_t numPersistents = 100000;
1013 Persistent<uint8_t>* persistents[numPersistents];
1015 for (int i = 0; i < 1000; i++) {
1016 size_t size = 128 + i * 8;
1018 persistents[persistentCount++] = new Persistent<uint8_t>(Heap::allocate<uint8_t>(size));
1020 getHeapStats(&heapStats);
1021 CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1022 if (testPagesAllocated)
1023 EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1027 uint8_t* alloc32b(Heap::allocate<uint8_t>(32));
1029 memset(alloc32b, 40, 32);
1030 uint8_t* alloc64b(Heap::allocate<uint8_t>(64));
1032 memset(alloc64b, 27, 64);
1033 EXPECT_TRUE(alloc32b != alloc64b);
1036 getHeapStats(&heapStats);
1037 CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1038 if (testPagesAllocated)
1039 EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1042 clearOutOldGarbage(&heapStats);
1045 if (testPagesAllocated)
1046 EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1048 Address bigAreaRaw = bigArea;
1049 // Clear the persistent, so that the big area will be garbage collected.
1051 clearOutOldGarbage(&heapStats);
1055 getHeapStats(&heapStats);
1056 CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1057 if (testPagesAllocated)
1058 EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1060 // Endless loop unless we eventually get the memory back that we just freed.
1062 Persistent<uint8_t>* alloc = new Persistent<uint8_t>(Heap::allocate<uint8_t>(big / 2));
1064 persistents[persistentCount++] = alloc;
1065 EXPECT_LT(persistentCount, numPersistents);
1067 if (bigAreaRaw == alloc->get())
1071 getHeapStats(&heapStats);
1072 CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1073 if (testPagesAllocated)
1074 EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1076 for (size_t i = 0; i < persistentCount; i++)
1077 persistents[i]->release();
1079 uint8_t* address = Heap::reallocate<uint8_t>(0, 100);
1080 for (int i = 0; i < 100; i++)
1082 address = Heap::reallocate<uint8_t>(address, 100000);
1083 for (int i = 0; i < 100; i++)
1084 EXPECT_EQ(address[i], i);
1085 address = Heap::reallocate<uint8_t>(address, 50);
1086 for (int i = 0; i < 50; i++)
1087 EXPECT_EQ(address[i], i);
1088 // This should be equivalent to free(address).
1089 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<uint8_t>(address, 0)), 0ul);
1090 // This should be equivalent to malloc(0).
1091 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<uint8_t>(0, 0)), 0ul);
1094 TEST(HeapTest, SimpleAllocation)
1096 HeapStats initialHeapStats;
1097 clearOutOldGarbage(&initialHeapStats);
1098 EXPECT_EQ(0ul, initialHeapStats.totalObjectSpace());
1100 // Allocate an object in the heap.
1101 HeapAllocatedArray* array = new HeapAllocatedArray();
1102 HeapStats statsAfterAllocation;
1103 getHeapStats(&statsAfterAllocation);
1104 EXPECT_TRUE(statsAfterAllocation.totalObjectSpace() >= sizeof(HeapAllocatedArray));
1106 // Sanity check of the contents in the heap.
1107 EXPECT_EQ(0, array->at(0));
1108 EXPECT_EQ(42, array->at(42));
1109 EXPECT_EQ(0, array->at(128));
1110 EXPECT_EQ(999 % 128, array->at(999));
1113 TEST(HeapTest, SimplePersistent)
1115 Persistent<TraceCounter> traceCounter = TraceCounter::create();
1116 EXPECT_EQ(0, traceCounter->traceCount());
1118 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1119 EXPECT_EQ(1, traceCounter->traceCount());
1121 Persistent<ClassWithMember> classWithMember = ClassWithMember::create();
1122 EXPECT_EQ(0, classWithMember->traceCount());
1124 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1125 EXPECT_EQ(1, classWithMember->traceCount());
1126 EXPECT_EQ(2, traceCounter->traceCount());
1129 TEST(HeapTest, SimpleFinalization)
1132 Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::create();
1133 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
1134 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1135 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
1138 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1139 EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls);
1142 TEST(HeapTest, Finalization)
1145 HeapTestSubClass* t1 = HeapTestSubClass::create();
1146 HeapTestSubClass* t2 = HeapTestSubClass::create();
1147 HeapTestSuperClass* t3 = HeapTestSuperClass::create();
1148 // FIXME(oilpan): Ignore unused variables.
1153 // Nothing is marked so the GC should free everything and call
1154 // the finalizer on all three objects.
1155 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1156 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
1157 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
1158 // Destructors not called again when GCing again.
1159 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1160 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
1161 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
1164 TEST(HeapTest, TypedHeapSanity)
1166 // We use TraceCounter for allocating an object on the general heap.
1167 Persistent<TraceCounter> generalHeapObject = TraceCounter::create();
1168 Persistent<TestTypedHeapClass> typedHeapObject = TestTypedHeapClass::create();
1169 EXPECT_NE(pageHeaderAddress(reinterpret_cast<Address>(generalHeapObject.get())),
1170 pageHeaderAddress(reinterpret_cast<Address>(typedHeapObject.get())));
1173 TEST(HeapTest, NoAllocation)
1175 EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
1177 // Disallow allocation
1178 NoAllocationScope<AnyThread> noAllocationScope;
1179 EXPECT_FALSE(ThreadState::current()->isAllocationAllowed());
1181 EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
1184 TEST(HeapTest, Members)
1191 h1 = Baz::create(Bar::create());
1192 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1193 EXPECT_EQ(1u, Bar::s_live);
1194 h2 = Baz::create(Bar::create());
1195 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1196 EXPECT_EQ(2u, Bar::s_live);
1198 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1199 EXPECT_EQ(2u, Bar::s_live);
1201 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1202 EXPECT_EQ(1u, Bar::s_live);
1204 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1205 EXPECT_EQ(0u, Bar::s_live);
1208 TEST(HeapTest, MarkTest)
1212 Persistent<Bar> bar = Bar::create();
1213 EXPECT_TRUE(ThreadState::current()->contains(bar));
1214 EXPECT_EQ(1u, Bar::s_live);
1216 Foo* foo = Foo::create(bar);
1217 EXPECT_TRUE(ThreadState::current()->contains(foo));
1218 EXPECT_EQ(2u, Bar::s_live);
1219 EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Address>(bar.get()));
1220 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1221 EXPECT_EQ(2u, Bar::s_live);
1223 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1224 EXPECT_EQ(1u, Bar::s_live);
1226 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1227 EXPECT_EQ(0u, Bar::s_live);
1230 TEST(HeapTest, DeepTest)
1232 const unsigned depth = 100000;
1235 Bar* bar = Bar::create();
1236 EXPECT_TRUE(ThreadState::current()->contains(bar));
1237 Foo* foo = Foo::create(bar);
1238 EXPECT_TRUE(ThreadState::current()->contains(foo));
1239 EXPECT_EQ(2u, Bar::s_live);
1240 for (unsigned i = 0; i < depth; i++) {
1241 Foo* foo2 = Foo::create(foo);
1243 EXPECT_TRUE(ThreadState::current()->contains(foo));
1245 EXPECT_EQ(depth + 2, Bar::s_live);
1246 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1247 EXPECT_EQ(depth + 2, Bar::s_live);
1249 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1250 EXPECT_EQ(0u, Bar::s_live);
1253 TEST(HeapTest, WideTest)
1257 Bars* bars = Bars::create();
1258 unsigned width = Bars::width;
1259 EXPECT_EQ(width + 1, Bar::s_live);
1260 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1261 EXPECT_EQ(width + 1, Bar::s_live);
1262 // Use bars here to make sure that it will be on the stack
1263 // for the conservative stack scan to find.
1264 EXPECT_EQ(width, bars->getWidth());
1266 EXPECT_EQ(Bars::width + 1, Bar::s_live);
1267 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1268 EXPECT_EQ(0u, Bar::s_live);
1271 TEST(HeapTest, HashMapOfMembers)
1273 HeapStats initialHeapSize;
1274 IntWrapper::s_destructorCalls = 0;
1276 clearOutOldGarbage(&initialHeapSize);
1281 DefaultHash<Member<IntWrapper> >::Hash,
1282 HashTraits<Member<IntWrapper> >,
1283 HashTraits<Member<IntWrapper> >,
1284 HeapAllocator> HeapObjectIdentityMap;
1286 HeapObjectIdentityMap* map(new HeapObjectIdentityMap());
1289 HeapStats afterSetWasCreated;
1290 getHeapStats(&afterSetWasCreated);
1291 EXPECT_TRUE(afterSetWasCreated.totalObjectSpace() > initialHeapSize.totalObjectSpace());
1293 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1295 getHeapStats(&afterGC);
1296 EXPECT_EQ(afterGC.totalObjectSpace(), afterSetWasCreated.totalObjectSpace());
1298 IntWrapper* one(IntWrapper::create(1));
1299 IntWrapper* anotherOne(IntWrapper::create(1));
1301 HeapStats afterOneAdd;
1302 getHeapStats(&afterOneAdd);
1303 EXPECT_TRUE(afterOneAdd.totalObjectSpace() > afterGC.totalObjectSpace());
1305 HeapObjectIdentityMap::iterator it(map->begin());
1306 HeapObjectIdentityMap::iterator it2(map->begin());
1310 map->add(anotherOne, one);
1312 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distinct.
1314 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1315 EXPECT_TRUE(map->contains(one));
1316 EXPECT_TRUE(map->contains(anotherOne));
1318 IntWrapper* gotten(map->get(one));
1319 EXPECT_EQ(gotten->value(), one->value());
1320 EXPECT_EQ(gotten, one);
1323 getHeapStats(&afterGC2);
1324 EXPECT_EQ(afterGC2.totalObjectSpace(), afterOneAdd.totalObjectSpace());
1326 IntWrapper* dozen = 0;
1328 for (int i = 1; i < 1000; i++) { // 999 iterations.
1329 IntWrapper* iWrapper(IntWrapper::create(i));
1330 IntWrapper* iSquared(IntWrapper::create(i * i));
1331 map->add(iWrapper, iSquared);
1335 HeapStats afterAdding1000;
1336 getHeapStats(&afterAdding1000);
1337 EXPECT_TRUE(afterAdding1000.totalObjectSpace() > afterGC2.totalObjectSpace());
1339 IntWrapper* gross(map->get(dozen));
1340 EXPECT_EQ(gross->value(), 144);
1342 // This should clear out junk created by all the adds.
1343 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1345 getHeapStats(&afterGC3);
1346 EXPECT_TRUE(afterGC3.totalObjectSpace() < afterAdding1000.totalObjectSpace());
1349 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1350 // The objects 'one', anotherOne, and the 999 other pairs.
1351 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
1353 getHeapStats(&afterGC4);
1354 EXPECT_EQ(afterGC4.totalObjectSpace(), initialHeapSize.totalObjectSpace());
1357 TEST(HeapTest, NestedAllocation)
1359 HeapStats initialHeapSize;
1360 clearOutOldGarbage(&initialHeapSize);
1362 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAllocation::create();
1364 HeapStats afterFree;
1365 clearOutOldGarbage(&afterFree);
1366 EXPECT_TRUE(initialHeapSize == afterFree);
1369 TEST(HeapTest, LargeObjects)
1371 HeapStats initialHeapSize;
1372 clearOutOldGarbage(&initialHeapSize);
1373 IntWrapper::s_destructorCalls = 0;
1374 LargeObject::s_destructorCalls = 0;
1376 int slack = 8; // LargeObject points to an IntWrapper that is also allocated.
1377 Persistent<LargeObject> object = LargeObject::create();
1378 HeapStats afterAllocation;
1379 clearOutOldGarbage(&afterAllocation);
1381 object->set(0, 'a');
1382 EXPECT_EQ('a', object->get(0));
1383 object->set(object->length() - 1, 'b');
1384 EXPECT_EQ('b', object->get(object->length() - 1));
1385 size_t expectedObjectSpace = sizeof(LargeObject) + sizeof(IntWrapper);
1386 size_t actualObjectSpace =
1387 afterAllocation.totalObjectSpace() - initialHeapSize.totalObjectSpace();
1388 CheckWithSlack(expectedObjectSpace, actualObjectSpace, slack);
1389 // There is probably space for the IntWrapper in a heap page without
1390 // allocating extra pages. However, the IntWrapper allocation might cause
1391 // the addition of a heap page.
1392 size_t largeObjectAllocationSize =
1393 sizeof(LargeObject) + sizeof(LargeHeapObject<FinalizedHeapObjectHeader>) + sizeof(FinalizedHeapObjectHeader);
1394 size_t allocatedSpaceLowerBound =
1395 initialHeapSize.totalAllocatedSpace() + largeObjectAllocationSize;
1396 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
1397 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation.totalAllocatedSpace());
1398 EXPECT_LE(afterAllocation.totalAllocatedSpace(), allocatedSpaceUpperBound);
1399 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
1400 EXPECT_EQ(0, LargeObject::s_destructorCalls);
1401 for (int i = 0; i < 10; i++)
1402 object = LargeObject::create();
1404 HeapStats oneLargeObject;
1405 clearOutOldGarbage(&oneLargeObject);
1406 EXPECT_TRUE(oneLargeObject == afterAllocation);
1407 EXPECT_EQ(10, IntWrapper::s_destructorCalls);
1408 EXPECT_EQ(10, LargeObject::s_destructorCalls);
1410 HeapStats backToInitial;
1411 clearOutOldGarbage(&backToInitial);
1412 EXPECT_TRUE(initialHeapSize == backToInitial);
1413 EXPECT_EQ(11, IntWrapper::s_destructorCalls);
1414 EXPECT_EQ(11, LargeObject::s_destructorCalls);
1415 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1418 TEST(HeapTest, RefCountedGarbageCollected)
1420 RefCountedAndGarbageCollected::s_destructorCalls = 0;
1422 RefPtr<RefCountedAndGarbageCollected> refPtr3;
1424 Persistent<RefCountedAndGarbageCollected> persistent;
1426 RefPtr<RefCountedAndGarbageCollected> refPtr1 = RefCountedAndGarbageCollected::create();
1427 RefPtr<RefCountedAndGarbageCollected> refPtr2 = RefCountedAndGarbageCollected::create();
1428 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1429 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
1430 persistent = refPtr1.get();
1432 // Reference count is zero for both objects but one of
1433 // them is kept alive by a persistent handle.
1434 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1435 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
1436 refPtr3 = persistent;
1438 // The persistent handle is gone but the ref count has been
1440 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1441 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
1443 // Both persistent handle is gone and ref count is zero so the
1444 // object can be collected.
1445 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1446 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls);
1449 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers)
1451 RefCountedAndGarbageCollected::s_destructorCalls = 0;
1452 RefCountedAndGarbageCollected2::s_destructorCalls = 0;
1454 RefCountedAndGarbageCollected* pointer1 = 0;
1455 RefCountedAndGarbageCollected* pointer2 = 0;
1457 RefPtr<RefCountedAndGarbageCollected> object1 = RefCountedAndGarbageCollected::create();
1458 RefPtr<RefCountedAndGarbageCollected> object2 = RefCountedAndGarbageCollected::create();
1459 pointer1 = object1.get();
1460 pointer2 = object2.get();
1461 void* objects[2] = { object1.get(), object2.get() };
1462 RefCountedGarbageCollectedVisitor visitor(2, objects);
1463 ThreadState::current()->visitPersistents(&visitor);
1464 EXPECT_TRUE(visitor.validate());
1466 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1467 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
1469 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1470 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
1472 // At this point, the reference counts of object1 and object2 are 0.
1473 // Only pointer1 and pointer2 keep references to object1 and object2.
1474 void* objects[] = { 0 };
1475 RefCountedGarbageCollectedVisitor visitor(0, objects);
1476 ThreadState::current()->visitPersistents(&visitor);
1477 EXPECT_TRUE(visitor.validate());
1480 RefPtr<RefCountedAndGarbageCollected> object1(pointer1);
1481 RefPtr<RefCountedAndGarbageCollected> object2(pointer2);
1482 void* objects[2] = { object1.get(), object2.get() };
1483 RefCountedGarbageCollectedVisitor visitor(2, objects);
1484 ThreadState::current()->visitPersistents(&visitor);
1485 EXPECT_TRUE(visitor.validate());
1487 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1488 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
1491 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1492 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
1495 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1496 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls);
1499 TEST(HeapTest, WeakMembers)
1503 Persistent<Bar> h1 = Bar::create();
1504 Persistent<Weak> h4;
1505 Persistent<WithWeakMember> h5;
1506 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1507 ASSERT_EQ(1u, Bar::s_live); // h1 is live.
1509 Bar* h2 = Bar::create();
1510 Bar* h3 = Bar::create();
1511 h4 = Weak::create(h2, h3);
1512 h5 = WithWeakMember::create(h2, h3);
1513 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1514 EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive.
1515 EXPECT_TRUE(h4->strongIsThere());
1516 EXPECT_TRUE(h4->weakIsThere());
1517 EXPECT_TRUE(h5->strongIsThere());
1518 EXPECT_TRUE(h5->weakIsThere());
1520 // h3 is collected, weak pointers from h4 and h5 don't keep it alive.
1521 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1522 EXPECT_EQ(4u, Bar::s_live);
1523 EXPECT_TRUE(h4->strongIsThere());
1524 EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer.
1525 EXPECT_TRUE(h5->strongIsThere());
1526 EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer.
1527 h1.release(); // Zero out h1.
1528 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1529 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left.
1530 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4.
1531 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5.
1533 // h4 and h5 have gone out of scope now and they were keeping h2 alive.
1534 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1535 EXPECT_EQ(0u, Bar::s_live); // All gone.
1538 TEST(HeapTest, Comparisons)
1540 Persistent<Bar> barPersistent = Bar::create();
1541 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
1542 EXPECT_TRUE(barPersistent != fooPersistent);
1543 barPersistent = fooPersistent;
1544 EXPECT_TRUE(barPersistent == fooPersistent);
1547 TEST(HeapTest, CheckAndMarkPointer)
1549 HeapStats initialHeapStats;
1550 clearOutOldGarbage(&initialHeapStats);
1552 Vector<Address> objectAddresses;
1553 Vector<Address> endAddresses;
1554 Address largeObjectAddress;
1555 Address largeObjectEndAddress;
1556 CountingVisitor visitor;
1557 for (int i = 0; i < 10; i++) {
1558 SimpleObject* object = SimpleObject::create();
1559 Address objectAddress = reinterpret_cast<Address>(object);
1560 objectAddresses.append(objectAddress);
1561 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
1563 LargeObject* largeObject = LargeObject::create();
1564 largeObjectAddress = reinterpret_cast<Address>(largeObject);
1565 largeObjectEndAddress = largeObjectAddress + sizeof(LargeObject) - 1;
1567 // This is a low-level test where we call checkAndMarkPointer. This method
1568 // causes the object start bitmap to be computed which requires the heap
1569 // to be in a consistent state (e.g. the free allocation area must be put
1570 // into a free list header). However when we call makeConsistentForGC it
1571 // also clears out the freelists so we have to rebuild those before trying
1572 // to allocate anything again. We do this by forcing a GC after doing the
1573 // checkAndMarkPointer tests.
1575 TestGCScope scope(ThreadState::HeapPointersOnStack);
1576 Heap::makeConsistentForGC();
1577 for (size_t i = 0; i < objectAddresses.size(); i++) {
1578 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
1579 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i]));
1581 EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
1583 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress));
1584 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress));
1585 EXPECT_EQ(2ul, visitor.count());
1588 // This forces a GC without stack scanning which results in the objects
1589 // being collected. This will also rebuild the above mentioned freelists,
1590 // however we don't rely on that below since we don't have any allocations.
1591 clearOutOldGarbage(&initialHeapStats);
1593 TestGCScope scope(ThreadState::HeapPointersOnStack);
1594 Heap::makeConsistentForGC();
1595 for (size_t i = 0; i < objectAddresses.size(); i++) {
1596 EXPECT_FALSE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
1597 EXPECT_FALSE(Heap::checkAndMarkPointer(&visitor, endAddresses[i]));
1599 EXPECT_EQ(0ul, visitor.count());
1600 EXPECT_FALSE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress));
1601 EXPECT_FALSE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress));
1602 EXPECT_EQ(0ul, visitor.count());
1604 // This round of GC is important to make sure that the object start
1605 // bitmap are cleared out and that the free lists are rebuild.
1606 clearOutOldGarbage(&initialHeapStats);
1609 DEFINE_GC_INFO(Bar);
1610 DEFINE_GC_INFO(Baz);
1611 DEFINE_GC_INFO(ClassWithMember);
1612 DEFINE_GC_INFO(ConstructorAllocation);
1613 DEFINE_GC_INFO(HeapAllocatedArray);
1614 DEFINE_GC_INFO(HeapTestSuperClass);
1615 DEFINE_GC_INFO(IntWrapper);
1616 DEFINE_GC_INFO(LargeObject);
1617 DEFINE_GC_INFO(PointsBack);
1618 DEFINE_GC_INFO(RefCountedAndGarbageCollected);
1619 DEFINE_GC_INFO(RefCountedAndGarbageCollected2);
1620 DEFINE_GC_INFO(SimpleFinalizedObject);
1621 DEFINE_GC_INFO(SimpleObject);
1622 DEFINE_GC_INFO(SuperClass);
1623 DEFINE_GC_INFO(SubData);
1624 DEFINE_GC_INFO(TestTypedHeapClass);
1625 DEFINE_GC_INFO(TraceCounter);