Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / heap / HeapTest.cpp
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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
13  * distribution.
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.
17  *
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.
29  */
30
31 #include "config.h"
32
33 #include "platform/Task.h"
34 #include "platform/heap/Handle.h"
35 #include "platform/heap/Heap.h"
36 #include "platform/heap/HeapLinkedStack.h"
37 #include "platform/heap/HeapTerminatedArrayBuilder.h"
38 #include "platform/heap/ThreadState.h"
39 #include "platform/heap/Visitor.h"
40 #include "public/platform/Platform.h"
41 #include "wtf/HashTraits.h"
42 #include "wtf/LinkedHashSet.h"
43
44 #include <gtest/gtest.h>
45
46 namespace blink {
47
48 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> {
49 public:
50     static IntWrapper* create(int x)
51     {
52         return new IntWrapper(x);
53     }
54
55     virtual ~IntWrapper()
56     {
57         ++s_destructorCalls;
58     }
59
60     static int s_destructorCalls;
61     static void trace(Visitor*) { }
62
63     int value() const { return m_x; }
64
65     bool operator==(const IntWrapper& other) const { return other.value() == value(); }
66
67     unsigned hash() { return IntHash<int>::hash(m_x); }
68
69     IntWrapper(int x) : m_x(x) { }
70
71 private:
72     IntWrapper();
73     int m_x;
74 };
75
76 USED_FROM_MULTIPLE_THREADS(IntWrapper);
77
78 class ThreadMarker {
79 public:
80     ThreadMarker() : m_creatingThread(reinterpret_cast<ThreadState*>(0)), m_num(0) { }
81     ThreadMarker(unsigned i) : m_creatingThread(ThreadState::current()), m_num(i) { }
82     ThreadMarker(WTF::HashTableDeletedValueType deleted) : m_creatingThread(reinterpret_cast<ThreadState*>(-1)), m_num(0) { }
83     ~ThreadMarker()
84     {
85         EXPECT_TRUE((m_creatingThread == ThreadState::current())
86             || (m_creatingThread == reinterpret_cast<ThreadState*>(0))
87             || (m_creatingThread == reinterpret_cast<ThreadState*>(-1)));
88     }
89     bool isHashTableDeletedValue() const { return m_creatingThread == reinterpret_cast<ThreadState*>(-1); }
90     bool operator==(const ThreadMarker& other) const { return other.m_creatingThread == m_creatingThread && other.m_num == m_num; }
91     ThreadState* m_creatingThread;
92     unsigned m_num;
93 };
94
95 struct ThreadMarkerHash {
96     static unsigned hash(const ThreadMarker& key)
97     {
98         return static_cast<unsigned>(reinterpret_cast<uintptr_t>(key.m_creatingThread) + key.m_num);
99     }
100
101     static bool equal(const ThreadMarker& a, const ThreadMarker& b)
102     {
103         return a == b;
104     }
105
106     static const bool safeToCompareToEmptyOrDeleted = false;
107 };
108
109 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeakPair;
110
111 struct PairWithWeakHandling : public StrongWeakPair {
112     ALLOW_ONLY_INLINE_ALLOCATION();
113
114 public:
115     // Regular constructor.
116     PairWithWeakHandling(IntWrapper* one, IntWrapper* two)
117         : StrongWeakPair(one, two)
118     {
119         ASSERT(one); // We use null first field to indicate empty slots in the hash table.
120     }
121
122     // The HashTable (via the HashTrait) calls this constructor with a
123     // placement new to mark slots in the hash table as being deleted. We will
124     // never call trace or the destructor on these slots. We mark ourselves deleted
125     // with a pointer to -1 in the first field.
126     PairWithWeakHandling(WTF::HashTableDeletedValueType)
127         : StrongWeakPair(reinterpret_cast<IntWrapper*>(-1), nullptr)
128     {
129     }
130
131     // Used by the HashTable (via the HashTrait) to skip deleted slots in the
132     // table. Recognizes objects that were 'constructed' using the above
133     // constructor.
134     bool isHashTableDeletedValue() const { return first == reinterpret_cast<IntWrapper*>(-1); }
135
136     // Since we don't allocate independent objects of this type, we don't need
137     // a regular trace method. Instead, we use a traceInCollection method. If
138     // the entry should be deleted from the collection we return true and don't
139     // trace the strong pointer.
140     bool traceInCollection(Visitor* visitor, WTF::ShouldWeakPointersBeMarkedStrongly strongify)
141     {
142         visitor->traceInCollection(second, strongify);
143         if (!visitor->isAlive(second))
144             return true;
145         visitor->trace(first);
146         return false;
147     }
148 };
149
150 }
151
152 namespace WTF {
153
154 template<typename T> struct DefaultHash;
155 template<> struct DefaultHash<blink::ThreadMarker> {
156     typedef blink::ThreadMarkerHash Hash;
157 };
158
159 // ThreadMarkerHash is the default hash for ThreadMarker
160 template<> struct HashTraits<blink::ThreadMarker> : GenericHashTraits<blink::ThreadMarker> {
161     static const bool emptyValueIsZero = true;
162     static void constructDeletedValue(blink::ThreadMarker& slot, bool) { new (NotNull, &slot) blink::ThreadMarker(HashTableDeletedValue); }
163     static bool isDeletedValue(const blink::ThreadMarker& slot) { return slot.isHashTableDeletedValue(); }
164 };
165
166 // The hash algorithm for our custom pair class is just the standard double
167 // hash for pairs. Note that this means you can't mutate either of the parts of
168 // the pair while they are in the hash table, as that would change their hash
169 // code and thus their preferred placement in the table.
170 template<> struct DefaultHash<blink::PairWithWeakHandling> {
171     typedef PairHash<blink::Member<blink::IntWrapper>, blink::WeakMember<blink::IntWrapper> > Hash;
172 };
173
174 // Custom traits for the pair. These are weakness handling traits, which means
175 // PairWithWeakHandling must implement the traceInCollection method.
176 // In addition, these traits are concerned with the two magic values for the
177 // object, that represent empty and deleted slots in the hash table. The
178 // SimpleClassHashTraits allow empty slots in the table to be initialzed with
179 // memset to zero, and we use -1 in the first part of the pair to represent
180 // deleted slots.
181 template<> struct HashTraits<blink::PairWithWeakHandling> : blink::WeakHandlingHashTraits<blink::PairWithWeakHandling> {
182     static const bool needsDestruction = false;
183     static const bool hasIsEmptyValueFunction = true;
184     static bool isEmptyValue(const blink::PairWithWeakHandling& value) { return !value.first; }
185     static void constructDeletedValue(blink::PairWithWeakHandling& slot, bool) { new (NotNull, &slot) blink::PairWithWeakHandling(HashTableDeletedValue); }
186     static bool isDeletedValue(const blink::PairWithWeakHandling& value) { return value.isHashTableDeletedValue(); }
187 };
188
189 }
190
191 namespace blink {
192
193 class TestGCScope {
194 public:
195     explicit TestGCScope(ThreadState::StackState state)
196         : m_state(ThreadState::current())
197         , m_safePointScope(state)
198         , m_parkedAllThreads(false)
199     {
200         m_state->checkThread();
201         EXPECT_FALSE(m_state->isInGC());
202         if (LIKELY(ThreadState::stopThreads())) {
203             m_state->enterGC();
204             m_parkedAllThreads = true;
205         }
206     }
207
208     bool allThreadsParked() { return m_parkedAllThreads; }
209
210     ~TestGCScope()
211     {
212         // Only cleanup if we parked all threads in which case the GC happened
213         // and we need to resume the other threads.
214         if (LIKELY(m_parkedAllThreads)) {
215             m_state->leaveGC();
216             EXPECT_FALSE(m_state->isInGC());
217             ThreadState::resumeThreads();
218         }
219     }
220
221 private:
222     ThreadState* m_state;
223     ThreadState::SafePointScope m_safePointScope;
224     bool m_parkedAllThreads; // False if we fail to park all threads
225 };
226
227 static void getHeapStats(HeapStats* stats)
228 {
229     TestGCScope scope(ThreadState::NoHeapPointersOnStack);
230     EXPECT_TRUE(scope.allThreadsParked());
231     Heap::getStats(stats);
232 }
233
234 #define DEFINE_VISITOR_METHODS(Type)                                       \
235     virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
236     {                                                                      \
237         if (object)                                                        \
238             m_count++;                                                     \
239     }                                                                      \
240     virtual bool isMarked(const Type*) OVERRIDE { return false; }
241
242 class CountingVisitor : public Visitor {
243 public:
244     CountingVisitor()
245         : m_count(0)
246     {
247     }
248
249     virtual void mark(const void* object, TraceCallback) OVERRIDE
250     {
251         if (object)
252             m_count++;
253     }
254
255     virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
256     {
257         ASSERT(header->payload());
258         m_count++;
259     }
260
261     virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
262     {
263         ASSERT(header->payload());
264         m_count++;
265     }
266
267     virtual void registerDelayedMarkNoTracing(const void*) OVERRIDE { }
268     virtual void registerWeakMembers(const void*, const void*, WeakPointerCallback) OVERRIDE { }
269     virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCallback) OVERRIDE { }
270 #if ENABLE(ASSERT)
271     virtual bool weakTableRegistered(const void*) OVERRIDE { return false; }
272 #endif
273     virtual void registerWeakCell(void**, WeakPointerCallback) OVERRIDE { }
274     virtual bool isMarked(const void*) OVERRIDE { return false; }
275
276     FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
277
278     size_t count() { return m_count; }
279     void reset() { m_count = 0; }
280
281 private:
282     size_t m_count;
283 };
284
285 class SimpleObject : public GarbageCollected<SimpleObject> {
286 public:
287     static SimpleObject* create() { return new SimpleObject(); }
288     void trace(Visitor*) { }
289     char getPayload(int i) { return payload[i]; }
290     // This virtual method is unused but it is here to make sure
291     // that this object has a vtable. This object is used
292     // as the super class for objects that also have garbage
293     // collected mixins and having a virtual here makes sure
294     // that adjustment is needed both for marking and for isAlive
295     // checks.
296     virtual void virtualMethod() { }
297 protected:
298     SimpleObject() { }
299     char payload[64];
300 };
301
302 #undef DEFINE_VISITOR_METHODS
303
304 class HeapTestSuperClass : public GarbageCollectedFinalized<HeapTestSuperClass> {
305 public:
306     static HeapTestSuperClass* create()
307     {
308         return new HeapTestSuperClass();
309     }
310
311     virtual ~HeapTestSuperClass()
312     {
313         ++s_destructorCalls;
314     }
315
316     static int s_destructorCalls;
317     void trace(Visitor*) { }
318
319 protected:
320     HeapTestSuperClass() { }
321 };
322
323 int HeapTestSuperClass::s_destructorCalls = 0;
324
325 class HeapTestOtherSuperClass {
326 public:
327     int payload;
328 };
329
330 static const size_t classMagic = 0xABCDDBCA;
331
332 class HeapTestSubClass : public HeapTestOtherSuperClass, public HeapTestSuperClass {
333 public:
334     static HeapTestSubClass* create()
335     {
336         return new HeapTestSubClass();
337     }
338
339     virtual ~HeapTestSubClass()
340     {
341         EXPECT_EQ(classMagic, m_magic);
342         ++s_destructorCalls;
343     }
344
345     static int s_destructorCalls;
346
347 private:
348
349     HeapTestSubClass() : m_magic(classMagic) { }
350
351     const size_t m_magic;
352 };
353
354 int HeapTestSubClass::s_destructorCalls = 0;
355
356 class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
357 public:
358     HeapAllocatedArray()
359     {
360         for (int i = 0; i < s_arraySize; ++i) {
361             m_array[i] = i % 128;
362         }
363     }
364
365     int8_t at(size_t i) { return m_array[i]; }
366     void trace(Visitor*) { }
367 private:
368     static const int s_arraySize = 1000;
369     int8_t m_array[s_arraySize];
370 };
371
372 // Do several GCs to make sure that later GCs don't free up old memory from
373 // previously run tests in this process.
374 static void clearOutOldGarbage(HeapStats* heapStats)
375 {
376     while (true) {
377         getHeapStats(heapStats);
378         size_t used = heapStats->totalObjectSpace();
379         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
380         getHeapStats(heapStats);
381         if (heapStats->totalObjectSpace() >= used)
382             break;
383     }
384 }
385
386 class OffHeapInt : public RefCounted<OffHeapInt> {
387 public:
388     static RefPtr<OffHeapInt> create(int x)
389     {
390         return adoptRef(new OffHeapInt(x));
391     }
392
393     virtual ~OffHeapInt()
394     {
395         ++s_destructorCalls;
396     }
397
398     static int s_destructorCalls;
399
400     int value() const { return m_x; }
401
402     bool operator==(const OffHeapInt& other) const { return other.value() == value(); }
403
404     unsigned hash() { return IntHash<int>::hash(m_x); }
405     void voidFunction() { }
406
407 protected:
408     OffHeapInt(int x) : m_x(x) { }
409
410 private:
411     OffHeapInt();
412     int m_x;
413 };
414
415 int IntWrapper::s_destructorCalls = 0;
416 int OffHeapInt::s_destructorCalls = 0;
417
418 class ThreadedTesterBase {
419 protected:
420     static void test(ThreadedTesterBase* tester)
421     {
422         Vector<OwnPtr<WebThread>, numberOfThreads> m_threads;
423         for (int i = 0; i < numberOfThreads; i++) {
424             m_threads.append(adoptPtr(Platform::current()->createThread("blink gc testing thread")));
425             m_threads.last()->postTask(new Task(WTF::bind(threadFunc, tester)));
426         }
427         while (tester->m_threadsToFinish) {
428             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
429             Platform::current()->yieldCurrentThread();
430         }
431         delete tester;
432     }
433
434     virtual void runThread() = 0;
435
436 protected:
437     static const int numberOfThreads = 10;
438     static const int gcPerThread = 5;
439     static const int numberOfAllocations = 50;
440
441     ThreadedTesterBase() : m_gcCount(0), m_threadsToFinish(numberOfThreads)
442     {
443     }
444
445     virtual ~ThreadedTesterBase()
446     {
447     }
448
449     inline bool done() const { return m_gcCount >= numberOfThreads * gcPerThread; }
450
451     volatile int m_gcCount;
452     volatile int m_threadsToFinish;
453
454 private:
455     static void threadFunc(void* data)
456     {
457         reinterpret_cast<ThreadedTesterBase*>(data)->runThread();
458     }
459 };
460
461 class ThreadedHeapTester : public ThreadedTesterBase {
462 public:
463     static void test()
464     {
465         ThreadedTesterBase::test(new ThreadedHeapTester);
466     }
467
468 protected:
469     virtual void runThread() OVERRIDE
470     {
471         ThreadState::attach();
472
473         int gcCount = 0;
474         while (!done()) {
475             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
476             {
477                 Persistent<IntWrapper> wrapper;
478
479                 typedef Persistent<IntWrapper, GlobalPersistents> GlobalIntWrapperPersistent;
480                 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(0x0ed0cabb)));
481
482                 for (int i = 0; i < numberOfAllocations; i++) {
483                     wrapper = IntWrapper::create(0x0bbac0de);
484                     if (!(i % 10)) {
485                         globalPersistent = adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(0x0ed0cabb)));
486                     }
487                     ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
488                     Platform::current()->yieldCurrentThread();
489                 }
490
491                 if (gcCount < gcPerThread) {
492                     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
493                     gcCount++;
494                     atomicIncrement(&m_gcCount);
495                 }
496
497                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
498                 EXPECT_EQ(wrapper->value(), 0x0bbac0de);
499                 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb);
500             }
501             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
502             Platform::current()->yieldCurrentThread();
503         }
504         ThreadState::detach();
505         atomicDecrement(&m_threadsToFinish);
506     }
507 };
508
509 class ThreadedWeaknessTester : public ThreadedTesterBase {
510 public:
511     static void test()
512     {
513         ThreadedTesterBase::test(new ThreadedWeaknessTester);
514     }
515
516 private:
517     virtual void runThread() OVERRIDE
518     {
519         ThreadState::attach();
520
521         int gcCount = 0;
522         while (!done()) {
523             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
524             {
525                 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper> > > weakMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper> >;
526                 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper> > weakMap2;
527
528                 for (int i = 0; i < numberOfAllocations; i++) {
529                     weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0));
530                     weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0));
531                     ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
532                     Platform::current()->yieldCurrentThread();
533                 }
534
535                 if (gcCount < gcPerThread) {
536                     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
537                     gcCount++;
538                     atomicIncrement(&m_gcCount);
539                 }
540
541                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
542                 EXPECT_TRUE(weakMap->isEmpty());
543                 EXPECT_TRUE(weakMap2.isEmpty());
544             }
545             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
546             Platform::current()->yieldCurrentThread();
547         }
548         ThreadState::detach();
549         atomicDecrement(&m_threadsToFinish);
550     }
551 };
552
553 // The accounting for memory includes the memory used by rounding up object
554 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
555 // have some slack in the tests.
556 template<typename T>
557 void CheckWithSlack(T expected, T actual, int slack)
558 {
559     EXPECT_LE(expected, actual);
560     EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
561 }
562
563 class TraceCounter : public GarbageCollectedFinalized<TraceCounter> {
564 public:
565     static TraceCounter* create()
566     {
567         return new TraceCounter();
568     }
569
570     void trace(Visitor*) { m_traceCount++; }
571
572     int traceCount() { return m_traceCount; }
573
574 private:
575     TraceCounter()
576         : m_traceCount(0)
577     {
578     }
579
580     int m_traceCount;
581 };
582
583 class ClassWithMember : public GarbageCollected<ClassWithMember> {
584 public:
585     static ClassWithMember* create()
586     {
587         return new ClassWithMember();
588     }
589
590     void trace(Visitor* visitor)
591     {
592         EXPECT_TRUE(visitor->isMarked(this));
593         if (!traceCount())
594             EXPECT_FALSE(visitor->isMarked(m_traceCounter));
595         else
596             EXPECT_TRUE(visitor->isMarked(m_traceCounter));
597
598         visitor->trace(m_traceCounter);
599     }
600
601     int traceCount() { return m_traceCounter->traceCount(); }
602
603 private:
604     ClassWithMember()
605         : m_traceCounter(TraceCounter::create())
606     { }
607
608     Member<TraceCounter> m_traceCounter;
609 };
610
611 class SimpleFinalizedObject : public GarbageCollectedFinalized<SimpleFinalizedObject> {
612 public:
613     static SimpleFinalizedObject* create()
614     {
615         return new SimpleFinalizedObject();
616     }
617
618     ~SimpleFinalizedObject()
619     {
620         ++s_destructorCalls;
621     }
622
623     static int s_destructorCalls;
624
625     void trace(Visitor*) { }
626
627 private:
628     SimpleFinalizedObject() { }
629 };
630
631 int SimpleFinalizedObject::s_destructorCalls = 0;
632
633 class Node : public GarbageCollected<Node> {
634 public:
635     static Node* create(int i)
636     {
637         return new Node(i);
638     }
639
640     void trace(Visitor*) { }
641
642     int value() { return m_value; }
643
644 private:
645     Node(int i) : m_value(i) { }
646     int m_value;
647 };
648
649 class Bar : public GarbageCollectedFinalized<Bar> {
650 public:
651     static Bar* create()
652     {
653         return new Bar();
654     }
655
656     void finalizeGarbageCollectedObject()
657     {
658         EXPECT_TRUE(m_magic == magic);
659         m_magic = 0;
660         s_live--;
661     }
662     bool hasBeenFinalized() const { return !m_magic; }
663
664     virtual void trace(Visitor* visitor) { }
665     static unsigned s_live;
666
667 protected:
668     static const int magic = 1337;
669     int m_magic;
670
671     Bar()
672         : m_magic(magic)
673     {
674         s_live++;
675     }
676 };
677
678 unsigned Bar::s_live = 0;
679
680 class Baz : public GarbageCollected<Baz> {
681 public:
682     static Baz* create(Bar* bar)
683     {
684         return new Baz(bar);
685     }
686
687     void trace(Visitor* visitor)
688     {
689         visitor->trace(m_bar);
690     }
691
692     void clear() { m_bar.release(); }
693
694     // willFinalize is called by FinalizationObserver.
695     void willFinalize()
696     {
697         EXPECT_TRUE(!m_bar->hasBeenFinalized());
698     }
699
700 private:
701     explicit Baz(Bar* bar)
702         : m_bar(bar)
703     {
704     }
705
706     Member<Bar> m_bar;
707 };
708
709 class Foo : public Bar {
710 public:
711     static Foo* create(Bar* bar)
712     {
713         return new Foo(bar);
714     }
715
716     static Foo* create(Foo* foo)
717     {
718         return new Foo(foo);
719     }
720
721     virtual void trace(Visitor* visitor) OVERRIDE
722     {
723         if (m_pointsToFoo)
724             visitor->mark(static_cast<Foo*>(m_bar));
725         else
726             visitor->mark(m_bar);
727     }
728
729 private:
730     Foo(Bar* bar)
731         : Bar()
732         , m_bar(bar)
733         , m_pointsToFoo(false)
734     {
735     }
736
737     Foo(Foo* foo)
738         : Bar()
739         , m_bar(foo)
740         , m_pointsToFoo(true)
741     {
742     }
743
744     Bar* m_bar;
745     bool m_pointsToFoo;
746 };
747
748 class Bars : public Bar {
749 public:
750     static Bars* create()
751     {
752         return new Bars();
753     }
754
755     virtual void trace(Visitor* visitor) OVERRIDE
756     {
757         for (unsigned i = 0; i < m_width; i++)
758             visitor->trace(m_bars[i]);
759     }
760
761     unsigned getWidth() const
762     {
763         return m_width;
764     }
765
766     static const unsigned width = 7500;
767 private:
768     Bars() : m_width(0)
769     {
770         for (unsigned i = 0; i < width; i++) {
771             m_bars[i] = Bar::create();
772             m_width++;
773         }
774     }
775
776     unsigned m_width;
777     Member<Bar> m_bars[width];
778 };
779
780 class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
781 public:
782     static ConstructorAllocation* create() { return new ConstructorAllocation(); }
783
784     void trace(Visitor* visitor) { visitor->trace(m_intWrapper); }
785
786 private:
787     ConstructorAllocation()
788     {
789         m_intWrapper = IntWrapper::create(42);
790     }
791
792     Member<IntWrapper> m_intWrapper;
793 };
794
795 class LargeObject : public GarbageCollectedFinalized<LargeObject> {
796 public:
797     ~LargeObject()
798     {
799         s_destructorCalls++;
800     }
801     static LargeObject* create() { return new LargeObject(); }
802     char get(size_t i) { return m_data[i]; }
803     void set(size_t i, char c) { m_data[i] = c; }
804     size_t length() { return s_length; }
805     void trace(Visitor* visitor)
806     {
807         visitor->trace(m_intWrapper);
808     }
809     static int s_destructorCalls;
810
811 private:
812     static const size_t s_length = 1024*1024;
813     LargeObject()
814     {
815         m_intWrapper = IntWrapper::create(23);
816     }
817     Member<IntWrapper> m_intWrapper;
818     char m_data[s_length];
819 };
820
821 int LargeObject::s_destructorCalls = 0;
822
823 class RefCountedAndGarbageCollected : public RefCountedGarbageCollected<RefCountedAndGarbageCollected> {
824 public:
825     static PassRefPtr<RefCountedAndGarbageCollected> create()
826     {
827         return adoptRef(new RefCountedAndGarbageCollected());
828     }
829
830     ~RefCountedAndGarbageCollected()
831     {
832         ++s_destructorCalls;
833     }
834
835     // These are here with their default implementations so you can break in
836     // them in the debugger.
837     void ref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::ref(); }
838     void deref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::deref(); }
839
840     void trace(Visitor*) { }
841
842     static int s_destructorCalls;
843
844 private:
845     RefCountedAndGarbageCollected()
846     {
847     }
848 };
849
850 int RefCountedAndGarbageCollected::s_destructorCalls = 0;
851
852 class RefCountedAndGarbageCollected2 : public HeapTestOtherSuperClass, public RefCountedGarbageCollected<RefCountedAndGarbageCollected2> {
853 public:
854     static RefCountedAndGarbageCollected2* create()
855     {
856         return adoptRefCountedGarbageCollected(new RefCountedAndGarbageCollected2());
857     }
858
859     ~RefCountedAndGarbageCollected2()
860     {
861         ++s_destructorCalls;
862     }
863
864     void trace(Visitor*) { }
865
866     static int s_destructorCalls;
867
868 private:
869     RefCountedAndGarbageCollected2()
870     {
871     }
872 };
873
874 int RefCountedAndGarbageCollected2::s_destructorCalls = 0;
875
876 #define DEFINE_VISITOR_METHODS(Type)                                       \
877     virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
878     {                                                                      \
879         mark(object);                                                      \
880     }                                                                      \
881
882 class RefCountedGarbageCollectedVisitor : public CountingVisitor {
883 public:
884     RefCountedGarbageCollectedVisitor(int expected, void** objects)
885         : m_count(0)
886         , m_expectedCount(expected)
887         , m_expectedObjects(objects)
888     {
889     }
890
891     void mark(const void* ptr) { markNoTrace(ptr); }
892
893     virtual void markNoTrace(const void* ptr)
894     {
895         if (!ptr)
896             return;
897         if (m_count < m_expectedCount)
898             EXPECT_TRUE(expectedObject(ptr));
899         else
900             EXPECT_FALSE(expectedObject(ptr));
901         m_count++;
902     }
903
904     virtual void mark(const void* ptr, TraceCallback) OVERRIDE
905     {
906         mark(ptr);
907     }
908
909     virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
910     {
911         mark(header->payload());
912     }
913
914     virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
915     {
916         mark(header->payload());
917     }
918
919     bool validate() { return m_count >= m_expectedCount; }
920     void reset() { m_count = 0; }
921
922     FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
923
924 private:
925     bool expectedObject(const void* ptr)
926     {
927         for (int i = 0; i < m_expectedCount; i++) {
928             if (m_expectedObjects[i] == ptr)
929                 return true;
930         }
931         return false;
932     }
933
934     int m_count;
935     int m_expectedCount;
936     void** m_expectedObjects;
937 };
938
939 #undef DEFINE_VISITOR_METHODS
940
941 class Weak : public Bar {
942 public:
943     static Weak* create(Bar* strong, Bar* weak)
944     {
945         return new Weak(strong, weak);
946     }
947
948     virtual void trace(Visitor* visitor) OVERRIDE
949     {
950         visitor->trace(m_strongBar);
951         visitor->registerWeakMembers(this, zapWeakMembers);
952     }
953
954     static void zapWeakMembers(Visitor* visitor, void* self)
955     {
956         reinterpret_cast<Weak*>(self)->zapWeakMembers(visitor);
957     }
958
959     bool strongIsThere() { return !!m_strongBar; }
960     bool weakIsThere() { return !!m_weakBar; }
961
962 private:
963     Weak(Bar* strongBar, Bar* weakBar)
964         : Bar()
965         , m_strongBar(strongBar)
966         , m_weakBar(weakBar)
967     {
968     }
969
970     void zapWeakMembers(Visitor* visitor)
971     {
972         if (!visitor->isAlive(m_weakBar))
973             m_weakBar = 0;
974     }
975
976     Member<Bar> m_strongBar;
977     Bar* m_weakBar;
978 };
979
980 class WithWeakMember : public Bar {
981 public:
982     static WithWeakMember* create(Bar* strong, Bar* weak)
983     {
984         return new WithWeakMember(strong, weak);
985     }
986
987     virtual void trace(Visitor* visitor) OVERRIDE
988     {
989         visitor->trace(m_strongBar);
990         visitor->trace(m_weakBar);
991     }
992
993     bool strongIsThere() { return !!m_strongBar; }
994     bool weakIsThere() { return !!m_weakBar; }
995
996 private:
997     WithWeakMember(Bar* strongBar, Bar* weakBar)
998         : Bar()
999         , m_strongBar(strongBar)
1000         , m_weakBar(weakBar)
1001     {
1002     }
1003
1004     Member<Bar> m_strongBar;
1005     WeakMember<Bar> m_weakBar;
1006 };
1007
1008 class Observable : public GarbageCollectedFinalized<Observable> {
1009 public:
1010     static Observable* create(Bar* bar) { return new Observable(bar);  }
1011     ~Observable() { m_wasDestructed = true; }
1012     void trace(Visitor* visitor) { visitor->trace(m_bar); }
1013
1014     // willFinalize is called by FinalizationObserver. willFinalize can touch
1015     // other on-heap objects.
1016     void willFinalize()
1017     {
1018         EXPECT_FALSE(m_wasDestructed);
1019         EXPECT_FALSE(m_bar->hasBeenFinalized());
1020     }
1021
1022 private:
1023     explicit Observable(Bar* bar)
1024         : m_bar(bar)
1025         , m_wasDestructed(false)
1026     {
1027     }
1028
1029     Member<Bar> m_bar;
1030     bool m_wasDestructed;
1031 };
1032
1033 template <typename T> class FinalizationObserver : public GarbageCollected<FinalizationObserver<T> > {
1034 public:
1035     static FinalizationObserver* create(T* data) { return new FinalizationObserver(data); }
1036     bool didCallWillFinalize() const { return m_didCallWillFinalize; }
1037
1038     void trace(Visitor* visitor)
1039     {
1040         visitor->registerWeakMembers(this, zapWeakMembers);
1041     }
1042
1043 private:
1044     FinalizationObserver(T* data)
1045         : m_data(data)
1046         , m_didCallWillFinalize(false)
1047     {
1048     }
1049
1050     static void zapWeakMembers(Visitor* visitor, void* self)
1051     {
1052         FinalizationObserver* o = reinterpret_cast<FinalizationObserver*>(self);
1053         if (o->m_data && !visitor->isAlive(o->m_data)) {
1054             o->m_data->willFinalize();
1055             o->m_data = nullptr;
1056             o->m_didCallWillFinalize = true;
1057         }
1058     }
1059
1060     WeakMember<T> m_data;
1061     bool m_didCallWillFinalize;
1062 };
1063
1064 class FinalizationObserverWithHashMap {
1065 public:
1066     typedef HeapHashMap<WeakMember<Observable>, OwnPtr<FinalizationObserverWithHashMap> > ObserverMap;
1067
1068     explicit FinalizationObserverWithHashMap(Observable& target) : m_target(target) { }
1069     ~FinalizationObserverWithHashMap()
1070     {
1071         m_target.willFinalize();
1072         s_didCallWillFinalize = true;
1073     }
1074
1075     static ObserverMap& observe(Observable& target)
1076     {
1077         ObserverMap& map = observers();
1078         ObserverMap::AddResult result = map.add(&target, nullptr);
1079         if (result.isNewEntry)
1080             result.storedValue->value = adoptPtr(new FinalizationObserverWithHashMap(target));
1081         else
1082             ASSERT(result.storedValue->value);
1083         return map;
1084     }
1085
1086     static bool s_didCallWillFinalize;
1087
1088 private:
1089     static ObserverMap& observers()
1090     {
1091         DEFINE_STATIC_LOCAL(Persistent<ObserverMap>, observerMap, ());
1092         if (!observerMap)
1093             observerMap = new ObserverMap();
1094         return *observerMap;
1095     }
1096
1097     Observable& m_target;
1098 };
1099
1100 bool FinalizationObserverWithHashMap::s_didCallWillFinalize = false;
1101
1102 class SuperClass;
1103
1104 class PointsBack : public RefCountedWillBeGarbageCollectedFinalized<PointsBack> {
1105 public:
1106     static PassRefPtrWillBeRawPtr<PointsBack> create()
1107     {
1108         return adoptRefWillBeNoop(new PointsBack());
1109     }
1110
1111     ~PointsBack()
1112     {
1113         --s_aliveCount;
1114     }
1115
1116     void setBackPointer(SuperClass* backPointer)
1117     {
1118         m_backPointer = backPointer;
1119     }
1120
1121     SuperClass* backPointer() const { return m_backPointer; }
1122
1123     void trace(Visitor* visitor)
1124     {
1125 #if ENABLE_OILPAN
1126         visitor->trace(m_backPointer);
1127 #endif
1128     }
1129
1130     static int s_aliveCount;
1131 private:
1132     PointsBack() : m_backPointer(nullptr)
1133     {
1134         ++s_aliveCount;
1135     }
1136
1137     RawPtrWillBeWeakMember<SuperClass> m_backPointer;
1138 };
1139
1140 int PointsBack::s_aliveCount = 0;
1141
1142 class SuperClass : public RefCountedWillBeGarbageCollectedFinalized<SuperClass> {
1143 public:
1144     static PassRefPtrWillBeRawPtr<SuperClass> create(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
1145     {
1146         return adoptRefWillBeNoop(new SuperClass(pointsBack));
1147     }
1148
1149     virtual ~SuperClass()
1150     {
1151 #if !ENABLE_OILPAN
1152         m_pointsBack->setBackPointer(0);
1153 #endif
1154         --s_aliveCount;
1155     }
1156
1157     void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* pointsBack, int superClassCount)
1158     {
1159         RefPtrWillBeRawPtr<SuperClass> target = targetPass;
1160         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1161         EXPECT_EQ(pointsBack, target->pointsBack());
1162         EXPECT_EQ(superClassCount, SuperClass::s_aliveCount);
1163     }
1164
1165     virtual void trace(Visitor* visitor)
1166     {
1167 #if ENABLE_OILPAN
1168         visitor->trace(m_pointsBack);
1169 #endif
1170     }
1171
1172     PointsBack* pointsBack() const { return m_pointsBack.get(); }
1173
1174     static int s_aliveCount;
1175 protected:
1176     explicit SuperClass(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
1177         : m_pointsBack(pointsBack)
1178     {
1179         m_pointsBack->setBackPointer(this);
1180         ++s_aliveCount;
1181     }
1182
1183 private:
1184     RefPtrWillBeMember<PointsBack> m_pointsBack;
1185 };
1186
1187 int SuperClass::s_aliveCount = 0;
1188 class SubData : public NoBaseWillBeGarbageCollectedFinalized<SubData> {
1189 public:
1190     SubData() { ++s_aliveCount; }
1191     ~SubData() { --s_aliveCount; }
1192
1193     void trace(Visitor*) { }
1194
1195     static int s_aliveCount;
1196 };
1197
1198 int SubData::s_aliveCount = 0;
1199
1200 class SubClass : public SuperClass {
1201 public:
1202     static PassRefPtrWillBeRawPtr<SubClass> create(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
1203     {
1204         return adoptRefWillBeNoop(new SubClass(pointsBack));
1205     }
1206
1207     virtual ~SubClass()
1208     {
1209         --s_aliveCount;
1210     }
1211
1212     virtual void trace(Visitor* visitor)
1213     {
1214 #if ENABLE_OILPAN
1215         SuperClass::trace(visitor);
1216         visitor->trace(m_data);
1217 #endif
1218     }
1219
1220     static int s_aliveCount;
1221 private:
1222     explicit SubClass(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
1223         : SuperClass(pointsBack)
1224         , m_data(adoptPtrWillBeNoop(new SubData()))
1225     {
1226         ++s_aliveCount;
1227     }
1228
1229 private:
1230     OwnPtrWillBeMember<SubData> m_data;
1231 };
1232
1233 int SubClass::s_aliveCount = 0;
1234
1235 class TransitionRefCounted : public RefCountedWillBeRefCountedGarbageCollected<TransitionRefCounted> {
1236 public:
1237     static PassRefPtrWillBeRawPtr<TransitionRefCounted> create()
1238     {
1239         return adoptRefWillBeRefCountedGarbageCollected(new TransitionRefCounted());
1240     }
1241
1242     ~TransitionRefCounted()
1243     {
1244         --s_aliveCount;
1245     }
1246
1247     void trace(Visitor* visitor) { }
1248
1249     static int s_aliveCount;
1250
1251 private:
1252     TransitionRefCounted()
1253     {
1254         ++s_aliveCount;
1255     }
1256 };
1257
1258 int TransitionRefCounted::s_aliveCount = 0;
1259
1260 class Mixin : public GarbageCollectedMixin {
1261 public:
1262     virtual void trace(Visitor* visitor) { }
1263
1264     virtual char getPayload(int i) { return m_padding[i]; }
1265
1266 protected:
1267     int m_padding[8];
1268 };
1269
1270 class UseMixin : public SimpleObject, public Mixin {
1271     USING_GARBAGE_COLLECTED_MIXIN(UseMixin)
1272 public:
1273     static UseMixin* create()
1274     {
1275         return new UseMixin();
1276     }
1277
1278     static int s_traceCount;
1279     virtual void trace(Visitor* visitor)
1280     {
1281         SimpleObject::trace(visitor);
1282         Mixin::trace(visitor);
1283         ++s_traceCount;
1284     }
1285
1286 private:
1287     UseMixin()
1288     {
1289         s_traceCount = 0;
1290     }
1291 };
1292
1293 int UseMixin::s_traceCount = 0;
1294
1295 class VectorObject {
1296     ALLOW_ONLY_INLINE_ALLOCATION();
1297 public:
1298     VectorObject()
1299     {
1300         m_value = SimpleFinalizedObject::create();
1301     }
1302
1303     void trace(Visitor* visitor)
1304     {
1305         visitor->trace(m_value);
1306     }
1307
1308 private:
1309     Member<SimpleFinalizedObject> m_value;
1310 };
1311
1312 class VectorObjectInheritedTrace : public VectorObject { };
1313
1314 class VectorObjectNoTrace {
1315     ALLOW_ONLY_INLINE_ALLOCATION();
1316 public:
1317     VectorObjectNoTrace()
1318     {
1319         m_value = SimpleFinalizedObject::create();
1320     }
1321
1322 private:
1323     Member<SimpleFinalizedObject> m_value;
1324 };
1325
1326 class TerminatedArrayItem {
1327     ALLOW_ONLY_INLINE_ALLOCATION();
1328 public:
1329     TerminatedArrayItem(IntWrapper* payload) : m_payload(payload), m_isLast(false) { }
1330
1331     void trace(Visitor* visitor) { visitor->trace(m_payload); }
1332
1333     bool isLastInArray() const { return m_isLast; }
1334     void setLastInArray(bool value) { m_isLast = value; }
1335
1336     IntWrapper* payload() const { return m_payload; }
1337
1338 private:
1339     Member<IntWrapper> m_payload;
1340     bool m_isLast;
1341 };
1342
1343 } // namespace blink
1344
1345 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObject);
1346 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObjectInheritedTrace);
1347 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObjectNoTrace);
1348
1349 namespace blink {
1350
1351 class OneKiloByteObject : public GarbageCollectedFinalized<OneKiloByteObject> {
1352 public:
1353     ~OneKiloByteObject() { s_destructorCalls++; }
1354     char* data() { return m_data; }
1355     void trace(Visitor* visitor) { }
1356     static int s_destructorCalls;
1357
1358 private:
1359     static const size_t s_length = 1024;
1360     char m_data[s_length];
1361 };
1362
1363 int OneKiloByteObject::s_destructorCalls = 0;
1364
1365 class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> {
1366 public:
1367     static DynamicallySizedObject* create(size_t size)
1368     {
1369         void* slot = Heap::allocate<DynamicallySizedObject>(size);
1370         return new (slot) DynamicallySizedObject();
1371     }
1372
1373     void* operator new(std::size_t, void* location)
1374     {
1375         return location;
1376     }
1377
1378     uint8_t get(int i)
1379     {
1380         return *(reinterpret_cast<uint8_t*>(this) + i);
1381     }
1382
1383     void trace(Visitor*) { }
1384
1385 private:
1386     DynamicallySizedObject() { }
1387 };
1388
1389 class FinalizationAllocator : public GarbageCollectedFinalized<FinalizationAllocator> {
1390 public:
1391     FinalizationAllocator(Persistent<IntWrapper>* wrapper)
1392         : m_wrapper(wrapper)
1393     {
1394     }
1395
1396     ~FinalizationAllocator()
1397     {
1398         for (int i = 0; i < 10; ++i)
1399             *m_wrapper = IntWrapper::create(42);
1400         for (int i = 0; i < 512; ++i)
1401             new OneKiloByteObject();
1402     }
1403
1404     void trace(Visitor*) { }
1405
1406 private:
1407     Persistent<IntWrapper>* m_wrapper;
1408 };
1409
1410 TEST(HeapTest, Transition)
1411 {
1412     {
1413         RefPtr<TransitionRefCounted> refCounted = TransitionRefCounted::create();
1414         EXPECT_EQ(1, TransitionRefCounted::s_aliveCount);
1415         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1416         EXPECT_EQ(1, TransitionRefCounted::s_aliveCount);
1417     }
1418     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1419     EXPECT_EQ(0, TransitionRefCounted::s_aliveCount);
1420
1421     RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create();
1422     RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create();
1423     RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBack1);
1424     RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2);
1425     EXPECT_EQ(2, PointsBack::s_aliveCount);
1426     EXPECT_EQ(2, SuperClass::s_aliveCount);
1427     EXPECT_EQ(1, SubClass::s_aliveCount);
1428     EXPECT_EQ(1, SubData::s_aliveCount);
1429
1430     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1431     EXPECT_EQ(0, TransitionRefCounted::s_aliveCount);
1432     EXPECT_EQ(2, PointsBack::s_aliveCount);
1433     EXPECT_EQ(2, SuperClass::s_aliveCount);
1434     EXPECT_EQ(1, SubClass::s_aliveCount);
1435     EXPECT_EQ(1, SubData::s_aliveCount);
1436
1437     superClass->doStuff(superClass.release(), pointsBack1.get(), 2);
1438     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1439     EXPECT_EQ(2, PointsBack::s_aliveCount);
1440     EXPECT_EQ(1, SuperClass::s_aliveCount);
1441     EXPECT_EQ(1, SubClass::s_aliveCount);
1442     EXPECT_EQ(1, SubData::s_aliveCount);
1443     EXPECT_EQ(0, pointsBack1->backPointer());
1444
1445     pointsBack1.release();
1446     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1447     EXPECT_EQ(1, PointsBack::s_aliveCount);
1448     EXPECT_EQ(1, SuperClass::s_aliveCount);
1449     EXPECT_EQ(1, SubClass::s_aliveCount);
1450     EXPECT_EQ(1, SubData::s_aliveCount);
1451
1452     subClass->doStuff(subClass.release(), pointsBack2.get(), 1);
1453     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1454     EXPECT_EQ(1, PointsBack::s_aliveCount);
1455     EXPECT_EQ(0, SuperClass::s_aliveCount);
1456     EXPECT_EQ(0, SubClass::s_aliveCount);
1457     EXPECT_EQ(0, SubData::s_aliveCount);
1458     EXPECT_EQ(0, pointsBack2->backPointer());
1459
1460     pointsBack2.release();
1461     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1462     EXPECT_EQ(0, PointsBack::s_aliveCount);
1463     EXPECT_EQ(0, SuperClass::s_aliveCount);
1464     EXPECT_EQ(0, SubClass::s_aliveCount);
1465     EXPECT_EQ(0, SubData::s_aliveCount);
1466
1467     EXPECT_TRUE(superClass == subClass);
1468 }
1469
1470 TEST(HeapTest, Threading)
1471 {
1472     ThreadedHeapTester::test();
1473 }
1474
1475 TEST(HeapTest, ThreadedWeakness)
1476 {
1477     ThreadedWeaknessTester::test();
1478 }
1479
1480 TEST(HeapTest, BasicFunctionality)
1481 {
1482     HeapStats heapStats;
1483     clearOutOldGarbage(&heapStats);
1484     {
1485         size_t slack = 0;
1486
1487         // When the test starts there may already have been leaked some memory
1488         // on the heap, so we establish a base line.
1489         size_t baseLevel = heapStats.totalObjectSpace();
1490         bool testPagesAllocated = !baseLevel;
1491         if (testPagesAllocated)
1492             EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
1493
1494         // This allocates objects on the general heap which should add a page of memory.
1495         DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32);
1496         slack += 4;
1497         memset(alloc32, 40, 32);
1498         DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64);
1499         slack += 4;
1500         memset(alloc64, 27, 64);
1501
1502         size_t total = 96;
1503
1504         getHeapStats(&heapStats);
1505         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1506         if (testPagesAllocated)
1507             EXPECT_EQ(heapStats.totalAllocatedSpace(), blinkPageSize);
1508
1509         CheckWithSlack(alloc32 + 32 + sizeof(FinalizedHeapObjectHeader), alloc64, slack);
1510
1511         EXPECT_EQ(alloc32->get(0), 40);
1512         EXPECT_EQ(alloc32->get(31), 40);
1513         EXPECT_EQ(alloc64->get(0), 27);
1514         EXPECT_EQ(alloc64->get(63), 27);
1515
1516         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1517
1518         EXPECT_EQ(alloc32->get(0), 40);
1519         EXPECT_EQ(alloc32->get(31), 40);
1520         EXPECT_EQ(alloc64->get(0), 27);
1521         EXPECT_EQ(alloc64->get(63), 27);
1522     }
1523
1524     clearOutOldGarbage(&heapStats);
1525     size_t total = 0;
1526     size_t slack = 0;
1527     size_t baseLevel = heapStats.totalObjectSpace();
1528     bool testPagesAllocated = !baseLevel;
1529     if (testPagesAllocated)
1530         EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
1531
1532     size_t big = 1008;
1533     Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(big);
1534     total += big;
1535     slack += 4;
1536
1537     size_t persistentCount = 0;
1538     const size_t numPersistents = 100000;
1539     Persistent<DynamicallySizedObject>* persistents[numPersistents];
1540
1541     for (int i = 0; i < 1000; i++) {
1542         size_t size = 128 + i * 8;
1543         total += size;
1544         persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(DynamicallySizedObject::create(size));
1545         slack += 4;
1546         getHeapStats(&heapStats);
1547         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1548         if (testPagesAllocated)
1549             EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1550     }
1551
1552     {
1553         DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32));
1554         slack += 4;
1555         memset(alloc32b, 40, 32);
1556         DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64));
1557         slack += 4;
1558         memset(alloc64b, 27, 64);
1559         EXPECT_TRUE(alloc32b != alloc64b);
1560
1561         total += 96;
1562         getHeapStats(&heapStats);
1563         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1564         if (testPagesAllocated)
1565             EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1566     }
1567
1568     clearOutOldGarbage(&heapStats);
1569     total -= 96;
1570     slack -= 8;
1571     if (testPagesAllocated)
1572         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1573
1574     DynamicallySizedObject* bigAreaRaw = bigArea;
1575     // Clear the persistent, so that the big area will be garbage collected.
1576     bigArea.release();
1577     clearOutOldGarbage(&heapStats);
1578
1579     total -= big;
1580     slack -= 4;
1581     getHeapStats(&heapStats);
1582     CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1583     if (testPagesAllocated)
1584         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1585
1586     // Endless loop unless we eventually get the memory back that we just freed.
1587     while (true) {
1588         Persistent<DynamicallySizedObject>* alloc = new Persistent<DynamicallySizedObject>(DynamicallySizedObject::create(big / 2));
1589         slack += 4;
1590         persistents[persistentCount++] = alloc;
1591         EXPECT_LT(persistentCount, numPersistents);
1592         total += big / 2;
1593         if (bigAreaRaw == alloc->get())
1594             break;
1595     }
1596
1597     getHeapStats(&heapStats);
1598     CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
1599     if (testPagesAllocated)
1600         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
1601
1602     for (size_t i = 0; i < persistentCount; i++) {
1603         delete persistents[i];
1604         persistents[i] = 0;
1605     }
1606
1607     uint8_t* address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(0, 100));
1608     for (int i = 0; i < 100; i++)
1609         address[i] = i;
1610     address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(address, 100000));
1611     for (int i = 0; i < 100; i++)
1612         EXPECT_EQ(address[i], i);
1613     address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(address, 50));
1614     for (int i = 0; i < 50; i++)
1615         EXPECT_EQ(address[i], i);
1616     // This should be equivalent to free(address).
1617     EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObject>(address, 0)), 0ul);
1618     // This should be equivalent to malloc(0).
1619     EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObject>(0, 0)), 0ul);
1620 }
1621
1622 TEST(HeapTest, SimpleAllocation)
1623 {
1624     HeapStats initialHeapStats;
1625     clearOutOldGarbage(&initialHeapStats);
1626     EXPECT_EQ(0ul, initialHeapStats.totalObjectSpace());
1627
1628     // Allocate an object in the heap.
1629     HeapAllocatedArray* array = new HeapAllocatedArray();
1630     HeapStats statsAfterAllocation;
1631     getHeapStats(&statsAfterAllocation);
1632     EXPECT_TRUE(statsAfterAllocation.totalObjectSpace() >= sizeof(HeapAllocatedArray));
1633
1634     // Sanity check of the contents in the heap.
1635     EXPECT_EQ(0, array->at(0));
1636     EXPECT_EQ(42, array->at(42));
1637     EXPECT_EQ(0, array->at(128));
1638     EXPECT_EQ(999 % 128, array->at(999));
1639 }
1640
1641 TEST(HeapTest, SimplePersistent)
1642 {
1643     Persistent<TraceCounter> traceCounter = TraceCounter::create();
1644     EXPECT_EQ(0, traceCounter->traceCount());
1645
1646     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1647     EXPECT_EQ(1, traceCounter->traceCount());
1648
1649     Persistent<ClassWithMember> classWithMember = ClassWithMember::create();
1650     EXPECT_EQ(0, classWithMember->traceCount());
1651
1652     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1653     EXPECT_EQ(1, classWithMember->traceCount());
1654     EXPECT_EQ(2, traceCounter->traceCount());
1655 }
1656
1657 TEST(HeapTest, SimpleFinalization)
1658 {
1659     {
1660         Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::create();
1661         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
1662         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1663         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
1664     }
1665
1666     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1667     EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls);
1668 }
1669
1670 TEST(HeapTest, Finalization)
1671 {
1672     {
1673         HeapTestSubClass* t1 = HeapTestSubClass::create();
1674         HeapTestSubClass* t2 = HeapTestSubClass::create();
1675         HeapTestSuperClass* t3 = HeapTestSuperClass::create();
1676         // FIXME(oilpan): Ignore unused variables.
1677         (void)t1;
1678         (void)t2;
1679         (void)t3;
1680     }
1681     // Nothing is marked so the GC should free everything and call
1682     // the finalizer on all three objects.
1683     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1684     EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
1685     EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
1686     // Destructors not called again when GCing again.
1687     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1688     EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
1689     EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
1690 }
1691
1692 TEST(HeapTest, TypedHeapSanity)
1693 {
1694     // We use TraceCounter for allocating an object on the general heap.
1695     Persistent<TraceCounter> generalHeapObject = TraceCounter::create();
1696     Persistent<Node> typedHeapObject = Node::create(0);
1697     EXPECT_NE(pageHeaderFromObject(generalHeapObject.get()),
1698         pageHeaderFromObject(typedHeapObject.get()));
1699 }
1700
1701 TEST(HeapTest, NoAllocation)
1702 {
1703     EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
1704     {
1705         // Disallow allocation
1706         NoAllocationScope<AnyThread> noAllocationScope;
1707         EXPECT_FALSE(ThreadState::current()->isAllocationAllowed());
1708     }
1709     EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
1710 }
1711
1712 TEST(HeapTest, Members)
1713 {
1714     Bar::s_live = 0;
1715     {
1716         Persistent<Baz> h1;
1717         Persistent<Baz> h2;
1718         {
1719             h1 = Baz::create(Bar::create());
1720             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1721             EXPECT_EQ(1u, Bar::s_live);
1722             h2 = Baz::create(Bar::create());
1723             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1724             EXPECT_EQ(2u, Bar::s_live);
1725         }
1726         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1727         EXPECT_EQ(2u, Bar::s_live);
1728         h1->clear();
1729         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1730         EXPECT_EQ(1u, Bar::s_live);
1731     }
1732     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1733     EXPECT_EQ(0u, Bar::s_live);
1734 }
1735
1736 TEST(HeapTest, MarkTest)
1737 {
1738     {
1739         Bar::s_live = 0;
1740         Persistent<Bar> bar = Bar::create();
1741         EXPECT_TRUE(ThreadState::current()->contains(bar));
1742         EXPECT_EQ(1u, Bar::s_live);
1743         {
1744             Foo* foo = Foo::create(bar);
1745             EXPECT_TRUE(ThreadState::current()->contains(foo));
1746             EXPECT_EQ(2u, Bar::s_live);
1747             EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Address>(bar.get()));
1748             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1749             EXPECT_TRUE(foo != bar); // To make sure foo is kept alive.
1750             EXPECT_EQ(2u, Bar::s_live);
1751         }
1752         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1753         EXPECT_EQ(1u, Bar::s_live);
1754     }
1755     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1756     EXPECT_EQ(0u, Bar::s_live);
1757 }
1758
1759 TEST(HeapTest, DeepTest)
1760 {
1761     const unsigned depth = 100000;
1762     Bar::s_live = 0;
1763     {
1764         Bar* bar = Bar::create();
1765         EXPECT_TRUE(ThreadState::current()->contains(bar));
1766         Foo* foo = Foo::create(bar);
1767         EXPECT_TRUE(ThreadState::current()->contains(foo));
1768         EXPECT_EQ(2u, Bar::s_live);
1769         for (unsigned i = 0; i < depth; i++) {
1770             Foo* foo2 = Foo::create(foo);
1771             foo = foo2;
1772             EXPECT_TRUE(ThreadState::current()->contains(foo));
1773         }
1774         EXPECT_EQ(depth + 2, Bar::s_live);
1775         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1776         EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive.
1777         EXPECT_EQ(depth + 2, Bar::s_live);
1778     }
1779     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1780     EXPECT_EQ(0u, Bar::s_live);
1781 }
1782
1783 TEST(HeapTest, WideTest)
1784 {
1785     Bar::s_live = 0;
1786     {
1787         Bars* bars = Bars::create();
1788         unsigned width = Bars::width;
1789         EXPECT_EQ(width + 1, Bar::s_live);
1790         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
1791         EXPECT_EQ(width + 1, Bar::s_live);
1792         // Use bars here to make sure that it will be on the stack
1793         // for the conservative stack scan to find.
1794         EXPECT_EQ(width, bars->getWidth());
1795     }
1796     EXPECT_EQ(Bars::width + 1, Bar::s_live);
1797     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1798     EXPECT_EQ(0u, Bar::s_live);
1799 }
1800
1801 TEST(HeapTest, HashMapOfMembers)
1802 {
1803     HeapStats initialHeapSize;
1804     IntWrapper::s_destructorCalls = 0;
1805
1806     clearOutOldGarbage(&initialHeapSize);
1807     {
1808         typedef HeapHashMap<
1809             Member<IntWrapper>,
1810             Member<IntWrapper>,
1811             DefaultHash<Member<IntWrapper> >::Hash,
1812             HashTraits<Member<IntWrapper> >,
1813             HashTraits<Member<IntWrapper> > > HeapObjectIdentityMap;
1814
1815         Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap();
1816
1817         map->clear();
1818         HeapStats afterSetWasCreated;
1819         getHeapStats(&afterSetWasCreated);
1820         EXPECT_TRUE(afterSetWasCreated.totalObjectSpace() > initialHeapSize.totalObjectSpace());
1821
1822         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1823         HeapStats afterGC;
1824         getHeapStats(&afterGC);
1825         EXPECT_EQ(afterGC.totalObjectSpace(), afterSetWasCreated.totalObjectSpace());
1826
1827         // If the additions below cause garbage collections, these
1828         // pointers should be found by conservative stack scanning.
1829         IntWrapper* one(IntWrapper::create(1));
1830         IntWrapper* anotherOne(IntWrapper::create(1));
1831
1832         map->add(one, one);
1833
1834         HeapStats afterOneAdd;
1835         getHeapStats(&afterOneAdd);
1836         EXPECT_TRUE(afterOneAdd.totalObjectSpace() > afterGC.totalObjectSpace());
1837
1838         HeapObjectIdentityMap::iterator it(map->begin());
1839         HeapObjectIdentityMap::iterator it2(map->begin());
1840         ++it;
1841         ++it2;
1842
1843         map->add(anotherOne, one);
1844
1845         // The addition above can cause an allocation of a new
1846         // backing store. We therefore garbage collect before
1847         // taking the heap stats in order to get rid of the old
1848         // backing store. We make sure to not use conservative
1849         // stack scanning as that could find a pointer to the
1850         // old backing.
1851         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1852         HeapStats afterAddAndGC;
1853         getHeapStats(&afterAddAndGC);
1854         EXPECT_TRUE(afterAddAndGC.totalObjectSpace() >= afterOneAdd.totalObjectSpace());
1855
1856         EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distinct.
1857
1858         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1859         EXPECT_TRUE(map->contains(one));
1860         EXPECT_TRUE(map->contains(anotherOne));
1861
1862         IntWrapper* gotten(map->get(one));
1863         EXPECT_EQ(gotten->value(), one->value());
1864         EXPECT_EQ(gotten, one);
1865
1866         HeapStats afterGC2;
1867         getHeapStats(&afterGC2);
1868         EXPECT_EQ(afterGC2.totalObjectSpace(), afterAddAndGC.totalObjectSpace());
1869
1870         IntWrapper* dozen = 0;
1871
1872         for (int i = 1; i < 1000; i++) { // 999 iterations.
1873             IntWrapper* iWrapper(IntWrapper::create(i));
1874             IntWrapper* iSquared(IntWrapper::create(i * i));
1875             map->add(iWrapper, iSquared);
1876             if (i == 12)
1877                 dozen = iWrapper;
1878         }
1879         HeapStats afterAdding1000;
1880         getHeapStats(&afterAdding1000);
1881         EXPECT_TRUE(afterAdding1000.totalObjectSpace() > afterGC2.totalObjectSpace());
1882
1883         IntWrapper* gross(map->get(dozen));
1884         EXPECT_EQ(gross->value(), 144);
1885
1886         // This should clear out any junk backings created by all the adds.
1887         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1888         HeapStats afterGC3;
1889         getHeapStats(&afterGC3);
1890         EXPECT_TRUE(afterGC3.totalObjectSpace() <= afterAdding1000.totalObjectSpace());
1891     }
1892
1893     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1894     // The objects 'one', anotherOne, and the 999 other pairs.
1895     EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
1896     HeapStats afterGC4;
1897     getHeapStats(&afterGC4);
1898     EXPECT_EQ(afterGC4.totalObjectSpace(), initialHeapSize.totalObjectSpace());
1899 }
1900
1901 TEST(HeapTest, NestedAllocation)
1902 {
1903     HeapStats initialHeapSize;
1904     clearOutOldGarbage(&initialHeapSize);
1905     {
1906         Persistent<ConstructorAllocation> constructorAllocation = ConstructorAllocation::create();
1907     }
1908     HeapStats afterFree;
1909     clearOutOldGarbage(&afterFree);
1910     EXPECT_TRUE(initialHeapSize == afterFree);
1911 }
1912
1913 TEST(HeapTest, LargeObjects)
1914 {
1915     HeapStats initialHeapSize;
1916     clearOutOldGarbage(&initialHeapSize);
1917     IntWrapper::s_destructorCalls = 0;
1918     LargeObject::s_destructorCalls = 0;
1919     {
1920         int slack = 8; // LargeObject points to an IntWrapper that is also allocated.
1921         Persistent<LargeObject> object = LargeObject::create();
1922         EXPECT_TRUE(ThreadState::current()->contains(object));
1923         EXPECT_TRUE(ThreadState::current()->contains(reinterpret_cast<char*>(object.get()) + sizeof(LargeObject) - 1));
1924 #if ENABLE(GC_PROFILE_MARKING)
1925         const GCInfo* info = ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()));
1926         EXPECT_NE(reinterpret_cast<const GCInfo*>(0), info);
1927         EXPECT_EQ(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) + sizeof(LargeObject) - 1));
1928         EXPECT_NE(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) + sizeof(LargeObject)));
1929         EXPECT_NE(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) - 1));
1930 #endif
1931         HeapStats afterAllocation;
1932         clearOutOldGarbage(&afterAllocation);
1933         {
1934             object->set(0, 'a');
1935             EXPECT_EQ('a', object->get(0));
1936             object->set(object->length() - 1, 'b');
1937             EXPECT_EQ('b', object->get(object->length() - 1));
1938             size_t expectedObjectSpace = sizeof(LargeObject) + sizeof(IntWrapper);
1939             size_t actualObjectSpace =
1940                 afterAllocation.totalObjectSpace() - initialHeapSize.totalObjectSpace();
1941             CheckWithSlack(expectedObjectSpace, actualObjectSpace, slack);
1942             // There is probably space for the IntWrapper in a heap page without
1943             // allocating extra pages. However, the IntWrapper allocation might cause
1944             // the addition of a heap page.
1945             size_t largeObjectAllocationSize =
1946                 sizeof(LargeObject) + sizeof(LargeHeapObject<FinalizedHeapObjectHeader>) + sizeof(FinalizedHeapObjectHeader);
1947             size_t allocatedSpaceLowerBound =
1948                 initialHeapSize.totalAllocatedSpace() + largeObjectAllocationSize;
1949             size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
1950             EXPECT_LE(allocatedSpaceLowerBound, afterAllocation.totalAllocatedSpace());
1951             EXPECT_LE(afterAllocation.totalAllocatedSpace(), allocatedSpaceUpperBound);
1952             EXPECT_EQ(0, IntWrapper::s_destructorCalls);
1953             EXPECT_EQ(0, LargeObject::s_destructorCalls);
1954             for (int i = 0; i < 10; i++)
1955                 object = LargeObject::create();
1956         }
1957         HeapStats oneLargeObject;
1958         clearOutOldGarbage(&oneLargeObject);
1959         EXPECT_TRUE(oneLargeObject == afterAllocation);
1960         EXPECT_EQ(10, IntWrapper::s_destructorCalls);
1961         EXPECT_EQ(10, LargeObject::s_destructorCalls);
1962     }
1963     HeapStats backToInitial;
1964     clearOutOldGarbage(&backToInitial);
1965     EXPECT_TRUE(initialHeapSize == backToInitial);
1966     EXPECT_EQ(11, IntWrapper::s_destructorCalls);
1967     EXPECT_EQ(11, LargeObject::s_destructorCalls);
1968     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
1969 }
1970
1971 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
1972 typedef std::pair<int, Member<IntWrapper> > PairUnwrappedWrapped;
1973 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper> > PairWeakStrong;
1974 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper> > PairStrongWeak;
1975 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
1976 typedef std::pair<int, WeakMember<IntWrapper> > PairUnwrappedWeak;
1977
1978 class Container : public GarbageCollected<Container> {
1979 public:
1980     static Container* create() { return new Container(); }
1981     HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > map;
1982     HeapHashSet<Member<IntWrapper> > set;
1983     HeapHashSet<Member<IntWrapper> > set2;
1984     HeapHashCountedSet<Member<IntWrapper> > set3;
1985     HeapVector<Member<IntWrapper>, 2> vector;
1986     HeapVector<PairWrappedUnwrapped, 2> vectorWU;
1987     HeapVector<PairUnwrappedWrapped, 2> vectorUW;
1988     HeapDeque<Member<IntWrapper>, 0> deque;
1989     HeapDeque<PairWrappedUnwrapped, 0> dequeWU;
1990     HeapDeque<PairUnwrappedWrapped, 0> dequeUW;
1991     void trace(Visitor* visitor)
1992     {
1993         visitor->trace(map);
1994         visitor->trace(set);
1995         visitor->trace(set2);
1996         visitor->trace(set3);
1997         visitor->trace(vector);
1998         visitor->trace(vectorWU);
1999         visitor->trace(vectorUW);
2000         visitor->trace(deque);
2001         visitor->trace(dequeWU);
2002         visitor->trace(dequeUW);
2003     }
2004 };
2005
2006 struct ShouldBeTraced {
2007     explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { }
2008     void trace(Visitor* visitor) { visitor->trace(m_wrapper); }
2009     Member<IntWrapper> m_wrapper;
2010 };
2011
2012 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> {
2013 public:
2014     static OffHeapContainer* create() { return new OffHeapContainer(); }
2015
2016     static const int iterations = 300;
2017     static const int deadWrappers = 1200;
2018
2019     OffHeapContainer()
2020     {
2021         for (int i = 0; i < iterations; i++) {
2022             m_deque1.append(ShouldBeTraced(IntWrapper::create(i)));
2023             m_vector1.append(ShouldBeTraced(IntWrapper::create(i)));
2024             m_deque2.append(IntWrapper::create(i));
2025             m_vector2.append(IntWrapper::create(i));
2026         }
2027
2028         Deque<ShouldBeTraced>::iterator d1Iterator(m_deque1.begin());
2029         Vector<ShouldBeTraced>::iterator v1Iterator(m_vector1.begin());
2030         Deque<Member<IntWrapper> >::iterator d2Iterator(m_deque2.begin());
2031         Vector<Member<IntWrapper> >::iterator v2Iterator(m_vector2.begin());
2032
2033         for (int i = 0; i < iterations; i++) {
2034             EXPECT_EQ(i, m_vector1[i].m_wrapper->value());
2035             EXPECT_EQ(i, m_vector2[i]->value());
2036             EXPECT_EQ(i, d1Iterator->m_wrapper->value());
2037             EXPECT_EQ(i, v1Iterator->m_wrapper->value());
2038             EXPECT_EQ(i, d2Iterator->get()->value());
2039             EXPECT_EQ(i, v2Iterator->get()->value());
2040             ++d1Iterator;
2041             ++v1Iterator;
2042             ++d2Iterator;
2043             ++v2Iterator;
2044         }
2045         EXPECT_EQ(d1Iterator, m_deque1.end());
2046         EXPECT_EQ(v1Iterator, m_vector1.end());
2047         EXPECT_EQ(d2Iterator, m_deque2.end());
2048         EXPECT_EQ(v2Iterator, m_vector2.end());
2049     }
2050
2051     void trace(Visitor* visitor)
2052     {
2053         visitor->trace(m_deque1);
2054         visitor->trace(m_vector1);
2055         visitor->trace(m_deque2);
2056         visitor->trace(m_vector2);
2057     }
2058
2059     Deque<ShouldBeTraced> m_deque1;
2060     Vector<ShouldBeTraced> m_vector1;
2061     Deque<Member<IntWrapper> > m_deque2;
2062     Vector<Member<IntWrapper> > m_vector2;
2063 };
2064
2065 const int OffHeapContainer::iterations;
2066 const int OffHeapContainer::deadWrappers;
2067
2068 // These class definitions test compile-time asserts with transition
2069 // types. They are therefore unused in test code and just need to
2070 // compile. This is intentional; do not delete the A and B classes below.
2071 class A : public WillBeGarbageCollectedMixin {
2072 };
2073
2074 class B : public NoBaseWillBeGarbageCollected<B>, public A {
2075     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B);
2076 public:
2077     void trace(Visitor*) { }
2078 };
2079
2080 TEST(HeapTest, HeapVectorFilledWithValue)
2081 {
2082     IntWrapper* val = IntWrapper::create(1);
2083     HeapVector<Member<IntWrapper> > vector(10, val);
2084     EXPECT_EQ(10u, vector.size());
2085     for (size_t i = 0; i < vector.size(); i++)
2086         EXPECT_EQ(val, vector[i]);
2087 }
2088
2089 TEST(HeapTest, HeapVectorWithInlineCapacity)
2090 {
2091     IntWrapper* one = IntWrapper::create(1);
2092     IntWrapper* two = IntWrapper::create(2);
2093     IntWrapper* three = IntWrapper::create(3);
2094     IntWrapper* four = IntWrapper::create(4);
2095     IntWrapper* five = IntWrapper::create(5);
2096     IntWrapper* six = IntWrapper::create(6);
2097     {
2098         HeapVector<Member<IntWrapper>, 2> vector;
2099         vector.append(one);
2100         vector.append(two);
2101         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2102         EXPECT_TRUE(vector.contains(one));
2103         EXPECT_TRUE(vector.contains(two));
2104
2105         vector.append(three);
2106         vector.append(four);
2107         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2108         EXPECT_TRUE(vector.contains(one));
2109         EXPECT_TRUE(vector.contains(two));
2110         EXPECT_TRUE(vector.contains(three));
2111         EXPECT_TRUE(vector.contains(four));
2112
2113         vector.shrink(1);
2114         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2115         EXPECT_TRUE(vector.contains(one));
2116         EXPECT_FALSE(vector.contains(two));
2117         EXPECT_FALSE(vector.contains(three));
2118         EXPECT_FALSE(vector.contains(four));
2119     }
2120     {
2121         HeapVector<Member<IntWrapper>, 2> vector1;
2122         HeapVector<Member<IntWrapper>, 2> vector2;
2123
2124         vector1.append(one);
2125         vector2.append(two);
2126         vector1.swap(vector2);
2127         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2128         EXPECT_TRUE(vector1.contains(two));
2129         EXPECT_TRUE(vector2.contains(one));
2130     }
2131     {
2132         HeapVector<Member<IntWrapper>, 2> vector1;
2133         HeapVector<Member<IntWrapper>, 2> vector2;
2134
2135         vector1.append(one);
2136         vector1.append(two);
2137         vector2.append(three);
2138         vector2.append(four);
2139         vector2.append(five);
2140         vector2.append(six);
2141         vector1.swap(vector2);
2142         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2143         EXPECT_TRUE(vector1.contains(three));
2144         EXPECT_TRUE(vector1.contains(four));
2145         EXPECT_TRUE(vector1.contains(five));
2146         EXPECT_TRUE(vector1.contains(six));
2147         EXPECT_TRUE(vector2.contains(one));
2148         EXPECT_TRUE(vector2.contains(two));
2149     }
2150 }
2151
2152 template<typename T, size_t inlineCapacity, typename U>
2153 bool dequeContains(HeapDeque<T, inlineCapacity>& deque, U u)
2154 {
2155     typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
2156     for (iterator it = deque.begin(); it != deque.end(); ++it) {
2157         if (*it == u)
2158             return true;
2159     }
2160     return false;
2161 }
2162
2163 TEST(HeapTest, HeapCollectionTypes)
2164 {
2165     HeapStats initialHeapSize;
2166     IntWrapper::s_destructorCalls = 0;
2167
2168     typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > MemberMember;
2169     typedef HeapHashMap<Member<IntWrapper>, int> MemberPrimitive;
2170     typedef HeapHashMap<int, Member<IntWrapper> > PrimitiveMember;
2171
2172     typedef HeapHashSet<Member<IntWrapper> > MemberSet;
2173     typedef HeapHashCountedSet<Member<IntWrapper> > MemberCountedSet;
2174
2175     typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
2176     typedef HeapDeque<Member<IntWrapper>, 0> MemberDeque;
2177
2178     typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
2179     typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
2180     typedef HeapDeque<PairWrappedUnwrapped, 0> DequeWU;
2181     typedef HeapDeque<PairUnwrappedWrapped, 0> DequeUW;
2182
2183     Persistent<MemberMember> memberMember = new MemberMember();
2184     Persistent<MemberMember> memberMember2 = new MemberMember();
2185     Persistent<MemberMember> memberMember3 = new MemberMember();
2186     Persistent<MemberPrimitive> memberPrimitive = new MemberPrimitive();
2187     Persistent<PrimitiveMember> primitiveMember = new PrimitiveMember();
2188     Persistent<MemberSet> set = new MemberSet();
2189     Persistent<MemberSet> set2 = new MemberSet();
2190     Persistent<MemberCountedSet> set3 = new MemberCountedSet();
2191     Persistent<MemberVector> vector = new MemberVector();
2192     Persistent<MemberVector> vector2 = new MemberVector();
2193     Persistent<VectorWU> vectorWU = new VectorWU();
2194     Persistent<VectorWU> vectorWU2 = new VectorWU();
2195     Persistent<VectorUW> vectorUW = new VectorUW();
2196     Persistent<VectorUW> vectorUW2 = new VectorUW();
2197     Persistent<MemberDeque> deque = new MemberDeque();
2198     Persistent<MemberDeque> deque2 = new MemberDeque();
2199     Persistent<DequeWU> dequeWU = new DequeWU();
2200     Persistent<DequeWU> dequeWU2 = new DequeWU();
2201     Persistent<DequeUW> dequeUW = new DequeUW();
2202     Persistent<DequeUW> dequeUW2 = new DequeUW();
2203     Persistent<Container> container = Container::create();
2204
2205     clearOutOldGarbage(&initialHeapSize);
2206     {
2207         Persistent<IntWrapper> one(IntWrapper::create(1));
2208         Persistent<IntWrapper> two(IntWrapper::create(2));
2209         Persistent<IntWrapper> oneB(IntWrapper::create(1));
2210         Persistent<IntWrapper> twoB(IntWrapper::create(2));
2211         Persistent<IntWrapper> oneC(IntWrapper::create(1));
2212         Persistent<IntWrapper> oneD(IntWrapper::create(1));
2213         Persistent<IntWrapper> oneE(IntWrapper::create(1));
2214         Persistent<IntWrapper> oneF(IntWrapper::create(1));
2215         {
2216             IntWrapper* threeB(IntWrapper::create(3));
2217             IntWrapper* threeC(IntWrapper::create(3));
2218             IntWrapper* threeD(IntWrapper::create(3));
2219             IntWrapper* threeE(IntWrapper::create(3));
2220             IntWrapper* threeF(IntWrapper::create(3));
2221             IntWrapper* three(IntWrapper::create(3));
2222             IntWrapper* fourB(IntWrapper::create(4));
2223             IntWrapper* fourC(IntWrapper::create(4));
2224             IntWrapper* fourD(IntWrapper::create(4));
2225             IntWrapper* fourE(IntWrapper::create(4));
2226             IntWrapper* fourF(IntWrapper::create(4));
2227             IntWrapper* four(IntWrapper::create(4));
2228             IntWrapper* fiveC(IntWrapper::create(5));
2229             IntWrapper* fiveD(IntWrapper::create(5));
2230             IntWrapper* fiveE(IntWrapper::create(5));
2231             IntWrapper* fiveF(IntWrapper::create(5));
2232
2233             // Member Collections.
2234             memberMember2->add(one, two);
2235             memberMember2->add(two, three);
2236             memberMember2->add(three, four);
2237             memberMember2->add(four, one);
2238             primitiveMember->add(1, two);
2239             primitiveMember->add(2, three);
2240             primitiveMember->add(3, four);
2241             primitiveMember->add(4, one);
2242             memberPrimitive->add(one, 2);
2243             memberPrimitive->add(two, 3);
2244             memberPrimitive->add(three, 4);
2245             memberPrimitive->add(four, 1);
2246             set2->add(one);
2247             set2->add(two);
2248             set2->add(three);
2249             set2->add(four);
2250             set->add(oneB);
2251             set3->add(oneB);
2252             set3->add(oneB);
2253             vector->append(oneB);
2254             deque->append(oneB);
2255             vector2->append(threeB);
2256             vector2->append(fourB);
2257             deque2->append(threeE);
2258             deque2->append(fourE);
2259             vectorWU->append(PairWrappedUnwrapped(&*oneC, 42));
2260             dequeWU->append(PairWrappedUnwrapped(&*oneE, 42));
2261             vectorWU2->append(PairWrappedUnwrapped(&*threeC, 43));
2262             vectorWU2->append(PairWrappedUnwrapped(&*fourC, 44));
2263             vectorWU2->append(PairWrappedUnwrapped(&*fiveC, 45));
2264             dequeWU2->append(PairWrappedUnwrapped(&*threeE, 43));
2265             dequeWU2->append(PairWrappedUnwrapped(&*fourE, 44));
2266             dequeWU2->append(PairWrappedUnwrapped(&*fiveE, 45));
2267             vectorUW->append(PairUnwrappedWrapped(1, &*oneD));
2268             vectorUW2->append(PairUnwrappedWrapped(103, &*threeD));
2269             vectorUW2->append(PairUnwrappedWrapped(104, &*fourD));
2270             vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD));
2271             dequeUW->append(PairUnwrappedWrapped(1, &*oneF));
2272             dequeUW2->append(PairUnwrappedWrapped(103, &*threeF));
2273             dequeUW2->append(PairUnwrappedWrapped(104, &*fourF));
2274             dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF));
2275
2276             EXPECT_TRUE(dequeContains(*deque, oneB));
2277
2278             // Collect garbage. This should change nothing since we are keeping
2279             // alive the IntWrapper objects with on-stack pointers.
2280             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
2281
2282             EXPECT_TRUE(dequeContains(*deque, oneB));
2283
2284             EXPECT_EQ(0u, memberMember->size());
2285             EXPECT_EQ(4u, memberMember2->size());
2286             EXPECT_EQ(4u, primitiveMember->size());
2287             EXPECT_EQ(4u, memberPrimitive->size());
2288             EXPECT_EQ(1u, set->size());
2289             EXPECT_EQ(4u, set2->size());
2290             EXPECT_EQ(1u, set3->size());
2291             EXPECT_EQ(1u, vector->size());
2292             EXPECT_EQ(2u, vector2->size());
2293             EXPECT_EQ(1u, vectorWU->size());
2294             EXPECT_EQ(3u, vectorWU2->size());
2295             EXPECT_EQ(1u, vectorUW->size());
2296             EXPECT_EQ(3u, vectorUW2->size());
2297             EXPECT_EQ(1u, deque->size());
2298             EXPECT_EQ(2u, deque2->size());
2299             EXPECT_EQ(1u, dequeWU->size());
2300             EXPECT_EQ(3u, dequeWU2->size());
2301             EXPECT_EQ(1u, dequeUW->size());
2302             EXPECT_EQ(3u, dequeUW2->size());
2303
2304             MemberVector& cvec = container->vector;
2305             cvec.swap(*vector.get());
2306             vector2->swap(cvec);
2307             vector->swap(cvec);
2308
2309             VectorWU& cvecWU = container->vectorWU;
2310             cvecWU.swap(*vectorWU.get());
2311             vectorWU2->swap(cvecWU);
2312             vectorWU->swap(cvecWU);
2313
2314             VectorUW& cvecUW = container->vectorUW;
2315             cvecUW.swap(*vectorUW.get());
2316             vectorUW2->swap(cvecUW);
2317             vectorUW->swap(cvecUW);
2318
2319             MemberDeque& cDeque = container->deque;
2320             cDeque.swap(*deque.get());
2321             deque2->swap(cDeque);
2322             deque->swap(cDeque);
2323
2324             DequeWU& cDequeWU = container->dequeWU;
2325             cDequeWU.swap(*dequeWU.get());
2326             dequeWU2->swap(cDequeWU);
2327             dequeWU->swap(cDequeWU);
2328
2329             DequeUW& cDequeUW = container->dequeUW;
2330             cDequeUW.swap(*dequeUW.get());
2331             dequeUW2->swap(cDequeUW);
2332             dequeUW->swap(cDequeUW);
2333
2334             // Swap set and set2 in a roundabout way.
2335             MemberSet& cset1 = container->set;
2336             MemberSet& cset2 = container->set2;
2337             set->swap(cset1);
2338             set2->swap(cset2);
2339             set->swap(cset2);
2340             cset1.swap(cset2);
2341             cset2.swap(set2);
2342
2343             MemberCountedSet& cCountedSet = container->set3;
2344             set3->swap(cCountedSet);
2345             EXPECT_EQ(0u, set3->size());
2346             set3->swap(cCountedSet);
2347
2348             // Triple swap.
2349             container->map.swap(memberMember2);
2350             MemberMember& containedMap = container->map;
2351             memberMember3->swap(containedMap);
2352             memberMember3->swap(memberMember);
2353
2354             EXPECT_TRUE(memberMember->get(one) == two);
2355             EXPECT_TRUE(memberMember->get(two) == three);
2356             EXPECT_TRUE(memberMember->get(three) == four);
2357             EXPECT_TRUE(memberMember->get(four) == one);
2358             EXPECT_TRUE(primitiveMember->get(1) == two);
2359             EXPECT_TRUE(primitiveMember->get(2) == three);
2360             EXPECT_TRUE(primitiveMember->get(3) == four);
2361             EXPECT_TRUE(primitiveMember->get(4) == one);
2362             EXPECT_EQ(1, memberPrimitive->get(four));
2363             EXPECT_EQ(2, memberPrimitive->get(one));
2364             EXPECT_EQ(3, memberPrimitive->get(two));
2365             EXPECT_EQ(4, memberPrimitive->get(three));
2366             EXPECT_TRUE(set->contains(one));
2367             EXPECT_TRUE(set->contains(two));
2368             EXPECT_TRUE(set->contains(three));
2369             EXPECT_TRUE(set->contains(four));
2370             EXPECT_TRUE(set2->contains(oneB));
2371             EXPECT_TRUE(set3->contains(oneB));
2372             EXPECT_TRUE(vector->contains(threeB));
2373             EXPECT_TRUE(vector->contains(fourB));
2374             EXPECT_TRUE(dequeContains(*deque, threeE));
2375             EXPECT_TRUE(dequeContains(*deque, fourE));
2376             EXPECT_TRUE(vector2->contains(oneB));
2377             EXPECT_FALSE(vector2->contains(threeB));
2378             EXPECT_TRUE(dequeContains(*deque2, oneB));
2379             EXPECT_FALSE(dequeContains(*deque2, threeE));
2380             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*threeC, 43)));
2381             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fourC, 44)));
2382             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fiveC, 45)));
2383             EXPECT_TRUE(vectorWU2->contains(PairWrappedUnwrapped(&*oneC, 42)));
2384             EXPECT_FALSE(vectorWU2->contains(PairWrappedUnwrapped(&*threeC, 43)));
2385             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(103, &*threeD)));
2386             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(104, &*fourD)));
2387             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(105, &*fiveD)));
2388             EXPECT_TRUE(vectorUW2->contains(PairUnwrappedWrapped(1, &*oneD)));
2389             EXPECT_FALSE(vectorUW2->contains(PairUnwrappedWrapped(103, &*threeD)));
2390             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*threeE, 43)));
2391             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fourE, 44)));
2392             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45)));
2393             EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42)));
2394             EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE, 43)));
2395             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*threeF)));
2396             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*fourF)));
2397             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*fiveF)));
2398             EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)));
2399             EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*threeF)));
2400         }
2401
2402         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2403
2404         EXPECT_EQ(4u, memberMember->size());
2405         EXPECT_EQ(0u, memberMember2->size());
2406         EXPECT_EQ(4u, primitiveMember->size());
2407         EXPECT_EQ(4u, memberPrimitive->size());
2408         EXPECT_EQ(4u, set->size());
2409         EXPECT_EQ(1u, set2->size());
2410         EXPECT_EQ(1u, set3->size());
2411         EXPECT_EQ(2u, vector->size());
2412         EXPECT_EQ(1u, vector2->size());
2413         EXPECT_EQ(3u, vectorUW->size());
2414         EXPECT_EQ(1u, vector2->size());
2415         EXPECT_EQ(2u, deque->size());
2416         EXPECT_EQ(1u, deque2->size());
2417         EXPECT_EQ(3u, dequeUW->size());
2418         EXPECT_EQ(1u, deque2->size());
2419
2420         EXPECT_TRUE(memberMember->get(one) == two);
2421         EXPECT_TRUE(primitiveMember->get(1) == two);
2422         EXPECT_TRUE(primitiveMember->get(4) == one);
2423         EXPECT_EQ(2, memberPrimitive->get(one));
2424         EXPECT_EQ(3, memberPrimitive->get(two));
2425         EXPECT_TRUE(set->contains(one));
2426         EXPECT_TRUE(set->contains(two));
2427         EXPECT_FALSE(set->contains(oneB));
2428         EXPECT_TRUE(set2->contains(oneB));
2429         EXPECT_TRUE(set3->contains(oneB));
2430         EXPECT_EQ(2u, set3->find(oneB)->value);
2431         EXPECT_EQ(3, vector->at(0)->value());
2432         EXPECT_EQ(4, vector->at(1)->value());
2433         EXPECT_EQ(3, deque->begin()->get()->value());
2434     }
2435
2436     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2437     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2438
2439     EXPECT_EQ(4u, memberMember->size());
2440     EXPECT_EQ(4u, primitiveMember->size());
2441     EXPECT_EQ(4u, memberPrimitive->size());
2442     EXPECT_EQ(4u, set->size());
2443     EXPECT_EQ(1u, set2->size());
2444     EXPECT_EQ(2u, vector->size());
2445     EXPECT_EQ(1u, vector2->size());
2446     EXPECT_EQ(3u, vectorWU->size());
2447     EXPECT_EQ(1u, vectorWU2->size());
2448     EXPECT_EQ(3u, vectorUW->size());
2449     EXPECT_EQ(1u, vectorUW2->size());
2450     EXPECT_EQ(2u, deque->size());
2451     EXPECT_EQ(1u, deque2->size());
2452     EXPECT_EQ(3u, dequeWU->size());
2453     EXPECT_EQ(1u, dequeWU2->size());
2454     EXPECT_EQ(3u, dequeUW->size());
2455     EXPECT_EQ(1u, dequeUW2->size());
2456 }
2457
2458 template<typename T>
2459 void MapIteratorCheck(T& it, const T& end, int expected)
2460 {
2461     int found = 0;
2462     while (it != end) {
2463         found++;
2464         int key = it->key->value();
2465         int value = it->value->value();
2466         EXPECT_TRUE(key >= 0 && key < 1100);
2467         EXPECT_TRUE(value >= 0 && value < 1100);
2468         ++it;
2469     }
2470     EXPECT_EQ(expected, found);
2471 }
2472
2473 template<typename T>
2474 void SetIteratorCheck(T& it, const T& end, int expected)
2475 {
2476     int found = 0;
2477     while (it != end) {
2478         found++;
2479         int value = (*it)->value();
2480         EXPECT_TRUE(value >= 0 && value < 1100);
2481         ++it;
2482     }
2483     EXPECT_EQ(expected, found);
2484 }
2485
2486 TEST(HeapTest, HeapWeakCollectionSimple)
2487 {
2488     HeapStats initialHeapStats;
2489     clearOutOldGarbage(&initialHeapStats);
2490     IntWrapper::s_destructorCalls = 0;
2491
2492     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2493
2494     typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
2495     typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
2496     typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
2497     typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
2498     typedef HeapHashCountedSet<WeakMember<IntWrapper> > WeakCountedSet;
2499
2500     Persistent<WeakStrong> weakStrong = new WeakStrong();
2501     Persistent<StrongWeak> strongWeak = new StrongWeak();
2502     Persistent<WeakWeak> weakWeak = new WeakWeak();
2503     Persistent<WeakSet> weakSet = new WeakSet();
2504     Persistent<WeakCountedSet> weakCountedSet = new WeakCountedSet();
2505
2506     Persistent<IntWrapper> two = IntWrapper::create(2);
2507
2508     keepNumbersAlive.append(IntWrapper::create(103));
2509     keepNumbersAlive.append(IntWrapper::create(10));
2510
2511     {
2512         weakStrong->add(IntWrapper::create(1), two);
2513         strongWeak->add(two, IntWrapper::create(1));
2514         weakWeak->add(two, IntWrapper::create(42));
2515         weakWeak->add(IntWrapper::create(42), two);
2516         weakSet->add(IntWrapper::create(0));
2517         weakSet->add(two);
2518         weakSet->add(keepNumbersAlive[0]);
2519         weakSet->add(keepNumbersAlive[1]);
2520         weakCountedSet->add(IntWrapper::create(0));
2521         weakCountedSet->add(two);
2522         weakCountedSet->add(two);
2523         weakCountedSet->add(two);
2524         weakCountedSet->add(keepNumbersAlive[0]);
2525         weakCountedSet->add(keepNumbersAlive[1]);
2526         EXPECT_EQ(1u, weakStrong->size());
2527         EXPECT_EQ(1u, strongWeak->size());
2528         EXPECT_EQ(2u, weakWeak->size());
2529         EXPECT_EQ(4u, weakSet->size());
2530         EXPECT_EQ(4u, weakCountedSet->size());
2531         EXPECT_EQ(3u, weakCountedSet->find(two)->value);
2532         weakCountedSet->remove(two);
2533         EXPECT_EQ(2u, weakCountedSet->find(two)->value);
2534     }
2535
2536     keepNumbersAlive[0] = nullptr;
2537
2538     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2539
2540     EXPECT_EQ(0u, weakStrong->size());
2541     EXPECT_EQ(0u, strongWeak->size());
2542     EXPECT_EQ(0u, weakWeak->size());
2543     EXPECT_EQ(2u, weakSet->size());
2544     EXPECT_EQ(2u, weakCountedSet->size());
2545 }
2546
2547 template<typename Set>
2548 void orderedSetHelper(bool strong)
2549 {
2550     HeapStats initialHeapStats;
2551     clearOutOldGarbage(&initialHeapStats);
2552     IntWrapper::s_destructorCalls = 0;
2553
2554     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2555
2556     Persistent<Set> set1 = new Set();
2557     Persistent<Set> set2 = new Set();
2558
2559     const Set& constSet = *set1.get();
2560
2561     keepNumbersAlive.append(IntWrapper::create(2));
2562     keepNumbersAlive.append(IntWrapper::create(103));
2563     keepNumbersAlive.append(IntWrapper::create(10));
2564
2565     set1->add(IntWrapper::create(0));
2566     set1->add(keepNumbersAlive[0]);
2567     set1->add(keepNumbersAlive[1]);
2568     set1->add(keepNumbersAlive[2]);
2569
2570     set2->clear();
2571     set2->add(IntWrapper::create(42));
2572     set2->clear();
2573
2574     EXPECT_EQ(4u, set1->size());
2575     typename Set::iterator it(set1->begin());
2576     typename Set::reverse_iterator reverse(set1->rbegin());
2577     typename Set::const_iterator cit(constSet.begin());
2578     typename Set::const_reverse_iterator creverse(constSet.rbegin());
2579
2580     EXPECT_EQ(0, (*it)->value());
2581     EXPECT_EQ(0, (*cit)->value());
2582     ++it;
2583     ++cit;
2584     EXPECT_EQ(2, (*it)->value());
2585     EXPECT_EQ(2, (*cit)->value());
2586     --it;
2587     --cit;
2588     EXPECT_EQ(0, (*it)->value());
2589     EXPECT_EQ(0, (*cit)->value());
2590     ++it;
2591     ++cit;
2592     ++it;
2593     ++cit;
2594     EXPECT_EQ(103, (*it)->value());
2595     EXPECT_EQ(103, (*cit)->value());
2596     ++it;
2597     ++cit;
2598     EXPECT_EQ(10, (*it)->value());
2599     EXPECT_EQ(10, (*cit)->value());
2600     ++it;
2601     ++cit;
2602
2603     EXPECT_EQ(10, (*reverse)->value());
2604     EXPECT_EQ(10, (*creverse)->value());
2605     ++reverse;
2606     ++creverse;
2607     EXPECT_EQ(103, (*reverse)->value());
2608     EXPECT_EQ(103, (*creverse)->value());
2609     --reverse;
2610     --creverse;
2611     EXPECT_EQ(10, (*reverse)->value());
2612     EXPECT_EQ(10, (*creverse)->value());
2613     ++reverse;
2614     ++creverse;
2615     ++reverse;
2616     ++creverse;
2617     EXPECT_EQ(2, (*reverse)->value());
2618     EXPECT_EQ(2, (*creverse)->value());
2619     ++reverse;
2620     ++creverse;
2621     EXPECT_EQ(0, (*reverse)->value());
2622     EXPECT_EQ(0, (*creverse)->value());
2623     ++reverse;
2624     ++creverse;
2625
2626     EXPECT_EQ(set1->end(), it);
2627     EXPECT_EQ(constSet.end(), cit);
2628     EXPECT_EQ(set1->rend(), reverse);
2629     EXPECT_EQ(constSet.rend(), creverse);
2630
2631     typename Set::iterator iX(set2->begin());
2632     EXPECT_EQ(set2->end(), iX);
2633
2634     if (strong)
2635         set1->remove(keepNumbersAlive[0]);
2636
2637     keepNumbersAlive[0] = nullptr;
2638
2639     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2640
2641     EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size());
2642
2643     EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls);
2644
2645     typename Set::iterator i2(set1->begin());
2646     if (strong) {
2647         EXPECT_EQ(0, (*i2)->value());
2648         ++i2;
2649         EXPECT_NE(set1->end(), i2);
2650     }
2651     EXPECT_EQ(103, (*i2)->value());
2652     ++i2;
2653     EXPECT_NE(set1->end(), i2);
2654     EXPECT_EQ(10, (*i2)->value());
2655     ++i2;
2656     EXPECT_EQ(set1->end(), i2);
2657 }
2658
2659 TEST(HeapTest, HeapWeakLinkedHashSet)
2660 {
2661     orderedSetHelper<HeapLinkedHashSet<Member<IntWrapper> > >(true);
2662     orderedSetHelper<HeapLinkedHashSet<WeakMember<IntWrapper> > >(false);
2663     orderedSetHelper<HeapListHashSet<Member<IntWrapper> > >(true);
2664 }
2665
2666 class ThingWithDestructor {
2667 public:
2668     ThingWithDestructor()
2669         : m_x(emptyValue)
2670     {
2671         s_liveThingsWithDestructor++;
2672     }
2673
2674     ThingWithDestructor(int x)
2675         : m_x(x)
2676     {
2677         s_liveThingsWithDestructor++;
2678     }
2679
2680     ThingWithDestructor(const ThingWithDestructor&other)
2681     {
2682         *this = other;
2683         s_liveThingsWithDestructor++;
2684     }
2685
2686     ~ThingWithDestructor()
2687     {
2688         s_liveThingsWithDestructor--;
2689     }
2690
2691     int value() { return m_x; }
2692
2693     static int s_liveThingsWithDestructor;
2694
2695     unsigned hash() { return IntHash<int>::hash(m_x); }
2696
2697 private:
2698     static const int emptyValue = 0;
2699     int m_x;
2700 };
2701
2702 int ThingWithDestructor::s_liveThingsWithDestructor;
2703
2704 struct ThingWithDestructorTraits : public HashTraits<ThingWithDestructor> {
2705     static const bool needsDestruction = true;
2706 };
2707
2708 static void heapMapDestructorHelper(bool clearMaps)
2709 {
2710     HeapStats initialHeapStats;
2711     clearOutOldGarbage(&initialHeapStats);
2712     ThingWithDestructor::s_liveThingsWithDestructor = 0;
2713
2714     typedef HeapHashMap<WeakMember<IntWrapper>, RefPtr<RefCountedAndGarbageCollected> > RefMap;
2715
2716     typedef HeapHashMap<
2717         WeakMember<IntWrapper>,
2718         ThingWithDestructor,
2719         DefaultHash<WeakMember<IntWrapper> >::Hash,
2720         HashTraits<WeakMember<IntWrapper> >,
2721         ThingWithDestructorTraits> Map;
2722
2723     Persistent<Map> map(new Map());
2724     Persistent<RefMap> refMap(new RefMap());
2725
2726     Persistent<IntWrapper> luck(IntWrapper::create(103));
2727
2728     int baseLine, refBaseLine;
2729
2730     {
2731         Map stackMap;
2732         RefMap stackRefMap;
2733
2734         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2735         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2736
2737         stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729));
2738         stackMap.add(luck, ThingWithDestructor(8128));
2739         stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
2740         stackRefMap.add(luck, RefCountedAndGarbageCollected::create());
2741
2742         baseLine = ThingWithDestructor::s_liveThingsWithDestructor;
2743         refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
2744
2745         // Although the heap maps are on-stack, we can't expect prompt
2746         // finalization of the elements, so when they go out of scope here we
2747         // will not necessarily have called the relevant destructors.
2748     }
2749
2750     // The RefCountedAndGarbageCollected things need an extra GC to discover
2751     // that they are no longer ref counted.
2752     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2753     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2754     EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
2755     EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
2756
2757     // Now use maps kept alive with persistents. Here we don't expect any
2758     // destructors to be called before there have been GCs.
2759
2760     map->add(IntWrapper::create(42), ThingWithDestructor(1729));
2761     map->add(luck, ThingWithDestructor(8128));
2762     refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
2763     refMap->add(luck, RefCountedAndGarbageCollected::create());
2764
2765     baseLine  =  ThingWithDestructor::s_liveThingsWithDestructor;
2766     refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
2767
2768     luck.clear();
2769     if (clearMaps) {
2770         map->clear(); // Clear map.
2771         refMap->clear(); // Clear map.
2772     } else {
2773         map.clear(); // Clear Persistent handle, not map.
2774         refMap.clear(); // Clear Persistent handle, not map.
2775         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2776         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2777     }
2778
2779     EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
2780
2781     // Need a GC to make sure that the RefCountedAndGarbageCollected thing
2782     // noticies it's been decremented to zero.
2783     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2784     EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
2785 }
2786
2787 TEST(HeapTest, HeapMapDestructor)
2788 {
2789     heapMapDestructorHelper(true);
2790     heapMapDestructorHelper(false);
2791 }
2792
2793 typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
2794 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
2795 typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
2796 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
2797 typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongLinkedSet;
2798 typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedLinkedSet;
2799 typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakLinkedSet;
2800 typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakLinkedSet;
2801 typedef HeapHashCountedSet<PairWeakStrong> WeakStrongCountedSet;
2802 typedef HeapHashCountedSet<PairWeakUnwrapped> WeakUnwrappedCountedSet;
2803 typedef HeapHashCountedSet<PairStrongWeak> StrongWeakCountedSet;
2804 typedef HeapHashCountedSet<PairUnwrappedWeak> UnwrappedWeakCountedSet;
2805
2806 template<typename T>
2807 T& iteratorExtractor(WTF::KeyValuePair<T, unsigned>& pair)
2808 {
2809     return pair.key;
2810 }
2811
2812 template<typename T>
2813 T& iteratorExtractor(T& notAPair)
2814 {
2815     return notAPair;
2816 }
2817
2818 template<typename WSSet, typename SWSet, typename WUSet, typename UWSet>
2819 void checkPairSets(
2820     Persistent<WSSet>& weakStrong,
2821     Persistent<SWSet>& strongWeak,
2822     Persistent<WUSet>& weakUnwrapped,
2823     Persistent<UWSet>& unwrappedWeak,
2824     bool ones,
2825     Persistent<IntWrapper>& two)
2826 {
2827     typename WSSet::iterator itWS = weakStrong->begin();
2828     typename SWSet::iterator itSW = strongWeak->begin();
2829     typename WUSet::iterator itWU = weakUnwrapped->begin();
2830     typename UWSet::iterator itUW = unwrappedWeak->begin();
2831
2832     EXPECT_EQ(2u, weakStrong->size());
2833     EXPECT_EQ(2u, strongWeak->size());
2834     EXPECT_EQ(2u, weakUnwrapped->size());
2835     EXPECT_EQ(2u, unwrappedWeak->size());
2836
2837     PairWeakStrong p = iteratorExtractor(*itWS);
2838     PairStrongWeak p2 = iteratorExtractor(*itSW);
2839     PairWeakUnwrapped p3 = iteratorExtractor(*itWU);
2840     PairUnwrappedWeak p4 = iteratorExtractor(*itUW);
2841     if (p.first == two && p.second == two)
2842         ++itWS;
2843     if (p2.first == two && p2.second == two)
2844         ++itSW;
2845     if (p3.first == two && p3.second == 2)
2846         ++itWU;
2847     if (p4.first == 2 && p4.second == two)
2848         ++itUW;
2849     p = iteratorExtractor(*itWS);
2850     p2 = iteratorExtractor(*itSW);
2851     p3 = iteratorExtractor(*itWU);
2852     p4 = iteratorExtractor(*itUW);
2853     IntWrapper* nullWrapper = 0;
2854     if (ones) {
2855         EXPECT_EQ(p.first->value(), 1);
2856         EXPECT_EQ(p2.second->value(), 1);
2857         EXPECT_EQ(p3.first->value(), 1);
2858         EXPECT_EQ(p4.second->value(), 1);
2859     } else {
2860         EXPECT_EQ(p.first, nullWrapper);
2861         EXPECT_EQ(p2.second, nullWrapper);
2862         EXPECT_EQ(p3.first, nullWrapper);
2863         EXPECT_EQ(p4.second, nullWrapper);
2864     }
2865
2866     EXPECT_EQ(p.second->value(), 2);
2867     EXPECT_EQ(p2.first->value(), 2);
2868     EXPECT_EQ(p3.second, 2);
2869     EXPECT_EQ(p4.first, 2);
2870
2871     EXPECT_TRUE(weakStrong->contains(PairWeakStrong(&*two, &*two)));
2872     EXPECT_TRUE(strongWeak->contains(PairStrongWeak(&*two, &*two)));
2873     EXPECT_TRUE(weakUnwrapped->contains(PairWeakUnwrapped(&*two, 2)));
2874     EXPECT_TRUE(unwrappedWeak->contains(PairUnwrappedWeak(2, &*two)));
2875 }
2876
2877 template<typename WSSet, typename SWSet, typename WUSet, typename UWSet>
2878 void weakPairsHelper()
2879 {
2880     IntWrapper::s_destructorCalls = 0;
2881
2882     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2883
2884     Persistent<WSSet> weakStrong = new WSSet();
2885     Persistent<SWSet> strongWeak = new SWSet();
2886     Persistent<WUSet> weakUnwrapped = new WUSet();
2887     Persistent<UWSet> unwrappedWeak = new UWSet();
2888
2889     Persistent<IntWrapper> two = IntWrapper::create(2);
2890
2891     weakStrong->add(PairWeakStrong(IntWrapper::create(1), &*two));
2892     weakStrong->add(PairWeakStrong(&*two, &*two));
2893     strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1)));
2894     strongWeak->add(PairStrongWeak(&*two, &*two));
2895     weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2));
2896     weakUnwrapped->add(PairWeakUnwrapped(&*two, 2));
2897     unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1)));
2898     unwrappedWeak->add(PairUnwrappedWeak(2, &*two));
2899
2900     checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrapped, unwrappedWeak, true, two);
2901
2902     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2903     checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrapped, unwrappedWeak, false, two);
2904 }
2905
2906 TEST(HeapTest, HeapWeakPairs)
2907 {
2908     {
2909         typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
2910         typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
2911         typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
2912         typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
2913         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
2914     }
2915
2916     {
2917         typedef HeapListHashSet<PairWeakStrong> WeakStrongSet;
2918         typedef HeapListHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
2919         typedef HeapListHashSet<PairStrongWeak> StrongWeakSet;
2920         typedef HeapListHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
2921         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
2922     }
2923
2924     {
2925         typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongSet;
2926         typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
2927         typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakSet;
2928         typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
2929         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
2930     }
2931 }
2932
2933 TEST(HeapTest, HeapWeakCollectionTypes)
2934 {
2935     HeapStats initialHeapSize;
2936     IntWrapper::s_destructorCalls = 0;
2937
2938     typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
2939     typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
2940     typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
2941     typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
2942     typedef HeapLinkedHashSet<WeakMember<IntWrapper> > WeakOrderedSet;
2943
2944     clearOutOldGarbage(&initialHeapSize);
2945
2946     const int weakStrongIndex = 0;
2947     const int strongWeakIndex = 1;
2948     const int weakWeakIndex = 2;
2949     const int numberOfMapIndices = 3;
2950     const int weakSetIndex = 3;
2951     const int weakOrderedSetIndex = 4;
2952     const int numberOfCollections = 5;
2953
2954     for (int testRun = 0; testRun < 4; testRun++) {
2955         for (int collectionNumber = 0; collectionNumber < numberOfCollections; collectionNumber++) {
2956             bool deleteAfterwards = (testRun == 1);
2957             bool addAfterwards = (testRun == 2);
2958             bool testThatIteratorsMakeStrong = (testRun == 3);
2959
2960             // The test doesn't work for strongWeak with deleting because we lost
2961             // the key from the keepNumbersAlive array, so we can't do the lookup.
2962             if (deleteAfterwards && collectionNumber == strongWeakIndex)
2963                 continue;
2964
2965             unsigned added = addAfterwards ? 100 : 0;
2966
2967             Persistent<WeakStrong> weakStrong = new WeakStrong();
2968             Persistent<StrongWeak> strongWeak = new StrongWeak();
2969             Persistent<WeakWeak> weakWeak = new WeakWeak();
2970
2971             Persistent<WeakSet> weakSet = new WeakSet();
2972             Persistent<WeakOrderedSet> weakOrderedSet = new WeakOrderedSet();
2973
2974             PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2975             for (int i = 0; i < 128; i += 2) {
2976                 IntWrapper* wrapped = IntWrapper::create(i);
2977                 IntWrapper* wrapped2 = IntWrapper::create(i + 1);
2978                 keepNumbersAlive.append(wrapped);
2979                 keepNumbersAlive.append(wrapped2);
2980                 weakStrong->add(wrapped, wrapped2);
2981                 strongWeak->add(wrapped2, wrapped);
2982                 weakWeak->add(wrapped, wrapped2);
2983                 weakSet->add(wrapped);
2984                 weakOrderedSet->add(wrapped);
2985             }
2986
2987             EXPECT_EQ(64u, weakStrong->size());
2988             EXPECT_EQ(64u, strongWeak->size());
2989             EXPECT_EQ(64u, weakWeak->size());
2990             EXPECT_EQ(64u, weakSet->size());
2991             EXPECT_EQ(64u, weakOrderedSet->size());
2992
2993             // Collect garbage. This should change nothing since we are keeping
2994             // alive the IntWrapper objects.
2995             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2996
2997             EXPECT_EQ(64u, weakStrong->size());
2998             EXPECT_EQ(64u, strongWeak->size());
2999             EXPECT_EQ(64u, weakWeak->size());
3000             EXPECT_EQ(64u, weakSet->size());
3001             EXPECT_EQ(64u, weakOrderedSet->size());
3002
3003             for (int i = 0; i < 128; i += 2) {
3004                 IntWrapper* wrapped = keepNumbersAlive[i];
3005                 IntWrapper* wrapped2 = keepNumbersAlive[i + 1];
3006                 EXPECT_EQ(wrapped2, weakStrong->get(wrapped));
3007                 EXPECT_EQ(wrapped, strongWeak->get(wrapped2));
3008                 EXPECT_EQ(wrapped2, weakWeak->get(wrapped));
3009                 EXPECT_TRUE(weakSet->contains(wrapped));
3010                 EXPECT_TRUE(weakOrderedSet->contains(wrapped));
3011             }
3012
3013             for (int i = 0; i < 128; i += 3)
3014                 keepNumbersAlive[i] = nullptr;
3015
3016             if (collectionNumber != weakStrongIndex)
3017                 weakStrong->clear();
3018             if (collectionNumber != strongWeakIndex)
3019                 strongWeak->clear();
3020             if (collectionNumber != weakWeakIndex)
3021                 weakWeak->clear();
3022             if (collectionNumber != weakSetIndex)
3023                 weakSet->clear();
3024             if (collectionNumber != weakOrderedSetIndex)
3025                 weakOrderedSet->clear();
3026
3027             if (testThatIteratorsMakeStrong) {
3028                 WeakStrong::iterator it1 = weakStrong->begin();
3029                 StrongWeak::iterator it2 = strongWeak->begin();
3030                 WeakWeak::iterator it3 = weakWeak->begin();
3031                 WeakSet::iterator it4 = weakSet->begin();
3032                 WeakOrderedSet::iterator it5 = weakOrderedSet->begin();
3033                 // Collect garbage. This should change nothing since the
3034                 // iterators make the collections strong.
3035                 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3036                 if (collectionNumber == weakStrongIndex) {
3037                     EXPECT_EQ(64u, weakStrong->size());
3038                     MapIteratorCheck(it1, weakStrong->end(), 64);
3039                 } else if (collectionNumber == strongWeakIndex) {
3040                     EXPECT_EQ(64u, strongWeak->size());
3041                     MapIteratorCheck(it2, strongWeak->end(), 64);
3042                 } else if (collectionNumber == weakWeakIndex) {
3043                     EXPECT_EQ(64u, weakWeak->size());
3044                     MapIteratorCheck(it3, weakWeak->end(), 64);
3045                 } else if (collectionNumber == weakSetIndex) {
3046                     EXPECT_EQ(64u, weakSet->size());
3047                     SetIteratorCheck(it4, weakSet->end(), 64);
3048                 } else if (collectionNumber == weakOrderedSetIndex) {
3049                     EXPECT_EQ(64u, weakOrderedSet->size());
3050                     SetIteratorCheck(it5, weakOrderedSet->end(), 64);
3051                 }
3052             } else {
3053                 // Collect garbage. This causes weak processing to remove
3054                 // things from the collections.
3055                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3056                 unsigned count = 0;
3057                 for (int i = 0; i < 128; i += 2) {
3058                     bool firstAlive = keepNumbersAlive[i];
3059                     bool secondAlive = keepNumbersAlive[i + 1];
3060                     if (firstAlive && (collectionNumber == weakStrongIndex || collectionNumber == strongWeakIndex))
3061                         secondAlive = true;
3062                     if (firstAlive && secondAlive && collectionNumber < numberOfMapIndices) {
3063                         if (collectionNumber == weakStrongIndex) {
3064                             if (deleteAfterwards)
3065                                 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAlive[i])->value());
3066                         } else if (collectionNumber == strongWeakIndex) {
3067                             if (deleteAfterwards)
3068                                 EXPECT_EQ(i, strongWeak->take(keepNumbersAlive[i + 1])->value());
3069                         } else if (collectionNumber == weakWeakIndex) {
3070                             if (deleteAfterwards)
3071                                 EXPECT_EQ(i + 1, weakWeak->take(keepNumbersAlive[i])->value());
3072                         }
3073                         if (!deleteAfterwards)
3074                             count++;
3075                     } else if (collectionNumber == weakSetIndex && firstAlive) {
3076                         ASSERT_TRUE(weakSet->contains(keepNumbersAlive[i]));
3077                         if (deleteAfterwards)
3078                             weakSet->remove(keepNumbersAlive[i]);
3079                         else
3080                             count++;
3081                     } else if (collectionNumber == weakOrderedSetIndex && firstAlive) {
3082                         ASSERT_TRUE(weakOrderedSet->contains(keepNumbersAlive[i]));
3083                         if (deleteAfterwards)
3084                             weakOrderedSet->remove(keepNumbersAlive[i]);
3085                         else
3086                             count++;
3087                     }
3088                 }
3089                 if (addAfterwards) {
3090                     for (int i = 1000; i < 1100; i++) {
3091                         IntWrapper* wrapped = IntWrapper::create(i);
3092                         keepNumbersAlive.append(wrapped);
3093                         weakStrong->add(wrapped, wrapped);
3094                         strongWeak->add(wrapped, wrapped);
3095                         weakWeak->add(wrapped, wrapped);
3096                         weakSet->add(wrapped);
3097                         weakOrderedSet->add(wrapped);
3098                     }
3099                 }
3100                 if (collectionNumber == weakStrongIndex)
3101                     EXPECT_EQ(count + added, weakStrong->size());
3102                 else if (collectionNumber == strongWeakIndex)
3103                     EXPECT_EQ(count + added, strongWeak->size());
3104                 else if (collectionNumber == weakWeakIndex)
3105                     EXPECT_EQ(count + added, weakWeak->size());
3106                 else if (collectionNumber == weakSetIndex)
3107                     EXPECT_EQ(count + added, weakSet->size());
3108                 else if (collectionNumber == weakOrderedSetIndex)
3109                     EXPECT_EQ(count + added, weakOrderedSet->size());
3110                 WeakStrong::iterator it1 = weakStrong->begin();
3111                 StrongWeak::iterator it2 = strongWeak->begin();
3112                 WeakWeak::iterator it3 = weakWeak->begin();
3113                 WeakSet::iterator it4 = weakSet->begin();
3114                 WeakOrderedSet::iterator it5 = weakOrderedSet->begin();
3115                 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == weakStrongIndex ? count : 0) + added);
3116                 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == strongWeakIndex ? count : 0) + added);
3117                 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weakWeakIndex ? count : 0) + added);
3118                 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakSetIndex ? count : 0) + added);
3119                 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber == weakOrderedSetIndex ? count : 0) + added);
3120             }
3121             for (unsigned i = 0; i < 128 + added; i++)
3122                 keepNumbersAlive[i] = nullptr;
3123             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3124             EXPECT_EQ(0u, weakStrong->size());
3125             EXPECT_EQ(0u, strongWeak->size());
3126             EXPECT_EQ(0u, weakWeak->size());
3127             EXPECT_EQ(0u, weakSet->size());
3128             EXPECT_EQ(0u, weakOrderedSet->size());
3129         }
3130     }
3131 }
3132
3133 TEST(HeapTest, RefCountedGarbageCollected)
3134 {
3135     RefCountedAndGarbageCollected::s_destructorCalls = 0;
3136     {
3137         RefPtr<RefCountedAndGarbageCollected> refPtr3;
3138         {
3139             Persistent<RefCountedAndGarbageCollected> persistent;
3140             {
3141                 RefPtr<RefCountedAndGarbageCollected> refPtr1 = RefCountedAndGarbageCollected::create();
3142                 RefPtr<RefCountedAndGarbageCollected> refPtr2 = RefCountedAndGarbageCollected::create();
3143                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3144                 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3145                 persistent = refPtr1.get();
3146             }
3147             // Reference count is zero for both objects but one of
3148             // them is kept alive by a persistent handle.
3149             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3150             EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3151             refPtr3 = persistent.get();
3152         }
3153         // The persistent handle is gone but the ref count has been
3154         // increased to 1.
3155         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3156         EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3157     }
3158     // Both persistent handle is gone and ref count is zero so the
3159     // object can be collected.
3160     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3161     EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls);
3162 }
3163
3164 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers)
3165 {
3166     RefCountedAndGarbageCollected::s_destructorCalls = 0;
3167     RefCountedAndGarbageCollected2::s_destructorCalls = 0;
3168     {
3169         RefCountedAndGarbageCollected* pointer1 = 0;
3170         RefCountedAndGarbageCollected2* pointer2 = 0;
3171         {
3172             RefPtr<RefCountedAndGarbageCollected> object1 = RefCountedAndGarbageCollected::create();
3173             RefPtr<RefCountedAndGarbageCollected2> object2 = RefCountedAndGarbageCollected2::create();
3174             pointer1 = object1.get();
3175             pointer2 = object2.get();
3176             void* objects[2] = { object1.get(), object2.get() };
3177             RefCountedGarbageCollectedVisitor visitor(2, objects);
3178             ThreadState::current()->visitPersistents(&visitor);
3179             EXPECT_TRUE(visitor.validate());
3180
3181             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3182             EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3183             EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3184         }
3185         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3186         EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3187         EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3188
3189         // At this point, the reference counts of object1 and object2 are 0.
3190         // Only pointer1 and pointer2 keep references to object1 and object2.
3191         void* objects[] = { 0 };
3192         RefCountedGarbageCollectedVisitor visitor(0, objects);
3193         ThreadState::current()->visitPersistents(&visitor);
3194         EXPECT_TRUE(visitor.validate());
3195
3196         {
3197             RefPtr<RefCountedAndGarbageCollected> object1(pointer1);
3198             RefPtr<RefCountedAndGarbageCollected2> object2(pointer2);
3199             void* objects[2] = { object1.get(), object2.get() };
3200             RefCountedGarbageCollectedVisitor visitor(2, objects);
3201             ThreadState::current()->visitPersistents(&visitor);
3202             EXPECT_TRUE(visitor.validate());
3203
3204             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3205             EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3206             EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3207         }
3208
3209         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3210         EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3211         EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3212     }
3213
3214     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3215     EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3216     EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls);
3217 }
3218
3219 TEST(HeapTest, WeakMembers)
3220 {
3221     Bar::s_live = 0;
3222     {
3223         Persistent<Bar> h1 = Bar::create();
3224         Persistent<Weak> h4;
3225         Persistent<WithWeakMember> h5;
3226         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3227         ASSERT_EQ(1u, Bar::s_live); // h1 is live.
3228         {
3229             Bar* h2 = Bar::create();
3230             Bar* h3 = Bar::create();
3231             h4 = Weak::create(h2, h3);
3232             h5 = WithWeakMember::create(h2, h3);
3233             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3234             EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive.
3235             EXPECT_TRUE(h4->strongIsThere());
3236             EXPECT_TRUE(h4->weakIsThere());
3237             EXPECT_TRUE(h5->strongIsThere());
3238             EXPECT_TRUE(h5->weakIsThere());
3239         }
3240         // h3 is collected, weak pointers from h4 and h5 don't keep it alive.
3241         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3242         EXPECT_EQ(4u, Bar::s_live);
3243         EXPECT_TRUE(h4->strongIsThere());
3244         EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer.
3245         EXPECT_TRUE(h5->strongIsThere());
3246         EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer.
3247         h1.release(); // Zero out h1.
3248         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3249         EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left.
3250         EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4.
3251         EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5.
3252     }
3253     // h4 and h5 have gone out of scope now and they were keeping h2 alive.
3254     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3255     EXPECT_EQ(0u, Bar::s_live); // All gone.
3256 }
3257
3258 TEST(HeapTest, FinalizationObserver)
3259 {
3260     Persistent<FinalizationObserver<Observable> > o;
3261     {
3262         Observable* foo = Observable::create(Bar::create());
3263         // |o| observes |foo|.
3264         o = FinalizationObserver<Observable>::create(foo);
3265     }
3266     // FinalizationObserver doesn't have a strong reference to |foo|. So |foo|
3267     // and its member will be collected.
3268     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3269     EXPECT_EQ(0u, Bar::s_live);
3270     EXPECT_TRUE(o->didCallWillFinalize());
3271
3272     FinalizationObserverWithHashMap::s_didCallWillFinalize = false;
3273     Observable* foo = Observable::create(Bar::create());
3274     FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWithHashMap::observe(*foo);
3275     EXPECT_EQ(1u, map.size());
3276     foo = 0;
3277     // FinalizationObserverWithHashMap doesn't have a strong reference to
3278     // |foo|. So |foo| and its member will be collected.
3279     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3280     EXPECT_EQ(0u, Bar::s_live);
3281     EXPECT_EQ(0u, map.size());
3282     EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize);
3283 }
3284
3285 TEST(HeapTest, Comparisons)
3286 {
3287     Persistent<Bar> barPersistent = Bar::create();
3288     Persistent<Foo> fooPersistent = Foo::create(barPersistent);
3289     EXPECT_TRUE(barPersistent != fooPersistent);
3290     barPersistent = fooPersistent;
3291     EXPECT_TRUE(barPersistent == fooPersistent);
3292 }
3293
3294 TEST(HeapTest, CheckAndMarkPointer)
3295 {
3296     HeapStats initialHeapStats;
3297     clearOutOldGarbage(&initialHeapStats);
3298
3299     Vector<Address> objectAddresses;
3300     Vector<Address> endAddresses;
3301     Address largeObjectAddress;
3302     Address largeObjectEndAddress;
3303     CountingVisitor visitor;
3304     for (int i = 0; i < 10; i++) {
3305         SimpleObject* object = SimpleObject::create();
3306         Address objectAddress = reinterpret_cast<Address>(object);
3307         objectAddresses.append(objectAddress);
3308         endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
3309     }
3310     LargeObject* largeObject = LargeObject::create();
3311     largeObjectAddress = reinterpret_cast<Address>(largeObject);
3312     largeObjectEndAddress = largeObjectAddress + sizeof(LargeObject) - 1;
3313
3314     // This is a low-level test where we call checkAndMarkPointer. This method
3315     // causes the object start bitmap to be computed which requires the heap
3316     // to be in a consistent state (e.g. the free allocation area must be put
3317     // into a free list header). However when we call makeConsistentForSweeping it
3318     // also clears out the freelists so we have to rebuild those before trying
3319     // to allocate anything again. We do this by forcing a GC after doing the
3320     // checkAndMarkPointer tests.
3321     {
3322         TestGCScope scope(ThreadState::HeapPointersOnStack);
3323         EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
3324         Heap::makeConsistentForSweeping();
3325         for (size_t i = 0; i < objectAddresses.size(); i++) {
3326             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
3327             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i]));
3328         }
3329         EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
3330         visitor.reset();
3331         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress));
3332         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress));
3333         EXPECT_EQ(2ul, visitor.count());
3334         visitor.reset();
3335     }
3336     // This forces a GC without stack scanning which results in the objects
3337     // being collected. This will also rebuild the above mentioned freelists,
3338     // however we don't rely on that below since we don't have any allocations.
3339     clearOutOldGarbage(&initialHeapStats);
3340     {
3341         TestGCScope scope(ThreadState::HeapPointersOnStack);
3342         EXPECT_TRUE(scope.allThreadsParked());
3343         Heap::makeConsistentForSweeping();
3344         for (size_t i = 0; i < objectAddresses.size(); i++) {
3345             // We would like to assert that checkAndMarkPointer returned false
3346             // here because the pointers no longer point into a valid object
3347             // (it's been freed by the GCs. But checkAndMarkPointer will return
3348             // true for any pointer that points into a heap page, regardless of
3349             // whether it points at a valid object (this ensures the
3350             // correctness of the page-based on-heap address caches), so we
3351             // can't make that assert.
3352             Heap::checkAndMarkPointer(&visitor, objectAddresses[i]);
3353             Heap::checkAndMarkPointer(&visitor, endAddresses[i]);
3354         }
3355         EXPECT_EQ(0ul, visitor.count());
3356         Heap::checkAndMarkPointer(&visitor, largeObjectAddress);
3357         Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress);
3358         EXPECT_EQ(0ul, visitor.count());
3359     }
3360     // This round of GC is important to make sure that the object start
3361     // bitmap are cleared out and that the free lists are rebuild.
3362     clearOutOldGarbage(&initialHeapStats);
3363 }
3364
3365 TEST(HeapTest, VisitOffHeapCollections)
3366 {
3367     HeapStats initialHeapStats;
3368     clearOutOldGarbage(&initialHeapStats);
3369     IntWrapper::s_destructorCalls = 0;
3370     Persistent<OffHeapContainer> container = OffHeapContainer::create();
3371     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3372     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3373     container = nullptr;
3374     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3375     EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls);
3376 }
3377
3378 TEST(HeapTest, PersistentHeapCollectionTypes)
3379 {
3380     HeapStats initialHeapSize;
3381     IntWrapper::s_destructorCalls = 0;
3382
3383     typedef HeapVector<Member<IntWrapper> > Vec;
3384     typedef PersistentHeapVector<Member<IntWrapper> > PVec;
3385     typedef PersistentHeapHashSet<Member<IntWrapper> > PSet;
3386     typedef PersistentHeapListHashSet<Member<IntWrapper> > PListSet;
3387     typedef PersistentHeapLinkedHashSet<Member<IntWrapper> > PLinkedSet;
3388     typedef PersistentHeapHashMap<Member<IntWrapper>, Member<IntWrapper> > PMap;
3389     typedef PersistentHeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakPMap;
3390     typedef PersistentHeapDeque<Member<IntWrapper> > PDeque;
3391
3392     clearOutOldGarbage(&initialHeapSize);
3393     {
3394         PVec pVec;
3395         PDeque pDeque;
3396         PSet pSet;
3397         PListSet pListSet;
3398         PLinkedSet pLinkedSet;
3399         PMap pMap;
3400         WeakPMap wpMap;
3401
3402         IntWrapper* one(IntWrapper::create(1));
3403         IntWrapper* two(IntWrapper::create(2));
3404         IntWrapper* three(IntWrapper::create(3));
3405         IntWrapper* four(IntWrapper::create(4));
3406         IntWrapper* five(IntWrapper::create(5));
3407         IntWrapper* six(IntWrapper::create(6));
3408         IntWrapper* seven(IntWrapper::create(7));
3409         IntWrapper* eight(IntWrapper::create(8));
3410         IntWrapper* nine(IntWrapper::create(9));
3411         Persistent<IntWrapper> ten(IntWrapper::create(10));
3412         IntWrapper* eleven(IntWrapper::create(11));
3413
3414         pVec.append(one);
3415         pVec.append(two);
3416
3417         pDeque.append(seven);
3418         pDeque.append(two);
3419
3420         Vec* vec = new Vec();
3421         vec->swap(pVec);
3422
3423         pVec.append(two);
3424         pVec.append(three);
3425
3426         pSet.add(four);
3427         pListSet.add(eight);
3428         pLinkedSet.add(nine);
3429         pMap.add(five, six);
3430         wpMap.add(ten, eleven);
3431
3432         // Collect |vec| and |one|.
3433         vec = 0;
3434         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3435         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
3436
3437         EXPECT_EQ(2u, pVec.size());
3438         EXPECT_EQ(two, pVec.at(0));
3439         EXPECT_EQ(three, pVec.at(1));
3440
3441         EXPECT_EQ(2u, pDeque.size());
3442         EXPECT_EQ(seven, pDeque.first());
3443         EXPECT_EQ(seven, pDeque.takeFirst());
3444         EXPECT_EQ(two, pDeque.first());
3445
3446         EXPECT_EQ(1u, pDeque.size());
3447
3448         EXPECT_EQ(1u, pSet.size());
3449         EXPECT_TRUE(pSet.contains(four));
3450
3451         EXPECT_EQ(1u, pListSet.size());
3452         EXPECT_TRUE(pListSet.contains(eight));
3453
3454         EXPECT_EQ(1u, pLinkedSet.size());
3455         EXPECT_TRUE(pLinkedSet.contains(nine));
3456
3457         EXPECT_EQ(1u, pMap.size());
3458         EXPECT_EQ(six, pMap.get(five));
3459
3460         EXPECT_EQ(1u, wpMap.size());
3461         EXPECT_EQ(eleven, wpMap.get(ten));
3462         ten.clear();
3463         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3464         EXPECT_EQ(0u, wpMap.size());
3465     }
3466
3467     // Collect previous roots.
3468     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3469     EXPECT_EQ(11, IntWrapper::s_destructorCalls);
3470 }
3471
3472 TEST(HeapTest, CollectionNesting)
3473 {
3474     HeapStats initialStats;
3475     clearOutOldGarbage(&initialStats);
3476     int* key = &IntWrapper::s_destructorCalls;
3477     IntWrapper::s_destructorCalls = 0;
3478     typedef HeapVector<Member<IntWrapper> > IntVector;
3479     typedef HeapDeque<Member<IntWrapper> > IntDeque;
3480     HeapHashMap<void*, IntVector>* map = new HeapHashMap<void*, IntVector>();
3481     HeapHashMap<void*, IntDeque>* map2 = new HeapHashMap<void*, IntDeque>();
3482
3483     map->add(key, IntVector());
3484     map2->add(key, IntDeque());
3485
3486     HeapHashMap<void*, IntVector>::iterator it = map->find(key);
3487     EXPECT_EQ(0u, map->get(key).size());
3488
3489     HeapHashMap<void*, IntDeque>::iterator it2 = map2->find(key);
3490     EXPECT_EQ(0u, map2->get(key).size());
3491
3492     it->value.append(IntWrapper::create(42));
3493     EXPECT_EQ(1u, map->get(key).size());
3494
3495     it2->value.append(IntWrapper::create(42));
3496     EXPECT_EQ(1u, map2->get(key).size());
3497
3498     Persistent<HeapHashMap<void*, IntVector> > keepAlive(map);
3499     Persistent<HeapHashMap<void*, IntDeque> > keepAlive2(map2);
3500
3501     for (int i = 0; i < 100; i++) {
3502         map->add(key + 1 + i, IntVector());
3503         map2->add(key + 1 + i, IntDeque());
3504     }
3505
3506     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3507
3508     EXPECT_EQ(1u, map->get(key).size());
3509     EXPECT_EQ(1u, map2->get(key).size());
3510     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3511
3512     keepAlive = nullptr;
3513     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3514     EXPECT_EQ(1, IntWrapper::s_destructorCalls);
3515 }
3516
3517 TEST(HeapTest, GarbageCollectedMixin)
3518 {
3519     HeapStats initialHeapStats;
3520     clearOutOldGarbage(&initialHeapStats);
3521
3522     Persistent<UseMixin> usemixin = UseMixin::create();
3523     EXPECT_EQ(0, UseMixin::s_traceCount);
3524     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3525     EXPECT_EQ(1, UseMixin::s_traceCount);
3526
3527     Persistent<Mixin> mixin = usemixin;
3528     usemixin = nullptr;
3529     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3530     EXPECT_EQ(2, UseMixin::s_traceCount);
3531
3532     PersistentHeapHashSet<WeakMember<Mixin> > weakMap;
3533     weakMap.add(UseMixin::create());
3534     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3535     EXPECT_EQ(0u, weakMap.size());
3536 }
3537
3538 TEST(HeapTest, CollectionNesting2)
3539 {
3540     HeapStats initialStats;
3541     clearOutOldGarbage(&initialStats);
3542     void* key = &IntWrapper::s_destructorCalls;
3543     IntWrapper::s_destructorCalls = 0;
3544     typedef HeapHashSet<Member<IntWrapper> > IntSet;
3545     HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>();
3546
3547     map->add(key, IntSet());
3548
3549     HeapHashMap<void*, IntSet>::iterator it = map->find(key);
3550     EXPECT_EQ(0u, map->get(key).size());
3551
3552     it->value.add(IntWrapper::create(42));
3553     EXPECT_EQ(1u, map->get(key).size());
3554
3555     Persistent<HeapHashMap<void*, IntSet> > keepAlive(map);
3556     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3557     EXPECT_EQ(1u, map->get(key).size());
3558     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3559 }
3560
3561 TEST(HeapTest, CollectionNesting3)
3562 {
3563     HeapStats initialStats;
3564     clearOutOldGarbage(&initialStats);
3565     IntWrapper::s_destructorCalls = 0;
3566     typedef HeapVector<Member<IntWrapper> > IntVector;
3567     typedef HeapDeque<Member<IntWrapper> > IntDeque;
3568     HeapVector<IntVector>* vector = new HeapVector<IntVector>();
3569     HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>();
3570
3571     vector->append(IntVector());
3572     deque->append(IntDeque());
3573
3574     HeapVector<IntVector>::iterator it = vector->begin();
3575     HeapDeque<IntDeque>::iterator it2 = deque->begin();
3576     EXPECT_EQ(0u, it->size());
3577     EXPECT_EQ(0u, it2->size());
3578
3579     it->append(IntWrapper::create(42));
3580     it2->append(IntWrapper::create(42));
3581     EXPECT_EQ(1u, it->size());
3582     EXPECT_EQ(1u, it2->size());
3583
3584     Persistent<HeapVector<IntVector> > keepAlive(vector);
3585     Persistent<HeapDeque<IntDeque> > keepAlive2(deque);
3586     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3587     EXPECT_EQ(1u, it->size());
3588     EXPECT_EQ(1u, it2->size());
3589     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3590 }
3591
3592 TEST(HeapTest, EmbeddedInVector)
3593 {
3594     HeapStats initialStats;
3595     clearOutOldGarbage(&initialStats);
3596     SimpleFinalizedObject::s_destructorCalls = 0;
3597     {
3598         PersistentHeapVector<VectorObject, 2> inlineVector;
3599         PersistentHeapVector<VectorObject> outlineVector;
3600         VectorObject i1, i2;
3601         inlineVector.append(i1);
3602         inlineVector.append(i2);
3603
3604         VectorObject o1, o2;
3605         outlineVector.append(o1);
3606         outlineVector.append(o2);
3607
3608         PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace;
3609         VectorObjectInheritedTrace it1, it2;
3610         vectorInheritedTrace.append(it1);
3611         vectorInheritedTrace.append(it2);
3612
3613         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3614         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
3615
3616         // Since VectorObjectNoTrace has no trace method it will
3617         // not be traced and hence be collected when doing GC.
3618         // We trace items in a collection braced on the item's
3619         // having a trace method. This is determined via the
3620         // NeedsTracing trait in wtf/TypeTraits.h.
3621         PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace;
3622         VectorObjectNoTrace n1, n2;
3623         vectorNoTrace.append(n1);
3624         vectorNoTrace.append(n2);
3625         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3626         EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
3627     }
3628     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3629     EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
3630 }
3631
3632 TEST(HeapTest, EmbeddedInDeque)
3633 {
3634     HeapStats initialStats;
3635     clearOutOldGarbage(&initialStats);
3636     SimpleFinalizedObject::s_destructorCalls = 0;
3637     {
3638         PersistentHeapDeque<VectorObject, 2> inlineDeque;
3639         PersistentHeapDeque<VectorObject> outlineDeque;
3640         VectorObject i1, i2;
3641         inlineDeque.append(i1);
3642         inlineDeque.append(i2);
3643
3644         VectorObject o1, o2;
3645         outlineDeque.append(o1);
3646         outlineDeque.append(o2);
3647
3648         PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace;
3649         VectorObjectInheritedTrace it1, it2;
3650         dequeInheritedTrace.append(it1);
3651         dequeInheritedTrace.append(it2);
3652
3653         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3654         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
3655
3656         // Since VectorObjectNoTrace has no trace method it will
3657         // not be traced and hence be collected when doing GC.
3658         // We trace items in a collection braced on the item's
3659         // having a trace method. This is determined via the
3660         // NeedsTracing trait in wtf/TypeTraits.h.
3661         PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace;
3662         VectorObjectNoTrace n1, n2;
3663         dequeNoTrace.append(n1);
3664         dequeNoTrace.append(n2);
3665         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3666         EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
3667     }
3668     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3669     EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
3670 }
3671
3672 template<typename Set>
3673 void rawPtrInHashHelper()
3674 {
3675     Set set;
3676     set.add(new int(42));
3677     set.add(new int(42));
3678     EXPECT_EQ(2u, set.size());
3679     for (typename Set::iterator it = set.begin(); it != set.end(); ++it) {
3680         EXPECT_EQ(42, **it);
3681         delete *it;
3682     }
3683 }
3684
3685 TEST(HeapTest, RawPtrInHash)
3686 {
3687     rawPtrInHashHelper<HashSet<RawPtr<int> > >();
3688     rawPtrInHashHelper<ListHashSet<RawPtr<int> > >();
3689     rawPtrInHashHelper<LinkedHashSet<RawPtr<int> > >();
3690 }
3691
3692 TEST(HeapTest, HeapTerminatedArray)
3693 {
3694     HeapStats initialHeapSize;
3695     clearOutOldGarbage(&initialHeapSize);
3696     IntWrapper::s_destructorCalls = 0;
3697
3698     HeapTerminatedArray<TerminatedArrayItem>* arr = 0;
3699
3700     const size_t prefixSize = 4;
3701     const size_t suffixSize = 4;
3702
3703     {
3704         HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
3705         builder.grow(prefixSize);
3706         for (size_t i = 0; i < prefixSize; i++)
3707             builder.append(TerminatedArrayItem(IntWrapper::create(i)));
3708         arr = builder.release();
3709     }
3710
3711     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3712     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3713     EXPECT_EQ(prefixSize, arr->size());
3714     for (size_t i = 0; i < prefixSize; i++)
3715         EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
3716
3717     {
3718         HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
3719         builder.grow(suffixSize);
3720         for (size_t i = 0; i < suffixSize; i++)
3721             builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i)));
3722         arr = builder.release();
3723     }
3724
3725     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3726     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3727     EXPECT_EQ(prefixSize + suffixSize, arr->size());
3728     for (size_t i = 0; i < prefixSize + suffixSize; i++)
3729         EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
3730
3731     {
3732         Persistent<HeapTerminatedArray<TerminatedArrayItem> > persistentArr = arr;
3733         arr = 0;
3734         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3735         arr = persistentArr.get();
3736         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3737         EXPECT_EQ(prefixSize + suffixSize, arr->size());
3738         for (size_t i = 0; i < prefixSize + suffixSize; i++)
3739             EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
3740     }
3741
3742     arr = 0;
3743     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3744     EXPECT_EQ(8, IntWrapper::s_destructorCalls);
3745 }
3746
3747 TEST(HeapTest, HeapLinkedStack)
3748 {
3749     HeapStats initialHeapSize;
3750     clearOutOldGarbage(&initialHeapSize);
3751     IntWrapper::s_destructorCalls = 0;
3752
3753     HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<TerminatedArrayItem>();
3754
3755     const size_t stackSize = 10;
3756
3757     for (size_t i = 0; i < stackSize; i++)
3758         stack->push(TerminatedArrayItem(IntWrapper::create(i)));
3759
3760     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3761     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3762     EXPECT_EQ(stackSize, stack->size());
3763     while (!stack->isEmpty()) {
3764         EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()->value()));
3765         stack->pop();
3766     }
3767
3768     Persistent<HeapLinkedStack<TerminatedArrayItem> > pStack = stack;
3769
3770     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3771     EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls));
3772     EXPECT_EQ(0u, pStack->size());
3773 }
3774
3775 TEST(HeapTest, AllocationDuringFinalization)
3776 {
3777     HeapStats initialHeapSize;
3778     clearOutOldGarbage(&initialHeapSize);
3779     IntWrapper::s_destructorCalls = 0;
3780     OneKiloByteObject::s_destructorCalls = 0;
3781
3782     Persistent<IntWrapper> wrapper;
3783     new FinalizationAllocator(&wrapper);
3784
3785     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3786     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3787     // Check that the wrapper allocated during finalization is not
3788     // swept away and zapped later in the same sweeping phase.
3789     EXPECT_EQ(42, wrapper->value());
3790
3791     wrapper.clear();
3792     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3793     EXPECT_EQ(10, IntWrapper::s_destructorCalls);
3794     EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls);
3795 }
3796
3797 class SimpleClassWithDestructor {
3798 public:
3799     SimpleClassWithDestructor() { }
3800     ~SimpleClassWithDestructor()
3801     {
3802         s_wasDestructed = true;
3803     }
3804     static bool s_wasDestructed;
3805 };
3806
3807 bool SimpleClassWithDestructor::s_wasDestructed;
3808
3809 class RefCountedWithDestructor : public RefCounted<RefCountedWithDestructor> {
3810 public:
3811     RefCountedWithDestructor() { }
3812     ~RefCountedWithDestructor()
3813     {
3814         s_wasDestructed = true;
3815     }
3816     static bool s_wasDestructed;
3817 };
3818
3819 bool RefCountedWithDestructor::s_wasDestructed;
3820
3821 template<typename Set>
3822 void destructorsCalledOnGC(bool addLots)
3823 {
3824     RefCountedWithDestructor::s_wasDestructed = false;
3825     {
3826         Set set;
3827         RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor();
3828         set.add(adoptRef(hasDestructor));
3829         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3830
3831         if (addLots) {
3832             for (int i = 0; i < 1000; i++) {
3833                 set.add(adoptRef(new RefCountedWithDestructor()));
3834             }
3835         }
3836
3837         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3838         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
3839         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3840     }
3841     // The destructors of the sets don't call the destructors of the elements
3842     // in the heap sets. You have to actually remove the elments, call clear()
3843     // or have a GC to get the destructors called.
3844     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3845     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3846     EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed);
3847 }
3848
3849 template<typename Set>
3850 void destructorsCalledOnClear(bool addLots)
3851 {
3852     RefCountedWithDestructor::s_wasDestructed = false;
3853     Set set;
3854     RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor();
3855     set.add(adoptRef(hasDestructor));
3856     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3857
3858     if (addLots) {
3859         for (int i = 0; i < 1000; i++) {
3860             set.add(adoptRef(new RefCountedWithDestructor()));
3861         }
3862     }
3863
3864     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
3865     set.clear();
3866     EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed);
3867 }
3868
3869 TEST(HeapTest, DestructorsCalled)
3870 {
3871     HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map;
3872     SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor();
3873     map.add(hasDestructor, adoptPtr(hasDestructor));
3874     SimpleClassWithDestructor::s_wasDestructed = false;
3875     map.clear();
3876     EXPECT_TRUE(SimpleClassWithDestructor::s_wasDestructed);
3877
3878     destructorsCalledOnClear<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3879     destructorsCalledOnClear<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3880     destructorsCalledOnClear<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3881     destructorsCalledOnClear<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3882     destructorsCalledOnClear<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3883     destructorsCalledOnClear<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3884
3885     destructorsCalledOnGC<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3886     destructorsCalledOnGC<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3887     destructorsCalledOnGC<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(false);
3888     destructorsCalledOnGC<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3889     destructorsCalledOnGC<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3890     destructorsCalledOnGC<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(true);
3891 }
3892
3893 class MixinA : public GarbageCollectedMixin {
3894 public:
3895     MixinA() : m_obj(IntWrapper::create(100)) { }
3896     virtual void trace(Visitor* visitor)
3897     {
3898         visitor->trace(m_obj);
3899     }
3900     Member<IntWrapper> m_obj;
3901 };
3902
3903 class MixinB : public GarbageCollectedMixin {
3904 public:
3905     MixinB() : m_obj(IntWrapper::create(101)) { }
3906     virtual void trace(Visitor* visitor)
3907     {
3908         visitor->trace(m_obj);
3909     }
3910     Member<IntWrapper> m_obj;
3911 };
3912
3913 class MultipleMixins : public GarbageCollected<MultipleMixins>, public MixinA, public MixinB {
3914     USING_GARBAGE_COLLECTED_MIXIN(MultipleMixins);
3915 public:
3916     MultipleMixins() : m_obj(IntWrapper::create(102)) { }
3917     virtual void trace(Visitor* visitor)
3918     {
3919         visitor->trace(m_obj);
3920         MixinA::trace(visitor);
3921         MixinB::trace(visitor);
3922     }
3923     Member<IntWrapper> m_obj;
3924 };
3925
3926 static const bool s_isMixinTrue = IsGarbageCollectedMixin<MultipleMixins>::value;
3927 static const bool s_isMixinFalse = IsGarbageCollectedMixin<IntWrapper>::value;
3928
3929 TEST(HeapTest, MultipleMixins)
3930 {
3931     EXPECT_TRUE(s_isMixinTrue);
3932     EXPECT_FALSE(s_isMixinFalse);
3933
3934     HeapStats initialHeapSize;
3935     clearOutOldGarbage(&initialHeapSize);
3936     IntWrapper::s_destructorCalls = 0;
3937     MultipleMixins* obj = new MultipleMixins();
3938     {
3939         Persistent<MixinA> a = obj;
3940         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3941         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3942     }
3943     {
3944         Persistent<MixinB> b = obj;
3945         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3946         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3947     }
3948     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3949     EXPECT_EQ(3, IntWrapper::s_destructorCalls);
3950 }
3951
3952 class GCParkingThreadTester {
3953 public:
3954     static void test()
3955     {
3956         OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createThread("SleepingThread"));
3957         sleepingThread->postTask(new Task(WTF::bind(sleeperMainFunc)));
3958
3959         // Wait for the sleeper to run.
3960         while (!s_sleeperRunning) {
3961             Platform::current()->yieldCurrentThread();
3962         }
3963
3964         {
3965             // Expect the first attempt to park the sleeping thread to fail
3966             TestGCScope scope(ThreadState::NoHeapPointersOnStack);
3967             EXPECT_FALSE(scope.allThreadsParked());
3968         }
3969
3970         s_sleeperDone = true;
3971
3972         // Wait for the sleeper to finish.
3973         while (s_sleeperRunning) {
3974             // We enter the safepoint here since the sleeper thread will detach
3975             // causing it to GC.
3976             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
3977             Platform::current()->yieldCurrentThread();
3978         }
3979
3980         {
3981             // Since the sleeper thread has detached this is the only thread.
3982             TestGCScope scope(ThreadState::NoHeapPointersOnStack);
3983             EXPECT_TRUE(scope.allThreadsParked());
3984         }
3985     }
3986
3987 private:
3988     static void sleeperMainFunc()
3989     {
3990         ThreadState::attach();
3991         s_sleeperRunning = true;
3992
3993         // Simulate a long running op that is not entering a safepoint.
3994         while (!s_sleeperDone) {
3995             Platform::current()->yieldCurrentThread();
3996         }
3997
3998         ThreadState::detach();
3999         s_sleeperRunning = false;
4000     }
4001
4002     static volatile bool s_sleeperRunning;
4003     static volatile bool s_sleeperDone;
4004 };
4005
4006 volatile bool GCParkingThreadTester::s_sleeperRunning = false;
4007 volatile bool GCParkingThreadTester::s_sleeperDone = false;
4008
4009 TEST(HeapTest, GCParkingTimeout)
4010 {
4011     GCParkingThreadTester::test();
4012 }
4013
4014 TEST(HeapTest, NeedsAdjustAndMark)
4015 {
4016     // class Mixin : public GarbageCollectedMixin {};
4017     EXPECT_TRUE(NeedsAdjustAndMark<Mixin>::value);
4018     EXPECT_TRUE(NeedsAdjustAndMark<const Mixin>::value);
4019
4020     // class SimpleObject : public GarbageCollected<SimpleObject> {};
4021     EXPECT_FALSE(NeedsAdjustAndMark<SimpleObject>::value);
4022     EXPECT_FALSE(NeedsAdjustAndMark<const SimpleObject>::value);
4023
4024     // class UseMixin : public SimpleObject, public Mixin {};
4025     EXPECT_FALSE(NeedsAdjustAndMark<UseMixin>::value);
4026     EXPECT_FALSE(NeedsAdjustAndMark<const UseMixin>::value);
4027 }
4028
4029 template<typename Set>
4030 void setWithCustomWeaknessHandling()
4031 {
4032     typedef typename Set::iterator Iterator;
4033     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
4034     Persistent<Set> set1(new Set());
4035     {
4036         Set set2;
4037         Set* set3 = new Set();
4038         set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)));
4039         set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)));
4040         set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)));
4041         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4042         // The first set is pointed to from a persistent, so it's referenced, but
4043         // the weak processing may have taken place.
4044         if (set1->size()) {
4045             Iterator i1 = set1->begin();
4046             EXPECT_EQ(4, i1->first->value());
4047             EXPECT_EQ(5, i1->second->value());
4048         }
4049         // The second set is on-stack, so its backing store must be referenced from
4050         // the stack. That makes the weak references strong.
4051         Iterator i2 = set2.begin();
4052         EXPECT_EQ(0, i2->first->value());
4053         EXPECT_EQ(1, i2->second->value());
4054         // The third set is pointed to from the stack, so it's referenced, but the
4055         // weak processing may have taken place.
4056         if (set3->size()) {
4057             Iterator i3 = set3->begin();
4058             EXPECT_EQ(2, i3->first->value());
4059             EXPECT_EQ(3, i3->second->value());
4060         }
4061     }
4062     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4063     EXPECT_EQ(0u, set1->size());
4064     set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt));
4065     set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This one gets zapped at GC time because nothing holds the 103 alive.
4066     set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103))); // This one gets zapped too.
4067     set1->add(PairWithWeakHandling(livingInt, livingInt));
4068     set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identical to the previous and doesn't add anything.
4069     EXPECT_EQ(4u, set1->size());
4070     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4071     EXPECT_EQ(2u, set1->size());
4072     Iterator i1 = set1->begin();
4073     EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt);
4074     EXPECT_EQ(livingInt, i1->second);
4075     ++i1;
4076     EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt);
4077     EXPECT_EQ(livingInt, i1->second);
4078 }
4079
4080 TEST(HeapTest, SetWithCustomWeaknessHandling)
4081 {
4082     setWithCustomWeaknessHandling<HeapHashSet<PairWithWeakHandling> >();
4083     setWithCustomWeaknessHandling<HeapLinkedHashSet<PairWithWeakHandling> >();
4084 }
4085
4086 TEST(HeapTest, MapWithCustomWeaknessHandling)
4087 {
4088     typedef HeapHashMap<PairWithWeakHandling, RefPtr<OffHeapInt> > Map;
4089     typedef Map::iterator Iterator;
4090     HeapStats initialHeapSize;
4091     clearOutOldGarbage(&initialHeapSize);
4092     OffHeapInt::s_destructorCalls = 0;
4093
4094     Persistent<Map> map1(new Map());
4095     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
4096     {
4097         Map map2;
4098         Map* map3 = new Map();
4099         map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)), OffHeapInt::create(1001));
4100         map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)), OffHeapInt::create(1002));
4101         map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)), OffHeapInt::create(1003));
4102         EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
4103
4104         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4105         // The first map2 is pointed to from a persistent, so it's referenced, but
4106         // the weak processing may have taken place.
4107         if (map1->size()) {
4108             Iterator i1 = map1->begin();
4109             EXPECT_EQ(4, i1->key.first->value());
4110             EXPECT_EQ(5, i1->key.second->value());
4111             EXPECT_EQ(1003, i1->value->value());
4112         }
4113         // The second map2 is on-stack, so its backing store must be referenced from
4114         // the stack. That makes the weak references strong.
4115         Iterator i2 = map2.begin();
4116         EXPECT_EQ(0, i2->key.first->value());
4117         EXPECT_EQ(1, i2->key.second->value());
4118         EXPECT_EQ(1001, i2->value->value());
4119         // The third map2 is pointed to from the stack, so it's referenced, but the
4120         // weak processing may have taken place.
4121         if (map3->size()) {
4122             Iterator i3 = map3->begin();
4123             EXPECT_EQ(2, i3->key.first->value());
4124             EXPECT_EQ(3, i3->key.second->value());
4125             EXPECT_EQ(1002, i3->value->value());
4126         }
4127     }
4128     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4129
4130     EXPECT_EQ(0u, map1->size());
4131     EXPECT_EQ(3, OffHeapInt::s_destructorCalls);
4132
4133     OffHeapInt::s_destructorCalls = 0;
4134
4135     map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapInt::create(2000));
4136     map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapInt::create(2001)); // This one gets zapped at GC time because nothing holds the 103 alive.
4137     map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103)), OffHeapInt::create(2002)); // This one gets zapped too.
4138     RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003));
4139     map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt);
4140     map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one is identical to the previous and doesn't add anything.
4141     dupeInt.clear();
4142
4143     EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
4144     EXPECT_EQ(4u, map1->size());
4145     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4146     EXPECT_EQ(2, OffHeapInt::s_destructorCalls);
4147     EXPECT_EQ(2u, map1->size());
4148     Iterator i1 = map1->begin();
4149     EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt);
4150     EXPECT_EQ(livingInt, i1->key.second);
4151     ++i1;
4152     EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt);
4153     EXPECT_EQ(livingInt, i1->key.second);
4154 }
4155
4156 TEST(HeapTest, MapWithCustomWeaknessHandling2)
4157 {
4158     typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map;
4159     typedef Map::iterator Iterator;
4160     HeapStats initialHeapSize;
4161     clearOutOldGarbage(&initialHeapSize);
4162     OffHeapInt::s_destructorCalls = 0;
4163
4164     Persistent<Map> map1(new Map());
4165     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
4166
4167     {
4168         Map map2;
4169         Map* map3 = new Map();
4170         map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)));
4171         map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)));
4172         map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)));
4173         EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
4174
4175         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4176         // The first map2 is pointed to from a persistent, so it's referenced, but
4177         // the weak processing may have taken place.
4178         if (map1->size()) {
4179             Iterator i1 = map1->begin();
4180             EXPECT_EQ(4, i1->value.first->value());
4181             EXPECT_EQ(5, i1->value.second->value());
4182             EXPECT_EQ(1003, i1->key->value());
4183         }
4184         // The second map2 is on-stack, so its backing store must be referenced from
4185         // the stack. That makes the weak references strong.
4186         Iterator i2 = map2.begin();
4187         EXPECT_EQ(0, i2->value.first->value());
4188         EXPECT_EQ(1, i2->value.second->value());
4189         EXPECT_EQ(1001, i2->key->value());
4190         // The third map2 is pointed to from the stack, so it's referenced, but the
4191         // weak processing may have taken place.
4192         if (map3->size()) {
4193             Iterator i3 = map3->begin();
4194             EXPECT_EQ(2, i3->value.first->value());
4195             EXPECT_EQ(3, i3->value.second->value());
4196             EXPECT_EQ(1002, i3->key->value());
4197         }
4198     }
4199     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4200
4201     EXPECT_EQ(0u, map1->size());
4202     EXPECT_EQ(3, OffHeapInt::s_destructorCalls);
4203
4204     OffHeapInt::s_destructorCalls = 0;
4205
4206     map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(103), livingInt));
4207     map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This one gets zapped at GC time because nothing holds the 103 alive.
4208     map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103))); // This one gets zapped too.
4209     RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003));
4210     map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt));
4211     map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one is identical to the previous and doesn't add anything.
4212     dupeInt.clear();
4213
4214     EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
4215     EXPECT_EQ(4u, map1->size());
4216     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4217     EXPECT_EQ(2, OffHeapInt::s_destructorCalls);
4218     EXPECT_EQ(2u, map1->size());
4219     Iterator i1 = map1->begin();
4220     EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt);
4221     EXPECT_EQ(livingInt, i1->value.second);
4222     ++i1;
4223     EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt);
4224     EXPECT_EQ(livingInt, i1->value.second);
4225 }
4226
4227 static void addElementsToWeakMap(HeapHashMap<int, WeakMember<IntWrapper> >* map)
4228 {
4229     // Key cannot be zero in hashmap.
4230     for (int i = 1; i < 11; i++)
4231         map->add(i, IntWrapper::create(i));
4232 }
4233
4234 // crbug.com/402426
4235 // If it doesn't assert a concurrent modification to the map, then it's passing.
4236 TEST(HeapTest, RegressNullIsStrongified)
4237 {
4238     Persistent<HeapHashMap<int, WeakMember<IntWrapper> > > map = new HeapHashMap<int, WeakMember<IntWrapper> >();
4239     addElementsToWeakMap(map);
4240     HeapHashMap<int, WeakMember<IntWrapper> >::AddResult result = map->add(800, nullptr);
4241     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4242     result.storedValue->value = IntWrapper::create(42);
4243 }
4244
4245 TEST(HeapTest, Bind)
4246 {
4247     Closure closure = bind(&Bar::trace, Bar::create(), static_cast<Visitor*>(0));
4248     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4249     // The closure should have a persistent handle to the Bar.
4250     EXPECT_EQ(1u, Bar::s_live);
4251
4252     Closure closure2 = bind(&Bar::trace, RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0));
4253     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4254     // The closure should have a persistent handle to the Bar.
4255     EXPECT_EQ(2u, Bar::s_live);
4256     // RawPtr<OffHeapInt> should not make Persistent.
4257     Closure closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt>(OffHeapInt::create(1).get()));
4258
4259     UseMixin::s_traceCount = 0;
4260     Mixin* mixin = UseMixin::create();
4261     Closure mixinClosure = bind(&Mixin::trace, mixin, static_cast<Visitor*>(0));
4262     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4263     // The closure should have a persistent handle to the mixin.
4264     EXPECT_EQ(1, UseMixin::s_traceCount);
4265 }
4266
4267 typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
4268
4269 // These special traits will remove a set from a map when the set is empty.
4270 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> {
4271     static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCollections;
4272     static bool traceInCollection(Visitor* visitor, WeakSet& set, WTF::ShouldWeakPointersBeMarkedStrongly strongify)
4273     {
4274         bool liveEntriesFound = false;
4275         WeakSet::iterator end = set.end();
4276         for (WeakSet::iterator it = set.begin(); it != end; ++it) {
4277             if (visitor->isAlive(*it)) {
4278                 liveEntriesFound = true;
4279                 break;
4280             }
4281         }
4282         // If there are live entries in the set then the set cannot be removed
4283         // from the map it is contained in, and we need to mark it (and its
4284         // backing) live. We just trace normally, which will invoke the normal
4285         // weak handling for any entries that are not live.
4286         if (liveEntriesFound)
4287             set.trace(visitor);
4288         return !liveEntriesFound;
4289     }
4290 };
4291
4292 // This is an example to show how you can remove entries from a T->WeakSet map
4293 // when the weak sets become empty. For this example we are using a type that
4294 // is given to use (HeapHashSet) rather than a type of our own. This means:
4295 // 1) We can't just override the HashTrait for the type since this would affect
4296 //    all collections that use this kind of weak set. Instead we have our own
4297 //    traits and use a map with custom traits for the value type. These traits
4298 //    are the 5th template parameter, so we have to supply default values for
4299 //    the 3rd and 4th template parameters
4300 // 2) We can't just inherit from WeakHandlingHashTraits, since that trait
4301 //    assumes we can add methods to the type, but we can't add methods to
4302 //    HeapHashSet.
4303 TEST(HeapTest, RemoveEmptySets)
4304 {
4305     HeapStats initialHeapSize;
4306     clearOutOldGarbage(&initialHeapSize);
4307     OffHeapInt::s_destructorCalls = 0;
4308
4309     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
4310
4311     typedef RefPtr<OffHeapInt> Key;
4312     typedef HeapHashMap<Key, WeakSet, WTF::DefaultHash<Key>::Hash, HashTraits<Key>, EmptyClearingHashSetTraits> Map;
4313     Persistent<Map> map(new Map());
4314     map->add(OffHeapInt::create(1), WeakSet());
4315     {
4316         WeakSet& set = map->begin()->value;
4317         set.add(IntWrapper::create(103)); // Weak set can't hold this long.
4318         set.add(livingInt); // This prevents the set from being emptied.
4319         EXPECT_EQ(2u, set.size());
4320     }
4321
4322     // The set we add here is empty, so the entry will be removed from the map
4323     // at the next GC.
4324     map->add(OffHeapInt::create(2), WeakSet());
4325     EXPECT_EQ(2u, map->size());
4326
4327     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4328     EXPECT_EQ(1u, map->size()); // The one with key 2 was removed.
4329     EXPECT_EQ(1, OffHeapInt::s_destructorCalls);
4330     {
4331         WeakSet& set = map->begin()->value;
4332         EXPECT_EQ(1u, set.size());
4333     }
4334
4335     livingInt.clear(); // The weak set can no longer keep the '42' alive now.
4336     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4337     EXPECT_EQ(0u, map->size());
4338 }
4339
4340 TEST(HeapTest, EphemeronsInEphemerons)
4341 {
4342     typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > InnerMap;
4343     typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap;
4344
4345     for (int keepOuterAlive = 0; keepOuterAlive <= 1; keepOuterAlive++) {
4346         for (int keepInnerAlive = 0; keepInnerAlive <=1; keepInnerAlive++) {
4347             Persistent<OuterMap> outer = new OuterMap();
4348             Persistent<IntWrapper> one = IntWrapper::create(1);
4349             Persistent<IntWrapper> two = IntWrapper::create(2);
4350             outer->add(one, InnerMap());
4351             outer->begin()->value.add(two, IntWrapper::create(3));
4352             EXPECT_EQ(1u, outer->get(one).size());
4353             if (!keepOuterAlive)
4354                 one.clear();
4355             if (!keepInnerAlive)
4356                 two.clear();
4357             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4358             if (keepOuterAlive) {
4359                 const InnerMap& inner = outer->get(one);
4360                 if (keepInnerAlive) {
4361                     EXPECT_EQ(1u, inner.size());
4362                     IntWrapper* three = inner.get(two);
4363                     EXPECT_EQ(3, three->value());
4364                 } else {
4365                     EXPECT_EQ(0u, inner.size());
4366                 }
4367             } else {
4368                 EXPECT_EQ(0u, outer->size());
4369             }
4370             outer->clear();
4371             Persistent<IntWrapper> deep = IntWrapper::create(42);
4372             Persistent<IntWrapper> home = IntWrapper::create(103);
4373             Persistent<IntWrapper> composite = IntWrapper::create(91);
4374             Persistent<HeapVector<Member<IntWrapper> > > keepAlive = new HeapVector<Member<IntWrapper> >();
4375             for (int i = 0; i < 10000; i++) {
4376                 IntWrapper* value = IntWrapper::create(i);
4377                 keepAlive->append(value);
4378                 OuterMap::AddResult newEntry = outer->add(value, InnerMap());
4379                 newEntry.storedValue->value.add(deep, home);
4380                 newEntry.storedValue->value.add(composite, home);
4381             }
4382             composite.clear();
4383             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4384             EXPECT_EQ(10000u, outer->size());
4385             for (int i = 0; i < 10000; i++) {
4386                 IntWrapper* value = keepAlive->at(i);
4387                 EXPECT_EQ(1u, outer->get(value).size()); // Other one was deleted by weak handling.
4388                 if (i & 1)
4389                     keepAlive->at(i) = nullptr;
4390             }
4391             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4392             EXPECT_EQ(5000u, outer->size());
4393         }
4394     }
4395 }
4396
4397 class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> {
4398 public:
4399     void trace(Visitor* visitor)
4400     {
4401         visitor->trace(m_map);
4402     }
4403
4404     typedef HeapHashMap<WeakMember<IntWrapper>, Member<EphemeronWrapper> > Map;
4405     Map& map() { return m_map; }
4406
4407 private:
4408     Map m_map;
4409 };
4410
4411 TEST(HeapTest, EphemeronsPointToEphemerons)
4412 {
4413     Persistent<IntWrapper> key = IntWrapper::create(42);
4414     Persistent<IntWrapper> key2 = IntWrapper::create(103);
4415
4416     Persistent<EphemeronWrapper> chain;
4417     for (int i = 0; i < 100; i++) {
4418         EphemeronWrapper* oldHead = chain;
4419         chain = new EphemeronWrapper();
4420         if (i == 50)
4421             chain->map().add(key2, oldHead);
4422         else
4423             chain->map().add(key, oldHead);
4424         chain->map().add(IntWrapper::create(103), new EphemeronWrapper());
4425     }
4426
4427     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4428
4429     EphemeronWrapper* wrapper = chain;
4430     for (int i = 0; i< 100; i++) {
4431         EXPECT_EQ(1u, wrapper->map().size());
4432         if (i == 49)
4433             wrapper = wrapper->map().get(key2);
4434         else
4435             wrapper = wrapper->map().get(key);
4436     }
4437     EXPECT_EQ(nullptr, wrapper);
4438
4439     key2.clear();
4440     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4441
4442     wrapper = chain;
4443     for (int i = 0; i < 50; i++) {
4444         EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size());
4445         wrapper = wrapper->map().get(key);
4446     }
4447     EXPECT_EQ(nullptr, wrapper);
4448
4449     key.clear();
4450     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4451     EXPECT_EQ(0u, chain->map().size());
4452 }
4453
4454 TEST(HeapTest, Ephemeron)
4455 {
4456     typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling>  WeakPairMap;
4457     typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper> >  PairWeakMap;
4458     typedef HeapHashSet<WeakMember<IntWrapper> > Set;
4459
4460     Persistent<WeakPairMap> weakPairMap = new WeakPairMap();
4461     Persistent<WeakPairMap> weakPairMap2 = new WeakPairMap();
4462     Persistent<WeakPairMap> weakPairMap3 = new WeakPairMap();
4463     Persistent<WeakPairMap> weakPairMap4 = new WeakPairMap();
4464
4465     Persistent<PairWeakMap> pairWeakMap = new PairWeakMap();
4466     Persistent<PairWeakMap> pairWeakMap2 = new PairWeakMap();
4467
4468     Persistent<Set> set = new Set();
4469
4470     Persistent<IntWrapper> wp1 = IntWrapper::create(1);
4471     Persistent<IntWrapper> wp2 = IntWrapper::create(2);
4472     Persistent<IntWrapper> pw1 = IntWrapper::create(3);
4473     Persistent<IntWrapper> pw2 = IntWrapper::create(4);
4474
4475     weakPairMap->add(wp1, PairWithWeakHandling(wp1, wp1));
4476     weakPairMap->add(wp2, PairWithWeakHandling(wp1, wp1));
4477     weakPairMap2->add(wp1, PairWithWeakHandling(wp1, wp2));
4478     weakPairMap2->add(wp2, PairWithWeakHandling(wp1, wp2));
4479     // The map from wp1 to (wp2, wp1) would mark wp2 live, so we skip that.
4480     weakPairMap3->add(wp2, PairWithWeakHandling(wp2, wp1));
4481     weakPairMap4->add(wp1, PairWithWeakHandling(wp2, wp2));
4482     weakPairMap4->add(wp2, PairWithWeakHandling(wp2, wp2));
4483
4484     pairWeakMap->add(PairWithWeakHandling(pw1, pw1), pw1);
4485     pairWeakMap->add(PairWithWeakHandling(pw1, pw2), pw1);
4486     // The map from (pw2, pw1) to pw1 would make pw2 live, so we skip that.
4487     pairWeakMap->add(PairWithWeakHandling(pw2, pw2), pw1);
4488     pairWeakMap2->add(PairWithWeakHandling(pw1, pw1), pw2);
4489     pairWeakMap2->add(PairWithWeakHandling(pw1, pw2), pw2);
4490     pairWeakMap2->add(PairWithWeakHandling(pw2, pw1), pw2);
4491     pairWeakMap2->add(PairWithWeakHandling(pw2, pw2), pw2);
4492
4493
4494     set->add(wp1);
4495     set->add(wp2);
4496     set->add(pw1);
4497     set->add(pw2);
4498
4499     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4500
4501     EXPECT_EQ(2u, weakPairMap->size());
4502     EXPECT_EQ(2u, weakPairMap2->size());
4503     EXPECT_EQ(1u, weakPairMap3->size());
4504     EXPECT_EQ(2u, weakPairMap4->size());
4505
4506     EXPECT_EQ(3u, pairWeakMap->size());
4507     EXPECT_EQ(4u, pairWeakMap2->size());
4508
4509     EXPECT_EQ(4u, set->size());
4510
4511     wp2.clear(); // Kills all entries in the weakPairMaps except the first.
4512     pw2.clear(); // Kills all entries in the pairWeakMaps except the first.
4513
4514     for (int i = 0; i < 2; i++) {
4515         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4516
4517         EXPECT_EQ(1u, weakPairMap->size());
4518         EXPECT_EQ(0u, weakPairMap2->size());
4519         EXPECT_EQ(0u, weakPairMap3->size());
4520         EXPECT_EQ(0u, weakPairMap4->size());
4521
4522         EXPECT_EQ(1u, pairWeakMap->size());
4523         EXPECT_EQ(0u, pairWeakMap2->size());
4524
4525         EXPECT_EQ(2u, set->size()); // wp1 and pw1.
4526     }
4527
4528     wp1.clear();
4529     pw1.clear();
4530
4531     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4532
4533     EXPECT_EQ(0u, weakPairMap->size());
4534     EXPECT_EQ(0u, pairWeakMap->size());
4535     EXPECT_EQ(0u, set->size());
4536 }
4537
4538 class Link1 : public GarbageCollected<Link1> {
4539 public:
4540     Link1(IntWrapper* link) : m_link(link) { }
4541
4542     void trace(Visitor* visitor)
4543     {
4544         visitor->trace(m_link);
4545     }
4546
4547     IntWrapper* link() { return m_link; }
4548
4549 private:
4550     Member<IntWrapper> m_link;
4551 };
4552
4553 TEST(HeapTest, IndirectStrongToWeak)
4554 {
4555     typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1> > Map;
4556     Persistent<Map> map = new Map();
4557     Persistent<IntWrapper> deadObject = IntWrapper::create(100); // Named for "Drowning by Numbers" (1988).
4558     Persistent<IntWrapper> lifeObject = IntWrapper::create(42);
4559     map->add(deadObject, new Link1(deadObject));
4560     map->add(lifeObject, new Link1(lifeObject));
4561     EXPECT_EQ(2u, map->size());
4562     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4563     EXPECT_EQ(2u, map->size());
4564     EXPECT_EQ(deadObject, map->get(deadObject)->link());
4565     EXPECT_EQ(lifeObject, map->get(lifeObject)->link());
4566     deadObject.clear(); // Now it can live up to its name.
4567     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4568     EXPECT_EQ(1u, map->size());
4569     EXPECT_EQ(lifeObject, map->get(lifeObject)->link());
4570     lifeObject.clear(); // Despite its name.
4571     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4572     EXPECT_EQ(0u, map->size());
4573 }
4574
4575 static Mutex& mainThreadMutex()
4576 {
4577     AtomicallyInitializedStatic(Mutex&, mainMutex = *new Mutex);
4578     return mainMutex;
4579 }
4580
4581 static ThreadCondition& mainThreadCondition()
4582 {
4583     AtomicallyInitializedStatic(ThreadCondition&, mainCondition = *new ThreadCondition);
4584     return mainCondition;
4585 }
4586
4587 static void parkMainThread()
4588 {
4589     mainThreadCondition().wait(mainThreadMutex());
4590 }
4591
4592 static void wakeMainThread()
4593 {
4594     MutexLocker locker(mainThreadMutex());
4595     mainThreadCondition().signal();
4596 }
4597
4598 static Mutex& workerThreadMutex()
4599 {
4600     AtomicallyInitializedStatic(Mutex&, workerMutex = *new Mutex);
4601     return workerMutex;
4602 }
4603
4604 static ThreadCondition& workerThreadCondition()
4605 {
4606     AtomicallyInitializedStatic(ThreadCondition&, workerCondition = *new ThreadCondition);
4607     return workerCondition;
4608 }
4609
4610 static void parkWorkerThread()
4611 {
4612     workerThreadCondition().wait(workerThreadMutex());
4613 }
4614
4615 static void wakeWorkerThread()
4616 {
4617     MutexLocker locker(workerThreadMutex());
4618     workerThreadCondition().signal();
4619 }
4620
4621 class CrossThreadObject : public GarbageCollectedFinalized<CrossThreadObject> {
4622 public:
4623     static CrossThreadObject* create(IntWrapper* workerObjectPointer)
4624     {
4625         return new CrossThreadObject(workerObjectPointer);
4626     }
4627
4628     virtual ~CrossThreadObject()
4629     {
4630         ++s_destructorCalls;
4631     }
4632
4633     static int s_destructorCalls;
4634     void trace(Visitor* visitor) { visitor->trace(m_workerObject); }
4635
4636 private:
4637     CrossThreadObject(IntWrapper* workerObjectPointer) : m_workerObject(workerObjectPointer) { }
4638
4639 private:
4640     Member<IntWrapper> m_workerObject;
4641 };
4642
4643 int CrossThreadObject::s_destructorCalls = 0;
4644
4645 class CrossThreadPointerTester {
4646 public:
4647     static void test()
4648     {
4649         CrossThreadObject::s_destructorCalls = 0;
4650         IntWrapper::s_destructorCalls = 0;
4651
4652         MutexLocker locker(mainThreadMutex());
4653         OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread"));
4654         workerThread->postTask(new Task(WTF::bind(workerThreadMain)));
4655
4656         parkMainThread();
4657
4658         uintptr_t stackPtrValue = 0;
4659         {
4660             // Create an object with a pointer to the other heap's IntWrapper.
4661             Persistent<CrossThreadObject> cto = CrossThreadObject::create(const_cast<IntWrapper*>(s_workerObjectPointer));
4662             s_workerObjectPointer = 0;
4663
4664             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4665
4666             // Nothing should have been collected/destructed.
4667             EXPECT_EQ(0, CrossThreadObject::s_destructorCalls);
4668             EXPECT_EQ(0, IntWrapper::s_destructorCalls);
4669
4670             // Put cto into a stack value. This is used to check that a conservative
4671             // GC succeeds even though we are tracing the other thread heap after
4672             // shutting it down.
4673             stackPtrValue = reinterpret_cast<uintptr_t>(cto.get());
4674         }
4675         // At this point it is "programatically" okay to shut down the worker thread
4676         // since the cto object should be dead. However out stackPtrValue will cause a
4677         // trace of the object when doing a conservative GC.
4678         // The worker thread's thread local GC's should just add the worker thread's
4679         // pages to the heap after finalizing IntWrapper.
4680         wakeWorkerThread();
4681
4682         // Wait for the worker to shutdown.
4683         parkMainThread();
4684
4685         // After the worker thread has detached it should have finalized the
4686         // IntWrapper object on its heaps. Since there has been no global GC
4687         // the cto object should not have been finalized.
4688         EXPECT_EQ(0, CrossThreadObject::s_destructorCalls);
4689         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
4690
4691         // Now do a conservative GC. The stackPtrValue should keep cto alive
4692         // and will also cause the orphaned page of the other thread to be
4693         // traced. At this point cto should still not be finalized.
4694         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4695         EXPECT_EQ(0, CrossThreadObject::s_destructorCalls);
4696         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
4697
4698         // This release assert is here to ensure the stackValuePtr is not
4699         // optimized away before doing the above conservative GC. If the
4700         // EXPECT_EQ(0, CrossThreadObject::s_destructorCalls) call above
4701         // starts failing it means we have to find a better way to ensure
4702         // the stackPtrValue is not optimized away.
4703         RELEASE_ASSERT(stackPtrValue);
4704
4705         // Do a GC with no pointers on the stack to see the cto being collected.
4706         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4707         EXPECT_EQ(1, CrossThreadObject::s_destructorCalls);
4708         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
4709     }
4710
4711 private:
4712     static void workerThreadMain()
4713     {
4714         MutexLocker locker(workerThreadMutex());
4715         ThreadState::attach();
4716
4717         {
4718             // Create a worker object that is only kept alive by a cross thread
4719             // pointer (from CrossThreadObject).
4720             IntWrapper* workerObject = IntWrapper::create(42);
4721             s_workerObjectPointer = workerObject;
4722         }
4723
4724         // Wake up the main thread which is waiting for the worker to do its
4725         // allocation and passing the pointer.
4726         wakeMainThread();
4727
4728         // Wait for main thread to signal the worker to shutdown.
4729         {
4730             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
4731             parkWorkerThread();
4732         }
4733
4734         ThreadState::detach();
4735
4736         // Tell the main thread the worker has done its shutdown.
4737         wakeMainThread();
4738     }
4739
4740     static volatile IntWrapper* s_workerObjectPointer;
4741 };
4742
4743 volatile IntWrapper* CrossThreadPointerTester::s_workerObjectPointer = 0;
4744
4745 TEST(HeapTest, CrossThreadPointerToOrphanedPage)
4746 {
4747     CrossThreadPointerTester::test();
4748 }
4749
4750 class DeadBitTester {
4751 public:
4752     static void test()
4753     {
4754         IntWrapper::s_destructorCalls = 0;
4755
4756         MutexLocker locker(mainThreadMutex());
4757         OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread"));
4758         workerThread->postTask(new Task(WTF::bind(workerThreadMain)));
4759
4760         // Wait for the worker thread to have done its initialization,
4761         // IE. the worker allocates an object and then throw aways any
4762         // pointers to it.
4763         parkMainThread();
4764
4765         // Now do a GC. This will not find the worker threads object since it
4766         // is not referred from any of the threads. Even a conservative
4767         // GC will not find it.
4768         // Also at this point the worker is waiting for the main thread
4769         // to be parked and will not do any sweep of its heap.
4770         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4771
4772         // Since the worker thread is not sweeping the worker object should
4773         // not have been finalized.
4774         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
4775
4776         // Put the worker thread's object address on the stack and do a
4777         // conservative GC. This should find the worker object, but since
4778         // it was dead in the previous GC it should not be traced in this
4779         // GC.
4780         uintptr_t stackPtrValue = s_workerObjectPointer;
4781         s_workerObjectPointer = 0;
4782         ASSERT_UNUSED(stackPtrValue, stackPtrValue);
4783         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4784
4785         // Since the worker thread is not sweeping the worker object should
4786         // not have been finalized.
4787         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
4788
4789         // Wake up the worker thread so it can continue with its sweeping.
4790         // This should finalized the worker object which we test below.
4791         // The worker thread will go back to sleep once sweeping to ensure
4792         // we don't have thread local GCs until after validating the destructor
4793         // was called.
4794         wakeWorkerThread();
4795
4796         // Wait for the worker thread to sweep its heaps before checking.
4797         parkMainThread();
4798         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
4799
4800         // Wake up the worker to allow it thread to continue with thread
4801         // shutdown.
4802         wakeWorkerThread();
4803     }
4804
4805 private:
4806
4807     static void workerThreadMain()
4808     {
4809         MutexLocker locker(workerThreadMutex());
4810
4811         ThreadState::attach();
4812
4813         {
4814             // Create a worker object that is not kept alive except the
4815             // main thread will keep it as an integer value on its stack.
4816             IntWrapper* workerObject = IntWrapper::create(42);
4817             s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject);
4818         }
4819
4820         // Signal the main thread that the worker is done with its allocation.
4821         wakeMainThread();
4822
4823         {
4824             // Wait for the main thread to do two GCs without sweeping this thread
4825             // heap. The worker waits within a safepoint, but there is no sweeping
4826             // until leaving the safepoint scope.
4827             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
4828             parkWorkerThread();
4829         }
4830
4831         // Wake up the main thread when done sweeping.
4832         wakeMainThread();
4833
4834         // Wait with detach until the main thread says so. This is not strictly
4835         // necessary, but it means the worker thread will not do its thread local
4836         // GCs just yet, making it easier to reason about that no new GC has occurred
4837         // and the above sweep was the one finalizing the worker object.
4838         parkWorkerThread();
4839
4840         ThreadState::detach();
4841     }
4842
4843     static volatile uintptr_t s_workerObjectPointer;
4844 };
4845
4846 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0;
4847
4848 TEST(HeapTest, ObjectDeadBit)
4849 {
4850     DeadBitTester::test();
4851 }
4852
4853 class ThreadedStrongificationTester {
4854 public:
4855     static void test()
4856     {
4857         IntWrapper::s_destructorCalls = 0;
4858
4859         MutexLocker locker(mainThreadMutex());
4860         OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread"));
4861         workerThread->postTask(new Task(WTF::bind(workerThreadMain)));
4862
4863         // Wait for the worker thread initialization. The worker
4864         // allocates a weak collection where both collection and
4865         // contents are kept alive via persistent pointers.
4866         parkMainThread();
4867
4868         // Perform two garbage collections where the worker thread does
4869         // not wake up in between. This will cause us to remove marks
4870         // and mark unmarked objects dead. The collection on the worker
4871         // heap is found through the persistent and the backing should
4872         // be marked.
4873         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4874         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4875
4876         // Wake up the worker thread so it can continue. It will sweep
4877         // and perform another GC where the backing store of its
4878         // collection should be strongified.
4879         wakeWorkerThread();
4880
4881         // Wait for the worker thread to sweep its heaps before checking.
4882         {
4883             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
4884             parkMainThread();
4885         }
4886     }
4887
4888 private:
4889
4890     static HeapHashSet<WeakMember<IntWrapper> >* allocateCollection()
4891     {
4892         // Create a weak collection that is kept alive by a persistent
4893         // and keep the contents alive with a persistents as
4894         // well.
4895         Persistent<IntWrapper> wrapper1 = IntWrapper::create(32);
4896         Persistent<IntWrapper> wrapper2 = IntWrapper::create(32);
4897         Persistent<IntWrapper> wrapper3 = IntWrapper::create(32);
4898         Persistent<IntWrapper> wrapper4 = IntWrapper::create(32);
4899         Persistent<IntWrapper> wrapper5 = IntWrapper::create(32);
4900         Persistent<IntWrapper> wrapper6 = IntWrapper::create(32);
4901         Persistent<HeapHashSet<WeakMember<IntWrapper> > > weakCollection = new HeapHashSet<WeakMember<IntWrapper> >;
4902         weakCollection->add(wrapper1);
4903         weakCollection->add(wrapper2);
4904         weakCollection->add(wrapper3);
4905         weakCollection->add(wrapper4);
4906         weakCollection->add(wrapper5);
4907         weakCollection->add(wrapper6);
4908
4909         // Signal the main thread that the worker is done with its allocation.
4910         wakeMainThread();
4911
4912         {
4913             // Wait for the main thread to do two GCs without sweeping
4914             // this thread heap. The worker waits within a safepoint,
4915             // but there is no sweeping until leaving the safepoint
4916             // scope. If the weak collection backing is marked dead
4917             // because of this we will not get strongification in the
4918             // GC we force when we continue.
4919             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
4920             parkWorkerThread();
4921         }
4922
4923         return weakCollection;
4924     }
4925
4926     static void workerThreadMain()
4927     {
4928         MutexLocker locker(workerThreadMutex());
4929
4930         ThreadState::attach();
4931
4932         {
4933             Persistent<HeapHashSet<WeakMember<IntWrapper> > > collection = allocateCollection();
4934             {
4935                 // Prevent weak processing with an iterator and GC.
4936                 HeapHashSet<WeakMember<IntWrapper> >::iterator it = collection->begin();
4937                 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4938
4939                 // The backing should be strongified because of the iterator.
4940                 EXPECT_EQ(6u, collection->size());
4941                 EXPECT_EQ(32, (*it)->value());
4942             }
4943
4944             // Disregarding the iterator but keeping the collection alive
4945             // with a persistent should lead to weak processing.
4946             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4947             EXPECT_EQ(0u, collection->size());
4948         }
4949
4950         wakeMainThread();
4951         ThreadState::detach();
4952     }
4953
4954     static volatile uintptr_t s_workerObjectPointer;
4955 };
4956
4957 TEST(HeapTest, ThreadedStrongification)
4958 {
4959     ThreadedStrongificationTester::test();
4960 }
4961
4962 static bool allocateAndReturnBool()
4963 {
4964     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
4965     return true;
4966 }
4967
4968 class MixinWithGarbageCollectionInConstructor : public GarbageCollectedMixin {
4969 public:
4970     MixinWithGarbageCollectionInConstructor() : m_dummy(allocateAndReturnBool())
4971     {
4972     }
4973 private:
4974     bool m_dummy;
4975 };
4976
4977 class ClassWithGarbageCollectingMixinConstructor
4978     : public GarbageCollected<ClassWithGarbageCollectingMixinConstructor>
4979     , public MixinWithGarbageCollectionInConstructor {
4980     USING_GARBAGE_COLLECTED_MIXIN(ClassWithGarbageCollectingMixinConstructor);
4981 public:
4982     ClassWithGarbageCollectingMixinConstructor() : m_wrapper(IntWrapper::create(32))
4983     {
4984     }
4985
4986     virtual void trace(Visitor* visitor)
4987     {
4988         visitor->trace(m_wrapper);
4989     }
4990
4991     void verify()
4992     {
4993         EXPECT_EQ(32, m_wrapper->value());
4994     }
4995
4996 private:
4997     Member<IntWrapper> m_wrapper;
4998 };
4999
5000 // Regression test for out of bounds call through vtable.
5001 // Passes if it doesn't crash.
5002 TEST(HeapTest, GarbageCollectionDuringMixinConstruction)
5003 {
5004     ClassWithGarbageCollectingMixinConstructor* a =
5005         new ClassWithGarbageCollectingMixinConstructor();
5006     a->verify();
5007 }
5008
5009 static RecursiveMutex& recursiveMutex()
5010 {
5011     AtomicallyInitializedStatic(RecursiveMutex&, recursiveMutex = *new RecursiveMutex);
5012     return recursiveMutex;
5013 }
5014
5015 class DestructorLockingObject : public GarbageCollectedFinalized<DestructorLockingObject> {
5016 public:
5017     static DestructorLockingObject* create()
5018     {
5019         return new DestructorLockingObject();
5020     }
5021
5022     virtual ~DestructorLockingObject()
5023     {
5024         SafePointAwareMutexLocker lock(recursiveMutex());
5025         ++s_destructorCalls;
5026     }
5027
5028     static int s_destructorCalls;
5029     void trace(Visitor* visitor) { }
5030
5031 private:
5032     DestructorLockingObject() { }
5033 };
5034
5035 int DestructorLockingObject::s_destructorCalls = 0;
5036
5037 class RecursiveLockingTester {
5038 public:
5039     static void test()
5040     {
5041         DestructorLockingObject::s_destructorCalls = 0;
5042
5043         MutexLocker locker(mainThreadMutex());
5044         OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread"));
5045         workerThread->postTask(new Task(WTF::bind(workerThreadMain)));
5046
5047         // Park the main thread until the worker thread has initialized.
5048         parkMainThread();
5049
5050         {
5051             SafePointAwareMutexLocker recursiveLocker(recursiveMutex());
5052
5053             // Let the worker try to acquire the above mutex. It won't get it
5054             // until the main thread has done its GC.
5055             wakeWorkerThread();
5056
5057             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
5058
5059             // The worker thread should not have swept yet since it is waiting
5060             // to get the global mutex.
5061             EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls);
5062         }
5063         // At this point the main thread releases the global lock and the worker
5064         // can acquire it and do its sweep of its heaps. Just wait for the worker
5065         // to complete its sweep and check the result.
5066         parkMainThread();
5067         EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls);
5068     }
5069
5070 private:
5071     static void workerThreadMain()
5072     {
5073         MutexLocker locker(workerThreadMutex());
5074         ThreadState::attach();
5075
5076         DestructorLockingObject* dlo = DestructorLockingObject::create();
5077         ASSERT_UNUSED(dlo, dlo);
5078
5079         // Wake up the main thread which is waiting for the worker to do its
5080         // allocation.
5081         wakeMainThread();
5082
5083         // Wait for the main thread to get the global lock to ensure it has
5084         // it before the worker tries to acquire it. We want the worker to
5085         // block in the SafePointAwareMutexLocker until the main thread
5086         // has done a GC. The GC will not mark the "dlo" object since the worker
5087         // is entering the safepoint with NoHeapPointersOnStack. When the worker
5088         // subsequently gets the global lock and leaves the safepoint it will
5089         // sweep its heap and finalize "dlo". The destructor of "dlo" will try
5090         // to acquire the same global lock that the thread just got and deadlock
5091         // unless the global lock is recursive.
5092         parkWorkerThread();
5093         SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), ThreadState::NoHeapPointersOnStack);
5094
5095         // We won't get here unless the lock is recursive since the sweep done
5096         // in the constructor of SafePointAwareMutexLocker after
5097         // getting the lock will not complete given the "dlo" destructor is
5098         // waiting to get the same lock.
5099         // Tell the main thread the worker has done its sweep.
5100         wakeMainThread();
5101
5102         ThreadState::detach();
5103     }
5104
5105     static volatile IntWrapper* s_workerObjectPointer;
5106 };
5107
5108 TEST(HeapTest, RecursiveMutex)
5109 {
5110     RecursiveLockingTester::test();
5111 }
5112
5113 template<typename T>
5114 class TraceIfNeededTester : public GarbageCollectedFinalized<TraceIfNeededTester<T> > {
5115 public:
5116     static TraceIfNeededTester<T>* create() { return new TraceIfNeededTester<T>(); }
5117     static TraceIfNeededTester<T>* create(const T& obj) { return new TraceIfNeededTester<T>(obj); }
5118     void trace(Visitor* visitor) { TraceIfNeeded<T>::trace(visitor, &m_obj); }
5119     T& obj() { return m_obj; }
5120     ~TraceIfNeededTester() { }
5121 private:
5122     TraceIfNeededTester() { }
5123     explicit TraceIfNeededTester(const T& obj) : m_obj(obj) { }
5124     T m_obj;
5125 };
5126
5127 class PartObject {
5128     DISALLOW_ALLOCATION();
5129 public:
5130     PartObject() : m_obj(SimpleObject::create()) { }
5131     void trace(Visitor* visitor) { visitor->trace(m_obj); }
5132 private:
5133     Member<SimpleObject> m_obj;
5134 };
5135
5136 TEST(HeapTest, TraceIfNeeded)
5137 {
5138     CountingVisitor visitor;
5139
5140     {
5141         TraceIfNeededTester<RefPtr<OffHeapInt> >* m_offHeap = TraceIfNeededTester<RefPtr<OffHeapInt> >::create(OffHeapInt::create(42));
5142         visitor.reset();
5143         m_offHeap->trace(&visitor);
5144         EXPECT_EQ(0u, visitor.count());
5145     }
5146
5147     {
5148         TraceIfNeededTester<PartObject>* m_part = TraceIfNeededTester<PartObject>::create();
5149         visitor.reset();
5150         m_part->trace(&visitor);
5151         EXPECT_EQ(1u, visitor.count());
5152     }
5153
5154     {
5155         TraceIfNeededTester<Member<SimpleObject> >* m_obj = TraceIfNeededTester<Member<SimpleObject> >::create(Member<SimpleObject>(SimpleObject::create()));
5156         visitor.reset();
5157         m_obj->trace(&visitor);
5158         EXPECT_EQ(1u, visitor.count());
5159     }
5160
5161     {
5162         TraceIfNeededTester<HeapVector<Member<SimpleObject> > >* m_vec = TraceIfNeededTester<HeapVector<Member<SimpleObject> > >::create();
5163         m_vec->obj().append(SimpleObject::create());
5164         visitor.reset();
5165         m_vec->trace(&visitor);
5166         EXPECT_EQ(2u, visitor.count());
5167     }
5168 }
5169
5170 class AllocatesOnAssignment {
5171 public:
5172     AllocatesOnAssignment(std::nullptr_t)
5173         : m_value(nullptr)
5174     { }
5175     AllocatesOnAssignment(int x)
5176         : m_value(new IntWrapper(x))
5177     { }
5178     AllocatesOnAssignment(IntWrapper* x)
5179         : m_value(x)
5180     { }
5181
5182     AllocatesOnAssignment& operator=(const AllocatesOnAssignment x)
5183     {
5184         m_value = x.m_value;
5185         return *this;
5186     }
5187
5188     enum DeletedMarker {
5189         DeletedValue
5190     };
5191
5192     AllocatesOnAssignment(const AllocatesOnAssignment& other)
5193     {
5194         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
5195         m_value = new IntWrapper(other.m_value->value());
5196     }
5197
5198     AllocatesOnAssignment(DeletedMarker)
5199         : m_value(reinterpret_cast<IntWrapper*>(-1)) { }
5200
5201     inline bool isDeleted() const { return m_value == reinterpret_cast<IntWrapper*>(-1); }
5202
5203     virtual void trace(Visitor* visitor)
5204     {
5205         visitor->trace(m_value);
5206     }
5207
5208     int value() { return m_value->value(); }
5209
5210 private:
5211     Member<IntWrapper> m_value;
5212
5213     friend bool operator==(const AllocatesOnAssignment&, const AllocatesOnAssignment&);
5214     friend void swap(AllocatesOnAssignment&, AllocatesOnAssignment&);
5215 };
5216
5217 bool operator==(const AllocatesOnAssignment& a, const AllocatesOnAssignment& b)
5218 {
5219     if (a.m_value)
5220         return b.m_value && a.m_value->value() == b.m_value->value();
5221     return !b.m_value;
5222 }
5223
5224 void swap(AllocatesOnAssignment& a, AllocatesOnAssignment& b)
5225 {
5226     std::swap(a.m_value, b.m_value);
5227 }
5228
5229 struct DegenerateHash {
5230     static unsigned hash(const AllocatesOnAssignment&) { return 0; }
5231     static bool equal(const AllocatesOnAssignment& a, const AllocatesOnAssignment& b) { return !a.isDeleted() && a == b; }
5232     static const bool safeToCompareToEmptyOrDeleted = true;
5233 };
5234
5235 struct AllocatesOnAssignmentHashTraits : WTF::GenericHashTraits<AllocatesOnAssignment> {
5236     typedef AllocatesOnAssignment T;
5237     typedef std::nullptr_t EmptyValueType;
5238     static EmptyValueType emptyValue() { return nullptr; }
5239     static const bool emptyValueIsZero = false; // Can't be zero if it has a vtable.
5240     static const bool needsDestruction = false;
5241     static void constructDeletedValue(T& slot, bool) { slot = T(AllocatesOnAssignment::DeletedValue); }
5242     static bool isDeletedValue(const T& value) { return value.isDeleted(); }
5243 };
5244
5245 } // namespace blink
5246
5247 namespace WTF {
5248
5249 template<> struct DefaultHash<blink::AllocatesOnAssignment> {
5250     typedef blink::DegenerateHash Hash;
5251 };
5252
5253 template <> struct HashTraits<blink::AllocatesOnAssignment> : blink::AllocatesOnAssignmentHashTraits { };
5254
5255 } // namespace WTF
5256
5257 namespace blink {
5258
5259 TEST(HeapTest, GCInHashMapOperations)
5260 {
5261     typedef HeapHashMap<AllocatesOnAssignment, AllocatesOnAssignment> Map;
5262     Map* map = new Map();
5263     IntWrapper* key = new IntWrapper(42);
5264     map->add(key, AllocatesOnAssignment(103));
5265     map->remove(key);
5266     for (int i = 0; i < 10; i++)
5267         map->add(AllocatesOnAssignment(i), AllocatesOnAssignment(i));
5268     for (Map::iterator it = map->begin(); it != map->end(); ++it)
5269         EXPECT_EQ(it->key.value(), it->value.value());
5270 }
5271
5272 class PartObjectWithVirtualMethod {
5273 public:
5274     virtual void trace(Visitor*) { }
5275 };
5276
5277 class ObjectWithVirtualPartObject : public GarbageCollected<ObjectWithVirtualPartObject> {
5278 public:
5279     ObjectWithVirtualPartObject() : m_dummy(allocateAndReturnBool()) { }
5280     void trace(Visitor* visitor) { visitor->trace(m_part); }
5281 private:
5282     bool m_dummy;
5283     PartObjectWithVirtualMethod m_part;
5284 };
5285
5286 TEST(HeapTest, PartObjectWithVirtualMethod)
5287 {
5288     ObjectWithVirtualPartObject* object = new ObjectWithVirtualPartObject();
5289     EXPECT_TRUE(object);
5290 }
5291
5292 class AllocInSuperConstructorArgumentSuper : public GarbageCollectedFinalized<AllocInSuperConstructorArgumentSuper> {
5293 public:
5294     AllocInSuperConstructorArgumentSuper(bool value) : m_value(value) { }
5295     virtual void trace(Visitor*) { }
5296     bool value() { return m_value; }
5297 private:
5298     bool m_value;
5299 };
5300
5301 class AllocInSuperConstructorArgument : public AllocInSuperConstructorArgumentSuper {
5302 public:
5303     AllocInSuperConstructorArgument()
5304         : AllocInSuperConstructorArgumentSuper(allocateAndReturnBool())
5305     {
5306     }
5307 };
5308
5309 // Regression test for crbug.com/404511. Tests conservative marking of
5310 // an object with an uninitialized vtable.
5311 TEST(HeapTest, AllocationInSuperConstructorArgument)
5312 {
5313     AllocInSuperConstructorArgument* object = new AllocInSuperConstructorArgument();
5314     EXPECT_TRUE(object);
5315     Heap::collectAllGarbage();
5316 }
5317
5318 class NonNodeAllocatingNodeInDestructor : public GarbageCollectedFinalized<NonNodeAllocatingNodeInDestructor> {
5319 public:
5320     ~NonNodeAllocatingNodeInDestructor()
5321     {
5322         s_node = new Persistent<Node>(Node::create(10));
5323     }
5324
5325     void trace(Visitor*) { }
5326
5327     static Persistent<Node>* s_node;
5328 };
5329
5330 Persistent<Node>* NonNodeAllocatingNodeInDestructor::s_node = 0;
5331
5332 TEST(HeapTest, NonNodeAllocatingNodeInDestructor)
5333 {
5334     new NonNodeAllocatingNodeInDestructor();
5335     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
5336     EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::s_node)->value());
5337     delete NonNodeAllocatingNodeInDestructor::s_node;
5338     NonNodeAllocatingNodeInDestructor::s_node = 0;
5339 }
5340
5341 } // namespace blink