Home | History | Annotate | Download | only in heap
      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/heap/Handle.h"
     34 #include "platform/heap/Heap.h"
     35 #include "platform/heap/HeapLinkedStack.h"
     36 #include "platform/heap/HeapTerminatedArrayBuilder.h"
     37 #include "platform/heap/ThreadState.h"
     38 #include "platform/heap/Visitor.h"
     39 #include "public/platform/Platform.h"
     40 #include "wtf/HashTraits.h"
     41 #include "wtf/LinkedHashSet.h"
     42 
     43 #include <gtest/gtest.h>
     44 
     45 namespace WebCore {
     46 
     47 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> {
     48 public:
     49     static IntWrapper* create(int x)
     50     {
     51         return new IntWrapper(x);
     52     }
     53 
     54     virtual ~IntWrapper()
     55     {
     56         ++s_destructorCalls;
     57     }
     58 
     59     static int s_destructorCalls;
     60     static void trace(Visitor*) { }
     61 
     62     int value() const { return m_x; }
     63 
     64     bool operator==(const IntWrapper& other) const { return other.value() == value(); }
     65 
     66     unsigned hash() { return IntHash<int>::hash(m_x); }
     67 
     68 protected:
     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.
    138     void traceInCollection(Visitor* visitor, ShouldWeakPointersBeMarkedStrongly strongify)
    139     {
    140         visitor->trace(first);
    141         visitor->traceInCollection(second, strongify);
    142     }
    143     // The traceInCollection may not trace the weak members, so it is vital
    144     // that shouldRemoveFromCollection checks them so the entry can be removed
    145     // from the collection (otherwise it would contain a dangling pointer).
    146     bool shouldRemoveFromCollection(Visitor* visitor)
    147     {
    148         return !visitor->isAlive(second);
    149     }
    150 };
    151 
    152 }
    153 
    154 namespace WTF {
    155 
    156 template<typename T> struct DefaultHash;
    157 template<> struct DefaultHash<WebCore::ThreadMarker> {
    158     typedef WebCore::ThreadMarkerHash Hash;
    159 };
    160 
    161 // ThreadMarkerHash is the default hash for ThreadMarker
    162 template<> struct HashTraits<WebCore::ThreadMarker> : GenericHashTraits<WebCore::ThreadMarker> {
    163     static const bool emptyValueIsZero = true;
    164     static void constructDeletedValue(WebCore::ThreadMarker& slot) { new (NotNull, &slot) WebCore::ThreadMarker(HashTableDeletedValue); }
    165     static bool isDeletedValue(const WebCore::ThreadMarker& slot) { return slot.isHashTableDeletedValue(); }
    166 };
    167 
    168 // The hash algorithm for our custom pair class is just the standard double
    169 // hash for pairs. Note that this means you can't mutate either of the parts of
    170 // the pair while they are in the hash table, as that would change their hash
    171 // code and thus their preferred placement in the table.
    172 template<> struct DefaultHash<WebCore::PairWithWeakHandling> {
    173     typedef PairHash<WebCore::Member<WebCore::IntWrapper>, WebCore::WeakMember<WebCore::IntWrapper> > Hash;
    174 };
    175 
    176 // Custom traits for the pair. These are weakness handling traits, which means
    177 // PairWithWeakHandling must implement the traceInCollection and
    178 // shouldRemoveFromCollection methods. In addition, these traits are concerned
    179 // with the two magic values for the object, that represent empty and deleted
    180 // slots in the hash table. The SimpleClassHashTraits allow empty slots in the
    181 // table to be initialzed with memset to zero, and we use -1 in the first part
    182 // of the pair to represent deleted slots.
    183 template<> struct HashTraits<WebCore::PairWithWeakHandling> : WebCore::WeakHandlingHashTraits<WebCore::PairWithWeakHandling> {
    184     static const bool needsDestruction = false;
    185     static const bool hasIsEmptyValueFunction = true;
    186     static bool isEmptyValue(const WebCore::PairWithWeakHandling& value) { return !value.first; }
    187     static void constructDeletedValue(WebCore::PairWithWeakHandling& slot) { new (NotNull, &slot) WebCore::PairWithWeakHandling(HashTableDeletedValue); }
    188     static bool isDeletedValue(const WebCore::PairWithWeakHandling& value) { return value.isHashTableDeletedValue(); }
    189 };
    190 
    191 }
    192 
    193 namespace WebCore {
    194 
    195 class TestGCScope {
    196 public:
    197     explicit TestGCScope(ThreadState::StackState state)
    198         : m_state(ThreadState::current())
    199         , m_safePointScope(state)
    200         , m_parkedAllThreads(false)
    201     {
    202         m_state->checkThread();
    203         EXPECT_FALSE(m_state->isInGC());
    204         if (LIKELY(ThreadState::stopThreads())) {
    205             m_state->enterGC();
    206             m_parkedAllThreads = true;
    207         }
    208     }
    209 
    210     bool allThreadsParked() { return m_parkedAllThreads; }
    211 
    212     ~TestGCScope()
    213     {
    214         // Only cleanup if we parked all threads in which case the GC happened
    215         // and we need to resume the other threads.
    216         if (LIKELY(m_parkedAllThreads)) {
    217             m_state->leaveGC();
    218             EXPECT_FALSE(m_state->isInGC());
    219             ThreadState::resumeThreads();
    220         }
    221     }
    222 
    223 private:
    224     ThreadState* m_state;
    225     ThreadState::SafePointScope m_safePointScope;
    226     bool m_parkedAllThreads; // False if we fail to park all threads
    227 };
    228 
    229 static void getHeapStats(HeapStats* stats)
    230 {
    231     TestGCScope scope(ThreadState::NoHeapPointersOnStack);
    232     EXPECT_TRUE(scope.allThreadsParked());
    233     Heap::getStats(stats);
    234 }
    235 
    236 #define DEFINE_VISITOR_METHODS(Type)                                       \
    237     virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
    238     {                                                                      \
    239         if (object)                                                        \
    240             m_count++;                                                     \
    241     }                                                                      \
    242     virtual bool isMarked(const Type*) OVERRIDE { return false; }
    243 
    244 class CountingVisitor : public Visitor {
    245 public:
    246     CountingVisitor()
    247         : m_count(0)
    248     {
    249     }
    250 
    251     virtual void mark(const void* object, TraceCallback) OVERRIDE
    252     {
    253         if (object)
    254             m_count++;
    255     }
    256 
    257     virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
    258     {
    259         ASSERT(header->payload());
    260         m_count++;
    261     }
    262 
    263     virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
    264     {
    265         ASSERT(header->payload());
    266         m_count++;
    267     }
    268 
    269     virtual void markConservatively(HeapObjectHeader* header) OVERRIDE
    270     {
    271         ASSERT_NOT_REACHED();
    272     }
    273 
    274     virtual void markConservatively(FinalizedHeapObjectHeader* header) OVERRIDE
    275     {
    276         ASSERT_NOT_REACHED();
    277     }
    278 
    279     virtual void registerWeakMembers(const void*, const void*, WeakPointerCallback) OVERRIDE { }
    280     virtual void registerWeakCell(void**, WeakPointerCallback) OVERRIDE { }
    281     virtual bool isMarked(const void*) OVERRIDE { return false; }
    282 
    283     FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
    284 
    285     size_t count() { return m_count; }
    286     void reset() { m_count = 0; }
    287 
    288 private:
    289     size_t m_count;
    290 };
    291 
    292 class SimpleObject : public GarbageCollected<SimpleObject> {
    293 public:
    294     static SimpleObject* create() { return new SimpleObject(); }
    295     void trace(Visitor*) { }
    296     char getPayload(int i) { return payload[i]; }
    297     // This virtual method is unused but it is here to make sure
    298     // that this object has a vtable. This object is used
    299     // as the super class for objects that also have garbage
    300     // collected mixins and having a virtual here makes sure
    301     // that adjustment is needed both for marking and for isAlive
    302     // checks.
    303     virtual void virtualMethod() { }
    304 protected:
    305     SimpleObject() { }
    306     char payload[64];
    307 };
    308 
    309 #undef DEFINE_VISITOR_METHODS
    310 
    311 class HeapTestSuperClass : public GarbageCollectedFinalized<HeapTestSuperClass> {
    312 public:
    313     static HeapTestSuperClass* create()
    314     {
    315         return new HeapTestSuperClass();
    316     }
    317 
    318     virtual ~HeapTestSuperClass()
    319     {
    320         ++s_destructorCalls;
    321     }
    322 
    323     static int s_destructorCalls;
    324     void trace(Visitor*) { }
    325 
    326 protected:
    327     HeapTestSuperClass() { }
    328 };
    329 
    330 int HeapTestSuperClass::s_destructorCalls = 0;
    331 
    332 class HeapTestOtherSuperClass {
    333 public:
    334     int payload;
    335 };
    336 
    337 static const size_t classMagic = 0xABCDDBCA;
    338 
    339 class HeapTestSubClass : public HeapTestOtherSuperClass, public HeapTestSuperClass {
    340 public:
    341     static HeapTestSubClass* create()
    342     {
    343         return new HeapTestSubClass();
    344     }
    345 
    346     virtual ~HeapTestSubClass()
    347     {
    348         EXPECT_EQ(classMagic, m_magic);
    349         ++s_destructorCalls;
    350     }
    351 
    352     static int s_destructorCalls;
    353 
    354 private:
    355 
    356     HeapTestSubClass() : m_magic(classMagic) { }
    357 
    358     const size_t m_magic;
    359 };
    360 
    361 int HeapTestSubClass::s_destructorCalls = 0;
    362 
    363 class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
    364 public:
    365     HeapAllocatedArray()
    366     {
    367         for (int i = 0; i < s_arraySize; ++i) {
    368             m_array[i] = i % 128;
    369         }
    370     }
    371 
    372     int8_t at(size_t i) { return m_array[i]; }
    373     void trace(Visitor*) { }
    374 private:
    375     static const int s_arraySize = 1000;
    376     int8_t m_array[s_arraySize];
    377 };
    378 
    379 // Do several GCs to make sure that later GCs don't free up old memory from
    380 // previously run tests in this process.
    381 static void clearOutOldGarbage(HeapStats* heapStats)
    382 {
    383     while (true) {
    384         getHeapStats(heapStats);
    385         size_t used = heapStats->totalObjectSpace();
    386         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    387         getHeapStats(heapStats);
    388         if (heapStats->totalObjectSpace() >= used)
    389             break;
    390     }
    391 }
    392 
    393 class OffHeapInt : public RefCounted<OffHeapInt> {
    394 public:
    395     static RefPtr<OffHeapInt> create(int x)
    396     {
    397         return adoptRef(new OffHeapInt(x));
    398     }
    399 
    400     virtual ~OffHeapInt()
    401     {
    402         ++s_destructorCalls;
    403     }
    404 
    405     static int s_destructorCalls;
    406 
    407     int value() const { return m_x; }
    408 
    409     bool operator==(const OffHeapInt& other) const { return other.value() == value(); }
    410 
    411     unsigned hash() { return IntHash<int>::hash(m_x); }
    412     void voidFunction() { }
    413 
    414 protected:
    415     OffHeapInt(int x) : m_x(x) { }
    416 
    417 private:
    418     OffHeapInt();
    419     int m_x;
    420 };
    421 
    422 int IntWrapper::s_destructorCalls = 0;
    423 int OffHeapInt::s_destructorCalls = 0;
    424 
    425 class ThreadedTesterBase {
    426 protected:
    427     static void test(ThreadedTesterBase* tester)
    428     {
    429         for (int i = 0; i < numberOfThreads; i++)
    430             createThread(&threadFunc, tester, "testing thread");
    431         while (tester->m_threadsToFinish) {
    432             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
    433             yield();
    434         }
    435         delete tester;
    436     }
    437 
    438     virtual void runThread() = 0;
    439 
    440 protected:
    441     static const int numberOfThreads = 10;
    442     static const int gcPerThread = 5;
    443     static const int numberOfAllocations = 50;
    444 
    445     ThreadedTesterBase() : m_gcCount(0), m_threadsToFinish(numberOfThreads)
    446     {
    447     }
    448 
    449     virtual ~ThreadedTesterBase()
    450     {
    451     }
    452 
    453     inline bool done() const { return m_gcCount >= numberOfThreads * gcPerThread; }
    454 
    455     volatile int m_gcCount;
    456     volatile int m_threadsToFinish;
    457 
    458 private:
    459     static void threadFunc(void* data)
    460     {
    461         reinterpret_cast<ThreadedTesterBase*>(data)->runThread();
    462     }
    463 };
    464 
    465 class ThreadedHeapTester : public ThreadedTesterBase {
    466 public:
    467     static void test()
    468     {
    469         ThreadedTesterBase::test(new ThreadedHeapTester);
    470     }
    471 
    472 protected:
    473     virtual void runThread() OVERRIDE
    474     {
    475         ThreadState::attach();
    476 
    477         int gcCount = 0;
    478         while (!done()) {
    479             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
    480             {
    481                 Persistent<IntWrapper> wrapper;
    482 
    483                 typedef Persistent<IntWrapper, GlobalPersistents> GlobalIntWrapperPersistent;
    484                 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(0x0ed0cabb)));
    485 
    486                 for (int i = 0; i < numberOfAllocations; i++) {
    487                     wrapper = IntWrapper::create(0x0bbac0de);
    488                     if (!(i % 10)) {
    489                         globalPersistent = adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(0x0ed0cabb)));
    490                     }
    491                     ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
    492                     yield();
    493                 }
    494 
    495                 if (gcCount < gcPerThread) {
    496                     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    497                     gcCount++;
    498                     atomicIncrement(&m_gcCount);
    499                 }
    500 
    501                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    502                 EXPECT_EQ(wrapper->value(), 0x0bbac0de);
    503                 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb);
    504             }
    505             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
    506             yield();
    507         }
    508         ThreadState::detach();
    509         atomicDecrement(&m_threadsToFinish);
    510     }
    511 };
    512 
    513 class ThreadedWeaknessTester : public ThreadedTesterBase {
    514 public:
    515     static void test()
    516     {
    517         ThreadedTesterBase::test(new ThreadedWeaknessTester);
    518     }
    519 
    520 private:
    521     virtual void runThread() OVERRIDE
    522     {
    523         ThreadState::attach();
    524 
    525         int gcCount = 0;
    526         while (!done()) {
    527             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
    528             {
    529                 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper> > > weakMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper> >;
    530                 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper> > weakMap2;
    531 
    532                 for (int i = 0; i < numberOfAllocations; i++) {
    533                     weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0));
    534                     weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0));
    535                     ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
    536                     yield();
    537                 }
    538 
    539                 if (gcCount < gcPerThread) {
    540                     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    541                     gcCount++;
    542                     atomicIncrement(&m_gcCount);
    543                 }
    544 
    545                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    546                 EXPECT_TRUE(weakMap->isEmpty());
    547                 EXPECT_TRUE(weakMap2.isEmpty());
    548             }
    549             ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
    550             yield();
    551         }
    552         ThreadState::detach();
    553         atomicDecrement(&m_threadsToFinish);
    554     }
    555 };
    556 
    557 // The accounting for memory includes the memory used by rounding up object
    558 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
    559 // have some slack in the tests.
    560 template<typename T>
    561 void CheckWithSlack(T expected, T actual, int slack)
    562 {
    563     EXPECT_LE(expected, actual);
    564     EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
    565 }
    566 
    567 class TraceCounter : public GarbageCollectedFinalized<TraceCounter> {
    568 public:
    569     static TraceCounter* create()
    570     {
    571         return new TraceCounter();
    572     }
    573 
    574     void trace(Visitor*) { m_traceCount++; }
    575 
    576     int traceCount() { return m_traceCount; }
    577 
    578 private:
    579     TraceCounter()
    580         : m_traceCount(0)
    581     {
    582     }
    583 
    584     int m_traceCount;
    585 };
    586 
    587 class ClassWithMember : public GarbageCollected<ClassWithMember> {
    588 public:
    589     static ClassWithMember* create()
    590     {
    591         return new ClassWithMember();
    592     }
    593 
    594     void trace(Visitor* visitor)
    595     {
    596         EXPECT_TRUE(visitor->isMarked(this));
    597         if (!traceCount())
    598             EXPECT_FALSE(visitor->isMarked(m_traceCounter));
    599         else
    600             EXPECT_TRUE(visitor->isMarked(m_traceCounter));
    601 
    602         visitor->trace(m_traceCounter);
    603     }
    604 
    605     int traceCount() { return m_traceCounter->traceCount(); }
    606 
    607 private:
    608     ClassWithMember()
    609         : m_traceCounter(TraceCounter::create())
    610     { }
    611 
    612     Member<TraceCounter> m_traceCounter;
    613 };
    614 
    615 class SimpleFinalizedObject : public GarbageCollectedFinalized<SimpleFinalizedObject> {
    616 public:
    617     static SimpleFinalizedObject* create()
    618     {
    619         return new SimpleFinalizedObject();
    620     }
    621 
    622     ~SimpleFinalizedObject()
    623     {
    624         ++s_destructorCalls;
    625     }
    626 
    627     static int s_destructorCalls;
    628 
    629     void trace(Visitor*) { }
    630 
    631 private:
    632     SimpleFinalizedObject() { }
    633 };
    634 
    635 int SimpleFinalizedObject::s_destructorCalls = 0;
    636 
    637 class TestTypedHeapClass : public GarbageCollected<TestTypedHeapClass> {
    638 public:
    639     static TestTypedHeapClass* create()
    640     {
    641         return new TestTypedHeapClass();
    642     }
    643 
    644     void trace(Visitor*) { }
    645 
    646 private:
    647     TestTypedHeapClass() { }
    648 };
    649 
    650 class Bar : public GarbageCollectedFinalized<Bar> {
    651 public:
    652     static Bar* create()
    653     {
    654         return new Bar();
    655     }
    656 
    657     void finalizeGarbageCollectedObject()
    658     {
    659         EXPECT_TRUE(m_magic == magic);
    660         m_magic = 0;
    661         s_live--;
    662     }
    663     bool hasBeenFinalized() const { return !m_magic; }
    664 
    665     virtual void trace(Visitor* visitor) { }
    666     static unsigned s_live;
    667 
    668 protected:
    669     static const int magic = 1337;
    670     int m_magic;
    671 
    672     Bar()
    673         : m_magic(magic)
    674     {
    675         s_live++;
    676     }
    677 };
    678 
    679 unsigned Bar::s_live = 0;
    680 
    681 class Baz : public GarbageCollected<Baz> {
    682 public:
    683     static Baz* create(Bar* bar)
    684     {
    685         return new Baz(bar);
    686     }
    687 
    688     void trace(Visitor* visitor)
    689     {
    690         visitor->trace(m_bar);
    691     }
    692 
    693     void clear() { m_bar.release(); }
    694 
    695     // willFinalize is called by FinalizationObserver.
    696     void willFinalize()
    697     {
    698         EXPECT_TRUE(!m_bar->hasBeenFinalized());
    699     }
    700 
    701 private:
    702     explicit Baz(Bar* bar)
    703         : m_bar(bar)
    704     {
    705     }
    706 
    707     Member<Bar> m_bar;
    708 };
    709 
    710 class Foo : public Bar {
    711 public:
    712     static Foo* create(Bar* bar)
    713     {
    714         return new Foo(bar);
    715     }
    716 
    717     static Foo* create(Foo* foo)
    718     {
    719         return new Foo(foo);
    720     }
    721 
    722     virtual void trace(Visitor* visitor) OVERRIDE
    723     {
    724         if (m_pointsToFoo)
    725             visitor->mark(static_cast<Foo*>(m_bar));
    726         else
    727             visitor->mark(m_bar);
    728     }
    729 
    730 private:
    731     Foo(Bar* bar)
    732         : Bar()
    733         , m_bar(bar)
    734         , m_pointsToFoo(false)
    735     {
    736     }
    737 
    738     Foo(Foo* foo)
    739         : Bar()
    740         , m_bar(foo)
    741         , m_pointsToFoo(true)
    742     {
    743     }
    744 
    745     Bar* m_bar;
    746     bool m_pointsToFoo;
    747 };
    748 
    749 class Bars : public Bar {
    750 public:
    751     static Bars* create()
    752     {
    753         return new Bars();
    754     }
    755 
    756     virtual void trace(Visitor* visitor) OVERRIDE
    757     {
    758         for (unsigned i = 0; i < m_width; i++)
    759             visitor->trace(m_bars[i]);
    760     }
    761 
    762     unsigned getWidth() const
    763     {
    764         return m_width;
    765     }
    766 
    767     static const unsigned width = 7500;
    768 private:
    769     Bars() : m_width(0)
    770     {
    771         for (unsigned i = 0; i < width; i++) {
    772             m_bars[i] = Bar::create();
    773             m_width++;
    774         }
    775     }
    776 
    777     unsigned m_width;
    778     Member<Bar> m_bars[width];
    779 };
    780 
    781 class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
    782 public:
    783     static ConstructorAllocation* create() { return new ConstructorAllocation(); }
    784 
    785     void trace(Visitor* visitor) { visitor->trace(m_intWrapper); }
    786 
    787 private:
    788     ConstructorAllocation()
    789     {
    790         m_intWrapper = IntWrapper::create(42);
    791     }
    792 
    793     Member<IntWrapper> m_intWrapper;
    794 };
    795 
    796 class LargeObject : public GarbageCollectedFinalized<LargeObject> {
    797 public:
    798     ~LargeObject()
    799     {
    800         s_destructorCalls++;
    801     }
    802     static LargeObject* create() { return new LargeObject(); }
    803     char get(size_t i) { return m_data[i]; }
    804     void set(size_t i, char c) { m_data[i] = c; }
    805     size_t length() { return s_length; }
    806     void trace(Visitor* visitor)
    807     {
    808         visitor->trace(m_intWrapper);
    809     }
    810     static int s_destructorCalls;
    811 
    812 private:
    813     static const size_t s_length = 1024*1024;
    814     LargeObject()
    815     {
    816         m_intWrapper = IntWrapper::create(23);
    817     }
    818     Member<IntWrapper> m_intWrapper;
    819     char m_data[s_length];
    820 };
    821 
    822 int LargeObject::s_destructorCalls = 0;
    823 
    824 class RefCountedAndGarbageCollected : public RefCountedGarbageCollected<RefCountedAndGarbageCollected> {
    825 public:
    826     static PassRefPtr<RefCountedAndGarbageCollected> create()
    827     {
    828         return adoptRef(new RefCountedAndGarbageCollected());
    829     }
    830 
    831     ~RefCountedAndGarbageCollected()
    832     {
    833         ++s_destructorCalls;
    834     }
    835 
    836     // These are here with their default implementations so you can break in
    837     // them in the debugger.
    838     void ref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::ref(); }
    839     void deref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::deref(); }
    840 
    841     void trace(Visitor*) { }
    842 
    843     static int s_destructorCalls;
    844 
    845 private:
    846     RefCountedAndGarbageCollected()
    847     {
    848     }
    849 };
    850 
    851 int RefCountedAndGarbageCollected::s_destructorCalls = 0;
    852 
    853 class RefCountedAndGarbageCollected2 : public HeapTestOtherSuperClass, public RefCountedGarbageCollected<RefCountedAndGarbageCollected2> {
    854 public:
    855     static RefCountedAndGarbageCollected2* create()
    856     {
    857         return adoptRefCountedGarbageCollected(new RefCountedAndGarbageCollected2());
    858     }
    859 
    860     ~RefCountedAndGarbageCollected2()
    861     {
    862         ++s_destructorCalls;
    863     }
    864 
    865     void trace(Visitor*) { }
    866 
    867     static int s_destructorCalls;
    868 
    869 private:
    870     RefCountedAndGarbageCollected2()
    871     {
    872     }
    873 };
    874 
    875 int RefCountedAndGarbageCollected2::s_destructorCalls = 0;
    876 
    877 #define DEFINE_VISITOR_METHODS(Type)                                       \
    878     virtual void mark(const Type* object, TraceCallback callback) OVERRIDE \
    879     {                                                                      \
    880         mark(object);                                                      \
    881     }                                                                      \
    882 
    883 class RefCountedGarbageCollectedVisitor : public CountingVisitor {
    884 public:
    885     RefCountedGarbageCollectedVisitor(int expected, void** objects)
    886         : m_count(0)
    887         , m_expectedCount(expected)
    888         , m_expectedObjects(objects)
    889     {
    890     }
    891 
    892     void mark(const void* ptr) { markNoTrace(ptr); }
    893 
    894     virtual void markNoTrace(const void* ptr)
    895     {
    896         if (!ptr)
    897             return;
    898         if (m_count < m_expectedCount)
    899             EXPECT_TRUE(expectedObject(ptr));
    900         else
    901             EXPECT_FALSE(expectedObject(ptr));
    902         m_count++;
    903     }
    904 
    905     virtual void mark(const void* ptr, TraceCallback) OVERRIDE
    906     {
    907         mark(ptr);
    908     }
    909 
    910     virtual void mark(HeapObjectHeader* header, TraceCallback callback) OVERRIDE
    911     {
    912         mark(header->payload());
    913     }
    914 
    915     virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) OVERRIDE
    916     {
    917         mark(header->payload());
    918     }
    919 
    920     bool validate() { return m_count >= m_expectedCount; }
    921     void reset() { m_count = 0; }
    922 
    923     FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
    924 
    925 private:
    926     bool expectedObject(const void* ptr)
    927     {
    928         for (int i = 0; i < m_expectedCount; i++) {
    929             if (m_expectedObjects[i] == ptr)
    930                 return true;
    931         }
    932         return false;
    933     }
    934 
    935     int m_count;
    936     int m_expectedCount;
    937     void** m_expectedObjects;
    938 };
    939 
    940 #undef DEFINE_VISITOR_METHODS
    941 
    942 class Weak : public Bar {
    943 public:
    944     static Weak* create(Bar* strong, Bar* weak)
    945     {
    946         return new Weak(strong, weak);
    947     }
    948 
    949     virtual void trace(Visitor* visitor) OVERRIDE
    950     {
    951         visitor->trace(m_strongBar);
    952         visitor->registerWeakMembers(this, zapWeakMembers);
    953     }
    954 
    955     static void zapWeakMembers(Visitor* visitor, void* self)
    956     {
    957         reinterpret_cast<Weak*>(self)->zapWeakMembers(visitor);
    958     }
    959 
    960     bool strongIsThere() { return !!m_strongBar; }
    961     bool weakIsThere() { return !!m_weakBar; }
    962 
    963 private:
    964     Weak(Bar* strongBar, Bar* weakBar)
    965         : Bar()
    966         , m_strongBar(strongBar)
    967         , m_weakBar(weakBar)
    968     {
    969     }
    970 
    971     void zapWeakMembers(Visitor* visitor)
    972     {
    973         if (!visitor->isAlive(m_weakBar))
    974             m_weakBar = 0;
    975     }
    976 
    977     Member<Bar> m_strongBar;
    978     Bar* m_weakBar;
    979 };
    980 
    981 class WithWeakMember : public Bar {
    982 public:
    983     static WithWeakMember* create(Bar* strong, Bar* weak)
    984     {
    985         return new WithWeakMember(strong, weak);
    986     }
    987 
    988     virtual void trace(Visitor* visitor) OVERRIDE
    989     {
    990         visitor->trace(m_strongBar);
    991         visitor->trace(m_weakBar);
    992     }
    993 
    994     bool strongIsThere() { return !!m_strongBar; }
    995     bool weakIsThere() { return !!m_weakBar; }
    996 
    997 private:
    998     WithWeakMember(Bar* strongBar, Bar* weakBar)
    999         : Bar()
   1000         , m_strongBar(strongBar)
   1001         , m_weakBar(weakBar)
   1002     {
   1003     }
   1004 
   1005     Member<Bar> m_strongBar;
   1006     WeakMember<Bar> m_weakBar;
   1007 };
   1008 
   1009 class Observable : public GarbageCollectedFinalized<Observable> {
   1010 public:
   1011     static Observable* create(Bar* bar) { return new Observable(bar);  }
   1012     ~Observable() { m_wasDestructed = true; }
   1013     void trace(Visitor* visitor) { visitor->trace(m_bar); }
   1014 
   1015     // willFinalize is called by FinalizationObserver. willFinalize can touch
   1016     // other on-heap objects.
   1017     void willFinalize()
   1018     {
   1019         EXPECT_FALSE(m_wasDestructed);
   1020         EXPECT_FALSE(m_bar->hasBeenFinalized());
   1021     }
   1022 
   1023 private:
   1024     explicit Observable(Bar* bar)
   1025         : m_bar(bar)
   1026         , m_wasDestructed(false)
   1027     {
   1028     }
   1029 
   1030     Member<Bar> m_bar;
   1031     bool m_wasDestructed;
   1032 };
   1033 
   1034 template <typename T> class FinalizationObserver : public GarbageCollected<FinalizationObserver<T> > {
   1035 public:
   1036     static FinalizationObserver* create(T* data) { return new FinalizationObserver(data); }
   1037     bool didCallWillFinalize() const { return m_didCallWillFinalize; }
   1038 
   1039     void trace(Visitor* visitor)
   1040     {
   1041         visitor->registerWeakMembers(this, zapWeakMembers);
   1042     }
   1043 
   1044 private:
   1045     FinalizationObserver(T* data)
   1046         : m_data(data)
   1047         , m_didCallWillFinalize(false)
   1048     {
   1049     }
   1050 
   1051     static void zapWeakMembers(Visitor* visitor, void* self)
   1052     {
   1053         FinalizationObserver* o = reinterpret_cast<FinalizationObserver*>(self);
   1054         if (o->m_data && !visitor->isAlive(o->m_data)) {
   1055             o->m_data->willFinalize();
   1056             o->m_data = nullptr;
   1057             o->m_didCallWillFinalize = true;
   1058         }
   1059     }
   1060 
   1061     WeakMember<T> m_data;
   1062     bool m_didCallWillFinalize;
   1063 };
   1064 
   1065 class FinalizationObserverWithHashMap {
   1066 public:
   1067     typedef HeapHashMap<WeakMember<Observable>, OwnPtr<FinalizationObserverWithHashMap> > ObserverMap;
   1068 
   1069     explicit FinalizationObserverWithHashMap(Observable& target) : m_target(target) { }
   1070     ~FinalizationObserverWithHashMap()
   1071     {
   1072         m_target.willFinalize();
   1073         s_didCallWillFinalize = true;
   1074     }
   1075 
   1076     static ObserverMap& observe(Observable& target)
   1077     {
   1078         ObserverMap& map = observers();
   1079         ObserverMap::AddResult result = map.add(&target, nullptr);
   1080         if (result.isNewEntry)
   1081             result.storedValue->value = adoptPtr(new FinalizationObserverWithHashMap(target));
   1082         else
   1083             ASSERT(result.storedValue->value);
   1084         return map;
   1085     }
   1086 
   1087     static bool s_didCallWillFinalize;
   1088 
   1089 private:
   1090     static ObserverMap& observers()
   1091     {
   1092         DEFINE_STATIC_LOCAL(Persistent<ObserverMap>, observerMap, ());
   1093         if (!observerMap)
   1094             observerMap = new ObserverMap();
   1095         return *observerMap;
   1096     }
   1097 
   1098     Observable& m_target;
   1099 };
   1100 
   1101 bool FinalizationObserverWithHashMap::s_didCallWillFinalize = false;
   1102 
   1103 class SuperClass;
   1104 
   1105 class PointsBack : public RefCountedWillBeGarbageCollectedFinalized<PointsBack> {
   1106 public:
   1107     static PassRefPtrWillBeRawPtr<PointsBack> create()
   1108     {
   1109         return adoptRefWillBeNoop(new PointsBack());
   1110     }
   1111 
   1112     ~PointsBack()
   1113     {
   1114         --s_aliveCount;
   1115     }
   1116 
   1117     void setBackPointer(SuperClass* backPointer)
   1118     {
   1119         m_backPointer = backPointer;
   1120     }
   1121 
   1122     SuperClass* backPointer() const { return m_backPointer; }
   1123 
   1124     void trace(Visitor* visitor)
   1125     {
   1126 #if ENABLE_OILPAN
   1127         visitor->trace(m_backPointer);
   1128 #endif
   1129     }
   1130 
   1131     static int s_aliveCount;
   1132 private:
   1133     PointsBack() : m_backPointer(nullptr)
   1134     {
   1135         ++s_aliveCount;
   1136     }
   1137 
   1138     RawPtrWillBeWeakMember<SuperClass> m_backPointer;
   1139 };
   1140 
   1141 int PointsBack::s_aliveCount = 0;
   1142 
   1143 class SuperClass : public RefCountedWillBeGarbageCollectedFinalized<SuperClass> {
   1144 public:
   1145     static PassRefPtrWillBeRawPtr<SuperClass> create(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
   1146     {
   1147         return adoptRefWillBeNoop(new SuperClass(pointsBack));
   1148     }
   1149 
   1150     virtual ~SuperClass()
   1151     {
   1152 #if !ENABLE_OILPAN
   1153         m_pointsBack->setBackPointer(0);
   1154 #endif
   1155         --s_aliveCount;
   1156     }
   1157 
   1158     void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* pointsBack, int superClassCount)
   1159     {
   1160         RefPtrWillBeRawPtr<SuperClass> target = targetPass;
   1161         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   1162         EXPECT_EQ(pointsBack, target->pointsBack());
   1163         EXPECT_EQ(superClassCount, SuperClass::s_aliveCount);
   1164     }
   1165 
   1166     virtual void trace(Visitor* visitor)
   1167     {
   1168 #if ENABLE_OILPAN
   1169         visitor->trace(m_pointsBack);
   1170 #endif
   1171     }
   1172 
   1173     PointsBack* pointsBack() const { return m_pointsBack.get(); }
   1174 
   1175     static int s_aliveCount;
   1176 protected:
   1177     explicit SuperClass(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
   1178         : m_pointsBack(pointsBack)
   1179     {
   1180         m_pointsBack->setBackPointer(this);
   1181         ++s_aliveCount;
   1182     }
   1183 
   1184 private:
   1185     RefPtrWillBeMember<PointsBack> m_pointsBack;
   1186 };
   1187 
   1188 int SuperClass::s_aliveCount = 0;
   1189 class SubData : public NoBaseWillBeGarbageCollectedFinalized<SubData> {
   1190 public:
   1191     SubData() { ++s_aliveCount; }
   1192     ~SubData() { --s_aliveCount; }
   1193 
   1194     void trace(Visitor*) { }
   1195 
   1196     static int s_aliveCount;
   1197 };
   1198 
   1199 int SubData::s_aliveCount = 0;
   1200 
   1201 class SubClass : public SuperClass {
   1202 public:
   1203     static PassRefPtrWillBeRawPtr<SubClass> create(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
   1204     {
   1205         return adoptRefWillBeNoop(new SubClass(pointsBack));
   1206     }
   1207 
   1208     virtual ~SubClass()
   1209     {
   1210         --s_aliveCount;
   1211     }
   1212 
   1213     virtual void trace(Visitor* visitor)
   1214     {
   1215 #if ENABLE_OILPAN
   1216         SuperClass::trace(visitor);
   1217         visitor->trace(m_data);
   1218 #endif
   1219     }
   1220 
   1221     static int s_aliveCount;
   1222 private:
   1223     explicit SubClass(PassRefPtrWillBeRawPtr<PointsBack> pointsBack)
   1224         : SuperClass(pointsBack)
   1225         , m_data(adoptPtrWillBeNoop(new SubData()))
   1226     {
   1227         ++s_aliveCount;
   1228     }
   1229 
   1230 private:
   1231     OwnPtrWillBeMember<SubData> m_data;
   1232 };
   1233 
   1234 int SubClass::s_aliveCount = 0;
   1235 
   1236 class TransitionRefCounted : public RefCountedWillBeRefCountedGarbageCollected<TransitionRefCounted> {
   1237 public:
   1238     static PassRefPtrWillBeRawPtr<TransitionRefCounted> create()
   1239     {
   1240         return adoptRefWillBeRefCountedGarbageCollected(new TransitionRefCounted());
   1241     }
   1242 
   1243     ~TransitionRefCounted()
   1244     {
   1245         --s_aliveCount;
   1246     }
   1247 
   1248     void trace(Visitor* visitor) { }
   1249 
   1250     static int s_aliveCount;
   1251 
   1252 private:
   1253     TransitionRefCounted()
   1254     {
   1255         ++s_aliveCount;
   1256     }
   1257 };
   1258 
   1259 int TransitionRefCounted::s_aliveCount = 0;
   1260 
   1261 class Mixin : public GarbageCollectedMixin {
   1262 public:
   1263     virtual void trace(Visitor* visitor) { }
   1264 
   1265     virtual char getPayload(int i) { return m_padding[i]; }
   1266 
   1267 protected:
   1268     int m_padding[8];
   1269 };
   1270 
   1271 class UseMixin : public SimpleObject, public Mixin {
   1272     USING_GARBAGE_COLLECTED_MIXIN(UseMixin)
   1273 public:
   1274     static UseMixin* create()
   1275     {
   1276         return new UseMixin();
   1277     }
   1278 
   1279     static int s_traceCount;
   1280     virtual void trace(Visitor* visitor)
   1281     {
   1282         SimpleObject::trace(visitor);
   1283         Mixin::trace(visitor);
   1284         ++s_traceCount;
   1285     }
   1286 
   1287 private:
   1288     UseMixin()
   1289     {
   1290         s_traceCount = 0;
   1291     }
   1292 };
   1293 
   1294 int UseMixin::s_traceCount = 0;
   1295 
   1296 class VectorObject {
   1297     ALLOW_ONLY_INLINE_ALLOCATION();
   1298 public:
   1299     VectorObject()
   1300     {
   1301         m_value = SimpleFinalizedObject::create();
   1302     }
   1303 
   1304     void trace(Visitor* visitor)
   1305     {
   1306         visitor->trace(m_value);
   1307     }
   1308 
   1309 private:
   1310     Member<SimpleFinalizedObject> m_value;
   1311 };
   1312 
   1313 class VectorObjectInheritedTrace : public VectorObject { };
   1314 
   1315 class VectorObjectNoTrace {
   1316     ALLOW_ONLY_INLINE_ALLOCATION();
   1317 public:
   1318     VectorObjectNoTrace()
   1319     {
   1320         m_value = SimpleFinalizedObject::create();
   1321     }
   1322 
   1323 private:
   1324     Member<SimpleFinalizedObject> m_value;
   1325 };
   1326 
   1327 class TerminatedArrayItem {
   1328     ALLOW_ONLY_INLINE_ALLOCATION();
   1329 public:
   1330     TerminatedArrayItem(IntWrapper* payload) : m_payload(payload), m_isLast(false) { }
   1331 
   1332     void trace(Visitor* visitor) { visitor->trace(m_payload); }
   1333 
   1334     bool isLastInArray() const { return m_isLast; }
   1335     void setLastInArray(bool value) { m_isLast = value; }
   1336 
   1337     IntWrapper* payload() const { return m_payload; }
   1338 
   1339 private:
   1340     Member<IntWrapper> m_payload;
   1341     bool m_isLast;
   1342 };
   1343 
   1344 } // WebCore namespace
   1345 
   1346 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::VectorObject);
   1347 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::VectorObjectInheritedTrace);
   1348 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::VectorObjectNoTrace);
   1349 
   1350 namespace WebCore {
   1351 
   1352 class OneKiloByteObject : public GarbageCollectedFinalized<OneKiloByteObject> {
   1353 public:
   1354     ~OneKiloByteObject() { s_destructorCalls++; }
   1355     char* data() { return m_data; }
   1356     void trace(Visitor* visitor) { }
   1357     static int s_destructorCalls;
   1358 
   1359 private:
   1360     static const size_t s_length = 1024;
   1361     char m_data[s_length];
   1362 };
   1363 
   1364 int OneKiloByteObject::s_destructorCalls = 0;
   1365 
   1366 class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> {
   1367 public:
   1368     static DynamicallySizedObject* create(size_t size)
   1369     {
   1370         void* slot = Heap::allocate<DynamicallySizedObject>(size);
   1371         return new (slot) DynamicallySizedObject();
   1372     }
   1373 
   1374     void* operator new(std::size_t, void* location)
   1375     {
   1376         return location;
   1377     }
   1378 
   1379     uint8_t get(int i)
   1380     {
   1381         return *(reinterpret_cast<uint8_t*>(this) + i);
   1382     }
   1383 
   1384     void trace(Visitor*) { }
   1385 
   1386 private:
   1387     DynamicallySizedObject() { }
   1388 };
   1389 
   1390 class FinalizationAllocator : public GarbageCollectedFinalized<FinalizationAllocator> {
   1391 public:
   1392     FinalizationAllocator(Persistent<IntWrapper>* wrapper)
   1393         : m_wrapper(wrapper)
   1394     {
   1395     }
   1396 
   1397     ~FinalizationAllocator()
   1398     {
   1399         for (int i = 0; i < 10; ++i)
   1400             *m_wrapper = IntWrapper::create(42);
   1401         for (int i = 0; i < 512; ++i)
   1402             new OneKiloByteObject();
   1403     }
   1404 
   1405     void trace(Visitor*) { }
   1406 
   1407 private:
   1408     Persistent<IntWrapper>* m_wrapper;
   1409 };
   1410 
   1411 TEST(HeapTest, Transition)
   1412 {
   1413     {
   1414         RefPtr<TransitionRefCounted> refCounted = TransitionRefCounted::create();
   1415         EXPECT_EQ(1, TransitionRefCounted::s_aliveCount);
   1416         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1417         EXPECT_EQ(1, TransitionRefCounted::s_aliveCount);
   1418     }
   1419     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1420     EXPECT_EQ(0, TransitionRefCounted::s_aliveCount);
   1421 
   1422     RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create();
   1423     RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create();
   1424     RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBack1);
   1425     RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2);
   1426     EXPECT_EQ(2, PointsBack::s_aliveCount);
   1427     EXPECT_EQ(2, SuperClass::s_aliveCount);
   1428     EXPECT_EQ(1, SubClass::s_aliveCount);
   1429     EXPECT_EQ(1, SubData::s_aliveCount);
   1430 
   1431     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1432     EXPECT_EQ(0, TransitionRefCounted::s_aliveCount);
   1433     EXPECT_EQ(2, PointsBack::s_aliveCount);
   1434     EXPECT_EQ(2, SuperClass::s_aliveCount);
   1435     EXPECT_EQ(1, SubClass::s_aliveCount);
   1436     EXPECT_EQ(1, SubData::s_aliveCount);
   1437 
   1438     superClass->doStuff(superClass.release(), pointsBack1.get(), 2);
   1439     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1440     EXPECT_EQ(2, PointsBack::s_aliveCount);
   1441     EXPECT_EQ(1, SuperClass::s_aliveCount);
   1442     EXPECT_EQ(1, SubClass::s_aliveCount);
   1443     EXPECT_EQ(1, SubData::s_aliveCount);
   1444     EXPECT_EQ(0, pointsBack1->backPointer());
   1445 
   1446     pointsBack1.release();
   1447     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1448     EXPECT_EQ(1, PointsBack::s_aliveCount);
   1449     EXPECT_EQ(1, SuperClass::s_aliveCount);
   1450     EXPECT_EQ(1, SubClass::s_aliveCount);
   1451     EXPECT_EQ(1, SubData::s_aliveCount);
   1452 
   1453     subClass->doStuff(subClass.release(), pointsBack2.get(), 1);
   1454     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1455     EXPECT_EQ(1, PointsBack::s_aliveCount);
   1456     EXPECT_EQ(0, SuperClass::s_aliveCount);
   1457     EXPECT_EQ(0, SubClass::s_aliveCount);
   1458     EXPECT_EQ(0, SubData::s_aliveCount);
   1459     EXPECT_EQ(0, pointsBack2->backPointer());
   1460 
   1461     pointsBack2.release();
   1462     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1463     EXPECT_EQ(0, PointsBack::s_aliveCount);
   1464     EXPECT_EQ(0, SuperClass::s_aliveCount);
   1465     EXPECT_EQ(0, SubClass::s_aliveCount);
   1466     EXPECT_EQ(0, SubData::s_aliveCount);
   1467 
   1468     EXPECT_TRUE(superClass == subClass);
   1469 }
   1470 
   1471 TEST(HeapTest, Threading)
   1472 {
   1473     ThreadedHeapTester::test();
   1474 }
   1475 
   1476 TEST(HeapTest, ThreadedWeakness)
   1477 {
   1478     ThreadedWeaknessTester::test();
   1479 }
   1480 
   1481 TEST(HeapTest, BasicFunctionality)
   1482 {
   1483     HeapStats heapStats;
   1484     clearOutOldGarbage(&heapStats);
   1485     {
   1486         size_t slack = 0;
   1487 
   1488         // When the test starts there may already have been leaked some memory
   1489         // on the heap, so we establish a base line.
   1490         size_t baseLevel = heapStats.totalObjectSpace();
   1491         bool testPagesAllocated = !baseLevel;
   1492         if (testPagesAllocated)
   1493             EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
   1494 
   1495         // This allocates objects on the general heap which should add a page of memory.
   1496         DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32);
   1497         slack += 4;
   1498         memset(alloc32, 40, 32);
   1499         DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64);
   1500         slack += 4;
   1501         memset(alloc64, 27, 64);
   1502 
   1503         size_t total = 96;
   1504 
   1505         getHeapStats(&heapStats);
   1506         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
   1507         if (testPagesAllocated)
   1508             EXPECT_EQ(heapStats.totalAllocatedSpace(), blinkPageSize);
   1509 
   1510         CheckWithSlack(alloc32 + 32 + sizeof(HeapObjectHeader), alloc64, slack);
   1511 
   1512         EXPECT_EQ(alloc32->get(0), 40);
   1513         EXPECT_EQ(alloc32->get(31), 40);
   1514         EXPECT_EQ(alloc64->get(0), 27);
   1515         EXPECT_EQ(alloc64->get(63), 27);
   1516 
   1517         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   1518 
   1519         EXPECT_EQ(alloc32->get(0), 40);
   1520         EXPECT_EQ(alloc32->get(31), 40);
   1521         EXPECT_EQ(alloc64->get(0), 27);
   1522         EXPECT_EQ(alloc64->get(63), 27);
   1523     }
   1524 
   1525     clearOutOldGarbage(&heapStats);
   1526     size_t total = 0;
   1527     size_t slack = 0;
   1528     size_t baseLevel = heapStats.totalObjectSpace();
   1529     bool testPagesAllocated = !baseLevel;
   1530     if (testPagesAllocated)
   1531         EXPECT_EQ(heapStats.totalAllocatedSpace(), 0ul);
   1532 
   1533     size_t big = 1008;
   1534     Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(big);
   1535     total += big;
   1536     slack += 4;
   1537 
   1538     size_t persistentCount = 0;
   1539     const size_t numPersistents = 100000;
   1540     Persistent<DynamicallySizedObject>* persistents[numPersistents];
   1541 
   1542     for (int i = 0; i < 1000; i++) {
   1543         size_t size = 128 + i * 8;
   1544         total += size;
   1545         persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(DynamicallySizedObject::create(size));
   1546         slack += 4;
   1547         getHeapStats(&heapStats);
   1548         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
   1549         if (testPagesAllocated)
   1550             EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
   1551     }
   1552 
   1553     {
   1554         DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32));
   1555         slack += 4;
   1556         memset(alloc32b, 40, 32);
   1557         DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64));
   1558         slack += 4;
   1559         memset(alloc64b, 27, 64);
   1560         EXPECT_TRUE(alloc32b != alloc64b);
   1561 
   1562         total += 96;
   1563         getHeapStats(&heapStats);
   1564         CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
   1565         if (testPagesAllocated)
   1566             EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
   1567     }
   1568 
   1569     clearOutOldGarbage(&heapStats);
   1570     total -= 96;
   1571     slack -= 8;
   1572     if (testPagesAllocated)
   1573         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
   1574 
   1575     DynamicallySizedObject* bigAreaRaw = bigArea;
   1576     // Clear the persistent, so that the big area will be garbage collected.
   1577     bigArea.release();
   1578     clearOutOldGarbage(&heapStats);
   1579 
   1580     total -= big;
   1581     slack -= 4;
   1582     getHeapStats(&heapStats);
   1583     CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
   1584     if (testPagesAllocated)
   1585         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
   1586 
   1587     // Endless loop unless we eventually get the memory back that we just freed.
   1588     while (true) {
   1589         Persistent<DynamicallySizedObject>* alloc = new Persistent<DynamicallySizedObject>(DynamicallySizedObject::create(big / 2));
   1590         slack += 4;
   1591         persistents[persistentCount++] = alloc;
   1592         EXPECT_LT(persistentCount, numPersistents);
   1593         total += big / 2;
   1594         if (bigAreaRaw == alloc->get())
   1595             break;
   1596     }
   1597 
   1598     getHeapStats(&heapStats);
   1599     CheckWithSlack(baseLevel + total, heapStats.totalObjectSpace(), slack);
   1600     if (testPagesAllocated)
   1601         EXPECT_EQ(0ul, heapStats.totalAllocatedSpace() & (blinkPageSize - 1));
   1602 
   1603     for (size_t i = 0; i < persistentCount; i++) {
   1604         delete persistents[i];
   1605         persistents[i] = 0;
   1606     }
   1607 
   1608     uint8_t* address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(0, 100));
   1609     for (int i = 0; i < 100; i++)
   1610         address[i] = i;
   1611     address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(address, 100000));
   1612     for (int i = 0; i < 100; i++)
   1613         EXPECT_EQ(address[i], i);
   1614     address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject>(address, 50));
   1615     for (int i = 0; i < 50; i++)
   1616         EXPECT_EQ(address[i], i);
   1617     // This should be equivalent to free(address).
   1618     EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObject>(address, 0)), 0ul);
   1619     // This should be equivalent to malloc(0).
   1620     EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObject>(0, 0)), 0ul);
   1621 }
   1622 
   1623 TEST(HeapTest, SimpleAllocation)
   1624 {
   1625     HeapStats initialHeapStats;
   1626     clearOutOldGarbage(&initialHeapStats);
   1627     EXPECT_EQ(0ul, initialHeapStats.totalObjectSpace());
   1628 
   1629     // Allocate an object in the heap.
   1630     HeapAllocatedArray* array = new HeapAllocatedArray();
   1631     HeapStats statsAfterAllocation;
   1632     getHeapStats(&statsAfterAllocation);
   1633     EXPECT_TRUE(statsAfterAllocation.totalObjectSpace() >= sizeof(HeapAllocatedArray));
   1634 
   1635     // Sanity check of the contents in the heap.
   1636     EXPECT_EQ(0, array->at(0));
   1637     EXPECT_EQ(42, array->at(42));
   1638     EXPECT_EQ(0, array->at(128));
   1639     EXPECT_EQ(999 % 128, array->at(999));
   1640 }
   1641 
   1642 TEST(HeapTest, SimplePersistent)
   1643 {
   1644     Persistent<TraceCounter> traceCounter = TraceCounter::create();
   1645     EXPECT_EQ(0, traceCounter->traceCount());
   1646 
   1647     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1648     EXPECT_EQ(1, traceCounter->traceCount());
   1649 
   1650     Persistent<ClassWithMember> classWithMember = ClassWithMember::create();
   1651     EXPECT_EQ(0, classWithMember->traceCount());
   1652 
   1653     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1654     EXPECT_EQ(1, classWithMember->traceCount());
   1655     EXPECT_EQ(2, traceCounter->traceCount());
   1656 }
   1657 
   1658 TEST(HeapTest, SimpleFinalization)
   1659 {
   1660     {
   1661         Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::create();
   1662         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
   1663         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1664         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
   1665     }
   1666 
   1667     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1668     EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls);
   1669 }
   1670 
   1671 TEST(HeapTest, Finalization)
   1672 {
   1673     {
   1674         HeapTestSubClass* t1 = HeapTestSubClass::create();
   1675         HeapTestSubClass* t2 = HeapTestSubClass::create();
   1676         HeapTestSuperClass* t3 = HeapTestSuperClass::create();
   1677         // FIXME(oilpan): Ignore unused variables.
   1678         (void)t1;
   1679         (void)t2;
   1680         (void)t3;
   1681     }
   1682     // Nothing is marked so the GC should free everything and call
   1683     // the finalizer on all three objects.
   1684     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1685     EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
   1686     EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
   1687     // Destructors not called again when GCing again.
   1688     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1689     EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls);
   1690     EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls);
   1691 }
   1692 
   1693 TEST(HeapTest, TypedHeapSanity)
   1694 {
   1695     // We use TraceCounter for allocating an object on the general heap.
   1696     Persistent<TraceCounter> generalHeapObject = TraceCounter::create();
   1697     Persistent<TestTypedHeapClass> typedHeapObject = TestTypedHeapClass::create();
   1698     EXPECT_NE(pageHeaderAddress(reinterpret_cast<Address>(generalHeapObject.get())),
   1699         pageHeaderAddress(reinterpret_cast<Address>(typedHeapObject.get())));
   1700 }
   1701 
   1702 TEST(HeapTest, NoAllocation)
   1703 {
   1704     EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
   1705     {
   1706         // Disallow allocation
   1707         NoAllocationScope<AnyThread> noAllocationScope;
   1708         EXPECT_FALSE(ThreadState::current()->isAllocationAllowed());
   1709     }
   1710     EXPECT_TRUE(ThreadState::current()->isAllocationAllowed());
   1711 }
   1712 
   1713 TEST(HeapTest, Members)
   1714 {
   1715     Bar::s_live = 0;
   1716     {
   1717         Persistent<Baz> h1;
   1718         Persistent<Baz> h2;
   1719         {
   1720             h1 = Baz::create(Bar::create());
   1721             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1722             EXPECT_EQ(1u, Bar::s_live);
   1723             h2 = Baz::create(Bar::create());
   1724             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1725             EXPECT_EQ(2u, Bar::s_live);
   1726         }
   1727         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1728         EXPECT_EQ(2u, Bar::s_live);
   1729         h1->clear();
   1730         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1731         EXPECT_EQ(1u, Bar::s_live);
   1732     }
   1733     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1734     EXPECT_EQ(0u, Bar::s_live);
   1735 }
   1736 
   1737 TEST(HeapTest, MarkTest)
   1738 {
   1739     {
   1740         Bar::s_live = 0;
   1741         Persistent<Bar> bar = Bar::create();
   1742         EXPECT_TRUE(ThreadState::current()->contains(bar));
   1743         EXPECT_EQ(1u, Bar::s_live);
   1744         {
   1745             Foo* foo = Foo::create(bar);
   1746             EXPECT_TRUE(ThreadState::current()->contains(foo));
   1747             EXPECT_EQ(2u, Bar::s_live);
   1748             EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Address>(bar.get()));
   1749             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   1750             EXPECT_TRUE(foo != bar); // To make sure foo is kept alive.
   1751             EXPECT_EQ(2u, Bar::s_live);
   1752         }
   1753         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1754         EXPECT_EQ(1u, Bar::s_live);
   1755     }
   1756     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1757     EXPECT_EQ(0u, Bar::s_live);
   1758 }
   1759 
   1760 TEST(HeapTest, DeepTest)
   1761 {
   1762     const unsigned depth = 100000;
   1763     Bar::s_live = 0;
   1764     {
   1765         Bar* bar = Bar::create();
   1766         EXPECT_TRUE(ThreadState::current()->contains(bar));
   1767         Foo* foo = Foo::create(bar);
   1768         EXPECT_TRUE(ThreadState::current()->contains(foo));
   1769         EXPECT_EQ(2u, Bar::s_live);
   1770         for (unsigned i = 0; i < depth; i++) {
   1771             Foo* foo2 = Foo::create(foo);
   1772             foo = foo2;
   1773             EXPECT_TRUE(ThreadState::current()->contains(foo));
   1774         }
   1775         EXPECT_EQ(depth + 2, Bar::s_live);
   1776         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   1777         EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive.
   1778         EXPECT_EQ(depth + 2, Bar::s_live);
   1779     }
   1780     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1781     EXPECT_EQ(0u, Bar::s_live);
   1782 }
   1783 
   1784 TEST(HeapTest, WideTest)
   1785 {
   1786     Bar::s_live = 0;
   1787     {
   1788         Bars* bars = Bars::create();
   1789         unsigned width = Bars::width;
   1790         EXPECT_EQ(width + 1, Bar::s_live);
   1791         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   1792         EXPECT_EQ(width + 1, Bar::s_live);
   1793         // Use bars here to make sure that it will be on the stack
   1794         // for the conservative stack scan to find.
   1795         EXPECT_EQ(width, bars->getWidth());
   1796     }
   1797     EXPECT_EQ(Bars::width + 1, Bar::s_live);
   1798     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1799     EXPECT_EQ(0u, Bar::s_live);
   1800 }
   1801 
   1802 TEST(HeapTest, HashMapOfMembers)
   1803 {
   1804     HeapStats initialHeapSize;
   1805     IntWrapper::s_destructorCalls = 0;
   1806 
   1807     clearOutOldGarbage(&initialHeapSize);
   1808     {
   1809         typedef HeapHashMap<
   1810             Member<IntWrapper>,
   1811             Member<IntWrapper>,
   1812             DefaultHash<Member<IntWrapper> >::Hash,
   1813             HashTraits<Member<IntWrapper> >,
   1814             HashTraits<Member<IntWrapper> > > HeapObjectIdentityMap;
   1815 
   1816         Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap();
   1817 
   1818         map->clear();
   1819         HeapStats afterSetWasCreated;
   1820         getHeapStats(&afterSetWasCreated);
   1821         EXPECT_TRUE(afterSetWasCreated.totalObjectSpace() > initialHeapSize.totalObjectSpace());
   1822 
   1823         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1824         HeapStats afterGC;
   1825         getHeapStats(&afterGC);
   1826         EXPECT_EQ(afterGC.totalObjectSpace(), afterSetWasCreated.totalObjectSpace());
   1827 
   1828         // If the additions below cause garbage collections, these
   1829         // pointers should be found by conservative stack scanning.
   1830         IntWrapper* one(IntWrapper::create(1));
   1831         IntWrapper* anotherOne(IntWrapper::create(1));
   1832 
   1833         map->add(one, one);
   1834 
   1835         HeapStats afterOneAdd;
   1836         getHeapStats(&afterOneAdd);
   1837         EXPECT_TRUE(afterOneAdd.totalObjectSpace() > afterGC.totalObjectSpace());
   1838 
   1839         HeapObjectIdentityMap::iterator it(map->begin());
   1840         HeapObjectIdentityMap::iterator it2(map->begin());
   1841         ++it;
   1842         ++it2;
   1843 
   1844         map->add(anotherOne, one);
   1845 
   1846         // The addition above can cause an allocation of a new
   1847         // backing store. We therefore garbage collect before
   1848         // taking the heap stats in order to get rid of the old
   1849         // backing store. We make sure to not use conservative
   1850         // stack scanning as that could find a pointer to the
   1851         // old backing.
   1852         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1853         HeapStats afterAddAndGC;
   1854         getHeapStats(&afterAddAndGC);
   1855         EXPECT_TRUE(afterAddAndGC.totalObjectSpace() >= afterOneAdd.totalObjectSpace());
   1856 
   1857         EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distinct.
   1858 
   1859         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1860         EXPECT_TRUE(map->contains(one));
   1861         EXPECT_TRUE(map->contains(anotherOne));
   1862 
   1863         IntWrapper* gotten(map->get(one));
   1864         EXPECT_EQ(gotten->value(), one->value());
   1865         EXPECT_EQ(gotten, one);
   1866 
   1867         HeapStats afterGC2;
   1868         getHeapStats(&afterGC2);
   1869         EXPECT_EQ(afterGC2.totalObjectSpace(), afterAddAndGC.totalObjectSpace());
   1870 
   1871         IntWrapper* dozen = 0;
   1872 
   1873         for (int i = 1; i < 1000; i++) { // 999 iterations.
   1874             IntWrapper* iWrapper(IntWrapper::create(i));
   1875             IntWrapper* iSquared(IntWrapper::create(i * i));
   1876             map->add(iWrapper, iSquared);
   1877             if (i == 12)
   1878                 dozen = iWrapper;
   1879         }
   1880         HeapStats afterAdding1000;
   1881         getHeapStats(&afterAdding1000);
   1882         EXPECT_TRUE(afterAdding1000.totalObjectSpace() > afterGC2.totalObjectSpace());
   1883 
   1884         IntWrapper* gross(map->get(dozen));
   1885         EXPECT_EQ(gross->value(), 144);
   1886 
   1887         // This should clear out junk created by all the adds.
   1888         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1889         HeapStats afterGC3;
   1890         getHeapStats(&afterGC3);
   1891         EXPECT_TRUE(afterGC3.totalObjectSpace() < afterAdding1000.totalObjectSpace());
   1892     }
   1893 
   1894     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1895     // The objects 'one', anotherOne, and the 999 other pairs.
   1896     EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
   1897     HeapStats afterGC4;
   1898     getHeapStats(&afterGC4);
   1899     EXPECT_EQ(afterGC4.totalObjectSpace(), initialHeapSize.totalObjectSpace());
   1900 }
   1901 
   1902 TEST(HeapTest, NestedAllocation)
   1903 {
   1904     HeapStats initialHeapSize;
   1905     clearOutOldGarbage(&initialHeapSize);
   1906     {
   1907         Persistent<ConstructorAllocation> constructorAllocation = ConstructorAllocation::create();
   1908     }
   1909     HeapStats afterFree;
   1910     clearOutOldGarbage(&afterFree);
   1911     EXPECT_TRUE(initialHeapSize == afterFree);
   1912 }
   1913 
   1914 TEST(HeapTest, LargeObjects)
   1915 {
   1916     HeapStats initialHeapSize;
   1917     clearOutOldGarbage(&initialHeapSize);
   1918     IntWrapper::s_destructorCalls = 0;
   1919     LargeObject::s_destructorCalls = 0;
   1920     {
   1921         int slack = 8; // LargeObject points to an IntWrapper that is also allocated.
   1922         Persistent<LargeObject> object = LargeObject::create();
   1923         EXPECT_TRUE(ThreadState::current()->contains(object));
   1924         EXPECT_TRUE(ThreadState::current()->contains(reinterpret_cast<char*>(object.get()) + sizeof(LargeObject) - 1));
   1925 #if ENABLE(GC_TRACING)
   1926         const GCInfo* info = ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()));
   1927         EXPECT_NE(reinterpret_cast<const GCInfo*>(0), info);
   1928         EXPECT_EQ(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) + sizeof(LargeObject) - 1));
   1929         EXPECT_NE(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) + sizeof(LargeObject)));
   1930         EXPECT_NE(info, ThreadState::current()->findGCInfo(reinterpret_cast<Address>(object.get()) - 1));
   1931 #endif
   1932         HeapStats afterAllocation;
   1933         clearOutOldGarbage(&afterAllocation);
   1934         {
   1935             object->set(0, 'a');
   1936             EXPECT_EQ('a', object->get(0));
   1937             object->set(object->length() - 1, 'b');
   1938             EXPECT_EQ('b', object->get(object->length() - 1));
   1939             size_t expectedObjectSpace = sizeof(LargeObject) + sizeof(IntWrapper);
   1940             size_t actualObjectSpace =
   1941                 afterAllocation.totalObjectSpace() - initialHeapSize.totalObjectSpace();
   1942             CheckWithSlack(expectedObjectSpace, actualObjectSpace, slack);
   1943             // There is probably space for the IntWrapper in a heap page without
   1944             // allocating extra pages. However, the IntWrapper allocation might cause
   1945             // the addition of a heap page.
   1946             size_t largeObjectAllocationSize =
   1947                 sizeof(LargeObject) + sizeof(LargeHeapObject<FinalizedHeapObjectHeader>) + sizeof(FinalizedHeapObjectHeader);
   1948             size_t allocatedSpaceLowerBound =
   1949                 initialHeapSize.totalAllocatedSpace() + largeObjectAllocationSize;
   1950             size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
   1951             EXPECT_LE(allocatedSpaceLowerBound, afterAllocation.totalAllocatedSpace());
   1952             EXPECT_LE(afterAllocation.totalAllocatedSpace(), allocatedSpaceUpperBound);
   1953             EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   1954             EXPECT_EQ(0, LargeObject::s_destructorCalls);
   1955             for (int i = 0; i < 10; i++)
   1956                 object = LargeObject::create();
   1957         }
   1958         HeapStats oneLargeObject;
   1959         clearOutOldGarbage(&oneLargeObject);
   1960         EXPECT_TRUE(oneLargeObject == afterAllocation);
   1961         EXPECT_EQ(10, IntWrapper::s_destructorCalls);
   1962         EXPECT_EQ(10, LargeObject::s_destructorCalls);
   1963     }
   1964     HeapStats backToInitial;
   1965     clearOutOldGarbage(&backToInitial);
   1966     EXPECT_TRUE(initialHeapSize == backToInitial);
   1967     EXPECT_EQ(11, IntWrapper::s_destructorCalls);
   1968     EXPECT_EQ(11, LargeObject::s_destructorCalls);
   1969     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   1970 }
   1971 
   1972 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
   1973 typedef std::pair<int, Member<IntWrapper> > PairUnwrappedWrapped;
   1974 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper> > PairWeakStrong;
   1975 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper> > PairStrongWeak;
   1976 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
   1977 typedef std::pair<int, WeakMember<IntWrapper> > PairUnwrappedWeak;
   1978 
   1979 class Container : public GarbageCollected<Container> {
   1980 public:
   1981     static Container* create() { return new Container(); }
   1982     HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > map;
   1983     HeapHashSet<Member<IntWrapper> > set;
   1984     HeapHashSet<Member<IntWrapper> > set2;
   1985     HeapHashCountedSet<Member<IntWrapper> > set3;
   1986     HeapVector<Member<IntWrapper>, 2> vector;
   1987     HeapVector<PairWrappedUnwrapped, 2> vectorWU;
   1988     HeapVector<PairUnwrappedWrapped, 2> vectorUW;
   1989     HeapDeque<Member<IntWrapper>, 0> deque;
   1990     HeapDeque<PairWrappedUnwrapped, 0> dequeWU;
   1991     HeapDeque<PairUnwrappedWrapped, 0> dequeUW;
   1992     void trace(Visitor* visitor)
   1993     {
   1994         visitor->trace(map);
   1995         visitor->trace(set);
   1996         visitor->trace(set2);
   1997         visitor->trace(set3);
   1998         visitor->trace(vector);
   1999         visitor->trace(vectorWU);
   2000         visitor->trace(vectorUW);
   2001         visitor->trace(deque);
   2002         visitor->trace(dequeWU);
   2003         visitor->trace(dequeUW);
   2004     }
   2005 };
   2006 
   2007 struct ShouldBeTraced {
   2008     explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { }
   2009     void trace(Visitor* visitor) { visitor->trace(m_wrapper); }
   2010     Member<IntWrapper> m_wrapper;
   2011 };
   2012 
   2013 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> {
   2014 public:
   2015     static OffHeapContainer* create() { return new OffHeapContainer(); }
   2016 
   2017     static const int iterations = 300;
   2018     static const int deadWrappers = 2700;
   2019 
   2020     OffHeapContainer()
   2021     {
   2022         for (int i = 0; i < iterations; i++) {
   2023             m_deque1.append(ShouldBeTraced(IntWrapper::create(i)));
   2024             m_vector1.append(ShouldBeTraced(IntWrapper::create(i)));
   2025             m_deque2.append(IntWrapper::create(i));
   2026             m_vector2.append(IntWrapper::create(i));
   2027             m_hashSet.add(IntWrapper::create(i));
   2028             m_hashMap.add(i + 103, IntWrapper::create(i));
   2029             m_listHashSet.add(IntWrapper::create(i));
   2030             m_linkedHashSet.add(IntWrapper::create(i));
   2031             m_ownedVector.append(adoptPtr(new ShouldBeTraced(IntWrapper::create(i))));
   2032         }
   2033 
   2034         Deque<ShouldBeTraced>::iterator d1Iterator(m_deque1.begin());
   2035         Vector<ShouldBeTraced>::iterator v1Iterator(m_vector1.begin());
   2036         Deque<Member<IntWrapper> >::iterator d2Iterator(m_deque2.begin());
   2037         Vector<Member<IntWrapper> >::iterator v2Iterator(m_vector2.begin());
   2038         HashSet<Member<IntWrapper> >::iterator setIterator(m_hashSet.begin());
   2039         HashMap<int, Member<IntWrapper> >::iterator mapIterator(m_hashMap.begin());
   2040         ListHashSet<Member<IntWrapper> >::iterator listSetIterator(m_listHashSet.begin());
   2041         LinkedHashSet<Member<IntWrapper> >::iterator linkedSetIterator(m_linkedHashSet.begin());
   2042         Vector<OwnPtr<ShouldBeTraced> >::iterator ownedVectorIterator(m_ownedVector.begin());
   2043 
   2044         for (int i = 0; i < iterations; i++) {
   2045             EXPECT_EQ(i, m_vector1[i].m_wrapper->value());
   2046             EXPECT_EQ(i, m_vector2[i]->value());
   2047             EXPECT_EQ(i, d1Iterator->m_wrapper->value());
   2048             EXPECT_EQ(i, v1Iterator->m_wrapper->value());
   2049             EXPECT_EQ(i, d2Iterator->get()->value());
   2050             EXPECT_EQ(i, v2Iterator->get()->value());
   2051             EXPECT_EQ(i, linkedSetIterator->get()->value());
   2052             EXPECT_EQ(i, listSetIterator->get()->value());
   2053             EXPECT_EQ(i, ownedVectorIterator->get()->m_wrapper->value());
   2054             int value = setIterator->get()->value();
   2055             EXPECT_LE(0, value);
   2056             EXPECT_GT(iterations, value);
   2057             value = mapIterator->value.get()->value();
   2058             EXPECT_LE(0, value);
   2059             EXPECT_GT(iterations, value);
   2060             ++d1Iterator;
   2061             ++v1Iterator;
   2062             ++d2Iterator;
   2063             ++v2Iterator;
   2064             ++setIterator;
   2065             ++mapIterator;
   2066             ++listSetIterator;
   2067             ++linkedSetIterator;
   2068             ++ownedVectorIterator;
   2069         }
   2070         EXPECT_EQ(d1Iterator, m_deque1.end());
   2071         EXPECT_EQ(v1Iterator, m_vector1.end());
   2072         EXPECT_EQ(d2Iterator, m_deque2.end());
   2073         EXPECT_EQ(v2Iterator, m_vector2.end());
   2074         EXPECT_EQ(setIterator, m_hashSet.end());
   2075         EXPECT_EQ(mapIterator, m_hashMap.end());
   2076         EXPECT_EQ(listSetIterator, m_listHashSet.end());
   2077         EXPECT_EQ(linkedSetIterator, m_linkedHashSet.end());
   2078         EXPECT_EQ(ownedVectorIterator, m_ownedVector.end());
   2079     }
   2080 
   2081     void trace(Visitor* visitor)
   2082     {
   2083         visitor->trace(m_deque1);
   2084         visitor->trace(m_vector1);
   2085         visitor->trace(m_deque2);
   2086         visitor->trace(m_vector2);
   2087         visitor->trace(m_hashSet);
   2088         visitor->trace(m_hashMap);
   2089         visitor->trace(m_listHashSet);
   2090         visitor->trace(m_linkedHashSet);
   2091         visitor->trace(m_listHashSet);
   2092         visitor->trace(m_ownedVector);
   2093     }
   2094 
   2095     Deque<ShouldBeTraced> m_deque1;
   2096     Vector<ShouldBeTraced> m_vector1;
   2097     Deque<Member<IntWrapper> > m_deque2;
   2098     Vector<Member<IntWrapper> > m_vector2;
   2099     HashSet<Member<IntWrapper> > m_hashSet;
   2100     HashMap<int, Member<IntWrapper> > m_hashMap;
   2101     ListHashSet<Member<IntWrapper> > m_listHashSet;
   2102     LinkedHashSet<Member<IntWrapper> > m_linkedHashSet;
   2103     Vector<OwnPtr<ShouldBeTraced> > m_ownedVector;
   2104 };
   2105 
   2106 const int OffHeapContainer::iterations;
   2107 const int OffHeapContainer::deadWrappers;
   2108 
   2109 // These class definitions test compile-time asserts with transition
   2110 // types. They are therefore unused in test code and just need to
   2111 // compile. This is intentional; do not delete the A and B classes below.
   2112 class A : public WillBeGarbageCollectedMixin {
   2113 };
   2114 
   2115 class B : public NoBaseWillBeGarbageCollected<B>, public A {
   2116     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B);
   2117 public:
   2118     void trace(Visitor*) { }
   2119 };
   2120 
   2121 TEST(HeapTest, HeapVectorFilledWithValue)
   2122 {
   2123     IntWrapper* val = IntWrapper::create(1);
   2124     HeapVector<Member<IntWrapper> > vector(10, val);
   2125     EXPECT_EQ(10u, vector.size());
   2126     for (size_t i = 0; i < vector.size(); i++)
   2127         EXPECT_EQ(val, vector[i]);
   2128 }
   2129 
   2130 TEST(HeapTest, HeapVectorWithInlineCapacity)
   2131 {
   2132     IntWrapper* one = IntWrapper::create(1);
   2133     IntWrapper* two = IntWrapper::create(2);
   2134     IntWrapper* three = IntWrapper::create(3);
   2135     IntWrapper* four = IntWrapper::create(4);
   2136     IntWrapper* five = IntWrapper::create(5);
   2137     IntWrapper* six = IntWrapper::create(6);
   2138     {
   2139         HeapVector<Member<IntWrapper>, 2> vector;
   2140         vector.append(one);
   2141         vector.append(two);
   2142         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2143         EXPECT_TRUE(vector.contains(one));
   2144         EXPECT_TRUE(vector.contains(two));
   2145 
   2146         vector.append(three);
   2147         vector.append(four);
   2148         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2149         EXPECT_TRUE(vector.contains(one));
   2150         EXPECT_TRUE(vector.contains(two));
   2151         EXPECT_TRUE(vector.contains(three));
   2152         EXPECT_TRUE(vector.contains(four));
   2153 
   2154         vector.shrink(1);
   2155         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2156         EXPECT_TRUE(vector.contains(one));
   2157         EXPECT_FALSE(vector.contains(two));
   2158         EXPECT_FALSE(vector.contains(three));
   2159         EXPECT_FALSE(vector.contains(four));
   2160     }
   2161     {
   2162         HeapVector<Member<IntWrapper>, 2> vector1;
   2163         HeapVector<Member<IntWrapper>, 2> vector2;
   2164 
   2165         vector1.append(one);
   2166         vector2.append(two);
   2167         vector1.swap(vector2);
   2168         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2169         EXPECT_TRUE(vector1.contains(two));
   2170         EXPECT_TRUE(vector2.contains(one));
   2171     }
   2172     {
   2173         HeapVector<Member<IntWrapper>, 2> vector1;
   2174         HeapVector<Member<IntWrapper>, 2> vector2;
   2175 
   2176         vector1.append(one);
   2177         vector1.append(two);
   2178         vector2.append(three);
   2179         vector2.append(four);
   2180         vector2.append(five);
   2181         vector2.append(six);
   2182         vector1.swap(vector2);
   2183         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2184         EXPECT_TRUE(vector1.contains(three));
   2185         EXPECT_TRUE(vector1.contains(four));
   2186         EXPECT_TRUE(vector1.contains(five));
   2187         EXPECT_TRUE(vector1.contains(six));
   2188         EXPECT_TRUE(vector2.contains(one));
   2189         EXPECT_TRUE(vector2.contains(two));
   2190     }
   2191 }
   2192 
   2193 template<typename T, size_t inlineCapacity, typename U>
   2194 bool dequeContains(HeapDeque<T, inlineCapacity>& deque, U u)
   2195 {
   2196     typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
   2197     for (iterator it = deque.begin(); it != deque.end(); ++it) {
   2198         if (*it == u)
   2199             return true;
   2200     }
   2201     return false;
   2202 }
   2203 
   2204 TEST(HeapTest, HeapCollectionTypes)
   2205 {
   2206     HeapStats initialHeapSize;
   2207     IntWrapper::s_destructorCalls = 0;
   2208 
   2209     typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper> > MemberMember;
   2210     typedef HeapHashMap<Member<IntWrapper>, int> MemberPrimitive;
   2211     typedef HeapHashMap<int, Member<IntWrapper> > PrimitiveMember;
   2212 
   2213     typedef HeapHashSet<Member<IntWrapper> > MemberSet;
   2214     typedef HeapHashCountedSet<Member<IntWrapper> > MemberCountedSet;
   2215 
   2216     typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
   2217     typedef HeapDeque<Member<IntWrapper>, 0> MemberDeque;
   2218 
   2219     typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
   2220     typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
   2221     typedef HeapDeque<PairWrappedUnwrapped, 0> DequeWU;
   2222     typedef HeapDeque<PairUnwrappedWrapped, 0> DequeUW;
   2223 
   2224     Persistent<MemberMember> memberMember = new MemberMember();
   2225     Persistent<MemberMember> memberMember2 = new MemberMember();
   2226     Persistent<MemberMember> memberMember3 = new MemberMember();
   2227     Persistent<MemberPrimitive> memberPrimitive = new MemberPrimitive();
   2228     Persistent<PrimitiveMember> primitiveMember = new PrimitiveMember();
   2229     Persistent<MemberSet> set = new MemberSet();
   2230     Persistent<MemberSet> set2 = new MemberSet();
   2231     Persistent<MemberCountedSet> set3 = new MemberCountedSet();
   2232     Persistent<MemberVector> vector = new MemberVector();
   2233     Persistent<MemberVector> vector2 = new MemberVector();
   2234     Persistent<VectorWU> vectorWU = new VectorWU();
   2235     Persistent<VectorWU> vectorWU2 = new VectorWU();
   2236     Persistent<VectorUW> vectorUW = new VectorUW();
   2237     Persistent<VectorUW> vectorUW2 = new VectorUW();
   2238     Persistent<MemberDeque> deque = new MemberDeque();
   2239     Persistent<MemberDeque> deque2 = new MemberDeque();
   2240     Persistent<DequeWU> dequeWU = new DequeWU();
   2241     Persistent<DequeWU> dequeWU2 = new DequeWU();
   2242     Persistent<DequeUW> dequeUW = new DequeUW();
   2243     Persistent<DequeUW> dequeUW2 = new DequeUW();
   2244     Persistent<Container> container = Container::create();
   2245 
   2246     clearOutOldGarbage(&initialHeapSize);
   2247     {
   2248         Persistent<IntWrapper> one(IntWrapper::create(1));
   2249         Persistent<IntWrapper> two(IntWrapper::create(2));
   2250         Persistent<IntWrapper> oneB(IntWrapper::create(1));
   2251         Persistent<IntWrapper> twoB(IntWrapper::create(2));
   2252         Persistent<IntWrapper> oneC(IntWrapper::create(1));
   2253         Persistent<IntWrapper> oneD(IntWrapper::create(1));
   2254         Persistent<IntWrapper> oneE(IntWrapper::create(1));
   2255         Persistent<IntWrapper> oneF(IntWrapper::create(1));
   2256         {
   2257             IntWrapper* threeB(IntWrapper::create(3));
   2258             IntWrapper* threeC(IntWrapper::create(3));
   2259             IntWrapper* threeD(IntWrapper::create(3));
   2260             IntWrapper* threeE(IntWrapper::create(3));
   2261             IntWrapper* threeF(IntWrapper::create(3));
   2262             IntWrapper* three(IntWrapper::create(3));
   2263             IntWrapper* fourB(IntWrapper::create(4));
   2264             IntWrapper* fourC(IntWrapper::create(4));
   2265             IntWrapper* fourD(IntWrapper::create(4));
   2266             IntWrapper* fourE(IntWrapper::create(4));
   2267             IntWrapper* fourF(IntWrapper::create(4));
   2268             IntWrapper* four(IntWrapper::create(4));
   2269             IntWrapper* fiveC(IntWrapper::create(5));
   2270             IntWrapper* fiveD(IntWrapper::create(5));
   2271             IntWrapper* fiveE(IntWrapper::create(5));
   2272             IntWrapper* fiveF(IntWrapper::create(5));
   2273 
   2274             // Member Collections.
   2275             memberMember2->add(one, two);
   2276             memberMember2->add(two, three);
   2277             memberMember2->add(three, four);
   2278             memberMember2->add(four, one);
   2279             primitiveMember->add(1, two);
   2280             primitiveMember->add(2, three);
   2281             primitiveMember->add(3, four);
   2282             primitiveMember->add(4, one);
   2283             memberPrimitive->add(one, 2);
   2284             memberPrimitive->add(two, 3);
   2285             memberPrimitive->add(three, 4);
   2286             memberPrimitive->add(four, 1);
   2287             set2->add(one);
   2288             set2->add(two);
   2289             set2->add(three);
   2290             set2->add(four);
   2291             set->add(oneB);
   2292             set3->add(oneB);
   2293             set3->add(oneB);
   2294             vector->append(oneB);
   2295             deque->append(oneB);
   2296             vector2->append(threeB);
   2297             vector2->append(fourB);
   2298             deque2->append(threeE);
   2299             deque2->append(fourE);
   2300             vectorWU->append(PairWrappedUnwrapped(&*oneC, 42));
   2301             dequeWU->append(PairWrappedUnwrapped(&*oneE, 42));
   2302             vectorWU2->append(PairWrappedUnwrapped(&*threeC, 43));
   2303             vectorWU2->append(PairWrappedUnwrapped(&*fourC, 44));
   2304             vectorWU2->append(PairWrappedUnwrapped(&*fiveC, 45));
   2305             dequeWU2->append(PairWrappedUnwrapped(&*threeE, 43));
   2306             dequeWU2->append(PairWrappedUnwrapped(&*fourE, 44));
   2307             dequeWU2->append(PairWrappedUnwrapped(&*fiveE, 45));
   2308             vectorUW->append(PairUnwrappedWrapped(1, &*oneD));
   2309             vectorUW2->append(PairUnwrappedWrapped(103, &*threeD));
   2310             vectorUW2->append(PairUnwrappedWrapped(104, &*fourD));
   2311             vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD));
   2312             dequeUW->append(PairUnwrappedWrapped(1, &*oneF));
   2313             dequeUW2->append(PairUnwrappedWrapped(103, &*threeF));
   2314             dequeUW2->append(PairUnwrappedWrapped(104, &*fourF));
   2315             dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF));
   2316 
   2317             EXPECT_TRUE(dequeContains(*deque, oneB));
   2318 
   2319             // Collect garbage. This should change nothing since we are keeping
   2320             // alive the IntWrapper objects with on-stack pointers.
   2321             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   2322 
   2323             EXPECT_TRUE(dequeContains(*deque, oneB));
   2324 
   2325             EXPECT_EQ(0u, memberMember->size());
   2326             EXPECT_EQ(4u, memberMember2->size());
   2327             EXPECT_EQ(4u, primitiveMember->size());
   2328             EXPECT_EQ(4u, memberPrimitive->size());
   2329             EXPECT_EQ(1u, set->size());
   2330             EXPECT_EQ(4u, set2->size());
   2331             EXPECT_EQ(1u, set3->size());
   2332             EXPECT_EQ(1u, vector->size());
   2333             EXPECT_EQ(2u, vector2->size());
   2334             EXPECT_EQ(1u, vectorWU->size());
   2335             EXPECT_EQ(3u, vectorWU2->size());
   2336             EXPECT_EQ(1u, vectorUW->size());
   2337             EXPECT_EQ(3u, vectorUW2->size());
   2338             EXPECT_EQ(1u, deque->size());
   2339             EXPECT_EQ(2u, deque2->size());
   2340             EXPECT_EQ(1u, dequeWU->size());
   2341             EXPECT_EQ(3u, dequeWU2->size());
   2342             EXPECT_EQ(1u, dequeUW->size());
   2343             EXPECT_EQ(3u, dequeUW2->size());
   2344 
   2345             MemberVector& cvec = container->vector;
   2346             cvec.swap(*vector.get());
   2347             vector2->swap(cvec);
   2348             vector->swap(cvec);
   2349 
   2350             VectorWU& cvecWU = container->vectorWU;
   2351             cvecWU.swap(*vectorWU.get());
   2352             vectorWU2->swap(cvecWU);
   2353             vectorWU->swap(cvecWU);
   2354 
   2355             VectorUW& cvecUW = container->vectorUW;
   2356             cvecUW.swap(*vectorUW.get());
   2357             vectorUW2->swap(cvecUW);
   2358             vectorUW->swap(cvecUW);
   2359 
   2360             MemberDeque& cDeque = container->deque;
   2361             cDeque.swap(*deque.get());
   2362             deque2->swap(cDeque);
   2363             deque->swap(cDeque);
   2364 
   2365             DequeWU& cDequeWU = container->dequeWU;
   2366             cDequeWU.swap(*dequeWU.get());
   2367             dequeWU2->swap(cDequeWU);
   2368             dequeWU->swap(cDequeWU);
   2369 
   2370             DequeUW& cDequeUW = container->dequeUW;
   2371             cDequeUW.swap(*dequeUW.get());
   2372             dequeUW2->swap(cDequeUW);
   2373             dequeUW->swap(cDequeUW);
   2374 
   2375             // Swap set and set2 in a roundabout way.
   2376             MemberSet& cset1 = container->set;
   2377             MemberSet& cset2 = container->set2;
   2378             set->swap(cset1);
   2379             set2->swap(cset2);
   2380             set->swap(cset2);
   2381             cset1.swap(cset2);
   2382             cset2.swap(set2);
   2383 
   2384             MemberCountedSet& cCountedSet = container->set3;
   2385             set3->swap(cCountedSet);
   2386             EXPECT_EQ(0u, set3->size());
   2387             set3->swap(cCountedSet);
   2388 
   2389             // Triple swap.
   2390             container->map.swap(memberMember2);
   2391             MemberMember& containedMap = container->map;
   2392             memberMember3->swap(containedMap);
   2393             memberMember3->swap(memberMember);
   2394 
   2395             EXPECT_TRUE(memberMember->get(one) == two);
   2396             EXPECT_TRUE(memberMember->get(two) == three);
   2397             EXPECT_TRUE(memberMember->get(three) == four);
   2398             EXPECT_TRUE(memberMember->get(four) == one);
   2399             EXPECT_TRUE(primitiveMember->get(1) == two);
   2400             EXPECT_TRUE(primitiveMember->get(2) == three);
   2401             EXPECT_TRUE(primitiveMember->get(3) == four);
   2402             EXPECT_TRUE(primitiveMember->get(4) == one);
   2403             EXPECT_EQ(1, memberPrimitive->get(four));
   2404             EXPECT_EQ(2, memberPrimitive->get(one));
   2405             EXPECT_EQ(3, memberPrimitive->get(two));
   2406             EXPECT_EQ(4, memberPrimitive->get(three));
   2407             EXPECT_TRUE(set->contains(one));
   2408             EXPECT_TRUE(set->contains(two));
   2409             EXPECT_TRUE(set->contains(three));
   2410             EXPECT_TRUE(set->contains(four));
   2411             EXPECT_TRUE(set2->contains(oneB));
   2412             EXPECT_TRUE(set3->contains(oneB));
   2413             EXPECT_TRUE(vector->contains(threeB));
   2414             EXPECT_TRUE(vector->contains(fourB));
   2415             EXPECT_TRUE(dequeContains(*deque, threeE));
   2416             EXPECT_TRUE(dequeContains(*deque, fourE));
   2417             EXPECT_TRUE(vector2->contains(oneB));
   2418             EXPECT_FALSE(vector2->contains(threeB));
   2419             EXPECT_TRUE(dequeContains(*deque2, oneB));
   2420             EXPECT_FALSE(dequeContains(*deque2, threeE));
   2421             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*threeC, 43)));
   2422             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fourC, 44)));
   2423             EXPECT_TRUE(vectorWU->contains(PairWrappedUnwrapped(&*fiveC, 45)));
   2424             EXPECT_TRUE(vectorWU2->contains(PairWrappedUnwrapped(&*oneC, 42)));
   2425             EXPECT_FALSE(vectorWU2->contains(PairWrappedUnwrapped(&*threeC, 43)));
   2426             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(103, &*threeD)));
   2427             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(104, &*fourD)));
   2428             EXPECT_TRUE(vectorUW->contains(PairUnwrappedWrapped(105, &*fiveD)));
   2429             EXPECT_TRUE(vectorUW2->contains(PairUnwrappedWrapped(1, &*oneD)));
   2430             EXPECT_FALSE(vectorUW2->contains(PairUnwrappedWrapped(103, &*threeD)));
   2431             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*threeE, 43)));
   2432             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fourE, 44)));
   2433             EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45)));
   2434             EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42)));
   2435             EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE, 43)));
   2436             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*threeF)));
   2437             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*fourF)));
   2438             EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*fiveF)));
   2439             EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)));
   2440             EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*threeF)));
   2441         }
   2442 
   2443         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2444 
   2445         EXPECT_EQ(4u, memberMember->size());
   2446         EXPECT_EQ(0u, memberMember2->size());
   2447         EXPECT_EQ(4u, primitiveMember->size());
   2448         EXPECT_EQ(4u, memberPrimitive->size());
   2449         EXPECT_EQ(4u, set->size());
   2450         EXPECT_EQ(1u, set2->size());
   2451         EXPECT_EQ(1u, set3->size());
   2452         EXPECT_EQ(2u, vector->size());
   2453         EXPECT_EQ(1u, vector2->size());
   2454         EXPECT_EQ(3u, vectorUW->size());
   2455         EXPECT_EQ(1u, vector2->size());
   2456         EXPECT_EQ(2u, deque->size());
   2457         EXPECT_EQ(1u, deque2->size());
   2458         EXPECT_EQ(3u, dequeUW->size());
   2459         EXPECT_EQ(1u, deque2->size());
   2460 
   2461         EXPECT_TRUE(memberMember->get(one) == two);
   2462         EXPECT_TRUE(primitiveMember->get(1) == two);
   2463         EXPECT_TRUE(primitiveMember->get(4) == one);
   2464         EXPECT_EQ(2, memberPrimitive->get(one));
   2465         EXPECT_EQ(3, memberPrimitive->get(two));
   2466         EXPECT_TRUE(set->contains(one));
   2467         EXPECT_TRUE(set->contains(two));
   2468         EXPECT_FALSE(set->contains(oneB));
   2469         EXPECT_TRUE(set2->contains(oneB));
   2470         EXPECT_TRUE(set3->contains(oneB));
   2471         EXPECT_EQ(2u, set3->find(oneB)->value);
   2472         EXPECT_EQ(3, vector->at(0)->value());
   2473         EXPECT_EQ(4, vector->at(1)->value());
   2474         EXPECT_EQ(3, deque->begin()->get()->value());
   2475     }
   2476 
   2477     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2478     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2479 
   2480     EXPECT_EQ(4u, memberMember->size());
   2481     EXPECT_EQ(4u, primitiveMember->size());
   2482     EXPECT_EQ(4u, memberPrimitive->size());
   2483     EXPECT_EQ(4u, set->size());
   2484     EXPECT_EQ(1u, set2->size());
   2485     EXPECT_EQ(2u, vector->size());
   2486     EXPECT_EQ(1u, vector2->size());
   2487     EXPECT_EQ(3u, vectorWU->size());
   2488     EXPECT_EQ(1u, vectorWU2->size());
   2489     EXPECT_EQ(3u, vectorUW->size());
   2490     EXPECT_EQ(1u, vectorUW2->size());
   2491     EXPECT_EQ(2u, deque->size());
   2492     EXPECT_EQ(1u, deque2->size());
   2493     EXPECT_EQ(3u, dequeWU->size());
   2494     EXPECT_EQ(1u, dequeWU2->size());
   2495     EXPECT_EQ(3u, dequeUW->size());
   2496     EXPECT_EQ(1u, dequeUW2->size());
   2497 }
   2498 
   2499 template<typename T>
   2500 void MapIteratorCheck(T& it, const T& end, int expected)
   2501 {
   2502     int found = 0;
   2503     while (it != end) {
   2504         found++;
   2505         int key = it->key->value();
   2506         int value = it->value->value();
   2507         EXPECT_TRUE(key >= 0 && key < 1100);
   2508         EXPECT_TRUE(value >= 0 && value < 1100);
   2509         ++it;
   2510     }
   2511     EXPECT_EQ(expected, found);
   2512 }
   2513 
   2514 template<typename T>
   2515 void SetIteratorCheck(T& it, const T& end, int expected)
   2516 {
   2517     int found = 0;
   2518     while (it != end) {
   2519         found++;
   2520         int value = (*it)->value();
   2521         EXPECT_TRUE(value >= 0 && value < 1100);
   2522         ++it;
   2523     }
   2524     EXPECT_EQ(expected, found);
   2525 }
   2526 
   2527 TEST(HeapTest, HeapWeakCollectionSimple)
   2528 {
   2529     HeapStats initialHeapStats;
   2530     clearOutOldGarbage(&initialHeapStats);
   2531     IntWrapper::s_destructorCalls = 0;
   2532 
   2533     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
   2534 
   2535     typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
   2536     typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
   2537     typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
   2538     typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
   2539     typedef HeapHashCountedSet<WeakMember<IntWrapper> > WeakCountedSet;
   2540 
   2541     Persistent<WeakStrong> weakStrong = new WeakStrong();
   2542     Persistent<StrongWeak> strongWeak = new StrongWeak();
   2543     Persistent<WeakWeak> weakWeak = new WeakWeak();
   2544     Persistent<WeakSet> weakSet = new WeakSet();
   2545     Persistent<WeakCountedSet> weakCountedSet = new WeakCountedSet();
   2546 
   2547     Persistent<IntWrapper> two = IntWrapper::create(2);
   2548 
   2549     keepNumbersAlive.append(IntWrapper::create(103));
   2550     keepNumbersAlive.append(IntWrapper::create(10));
   2551 
   2552     {
   2553         weakStrong->add(IntWrapper::create(1), two);
   2554         strongWeak->add(two, IntWrapper::create(1));
   2555         weakWeak->add(two, IntWrapper::create(42));
   2556         weakWeak->add(IntWrapper::create(42), two);
   2557         weakSet->add(IntWrapper::create(0));
   2558         weakSet->add(two);
   2559         weakSet->add(keepNumbersAlive[0]);
   2560         weakSet->add(keepNumbersAlive[1]);
   2561         weakCountedSet->add(IntWrapper::create(0));
   2562         weakCountedSet->add(two);
   2563         weakCountedSet->add(two);
   2564         weakCountedSet->add(two);
   2565         weakCountedSet->add(keepNumbersAlive[0]);
   2566         weakCountedSet->add(keepNumbersAlive[1]);
   2567         EXPECT_EQ(1u, weakStrong->size());
   2568         EXPECT_EQ(1u, strongWeak->size());
   2569         EXPECT_EQ(2u, weakWeak->size());
   2570         EXPECT_EQ(4u, weakSet->size());
   2571         EXPECT_EQ(4u, weakCountedSet->size());
   2572         EXPECT_EQ(3u, weakCountedSet->find(two)->value);
   2573         weakCountedSet->remove(two);
   2574         EXPECT_EQ(2u, weakCountedSet->find(two)->value);
   2575     }
   2576 
   2577     keepNumbersAlive[0] = nullptr;
   2578 
   2579     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2580 
   2581     EXPECT_EQ(0u, weakStrong->size());
   2582     EXPECT_EQ(0u, strongWeak->size());
   2583     EXPECT_EQ(0u, weakWeak->size());
   2584     EXPECT_EQ(2u, weakSet->size());
   2585     EXPECT_EQ(2u, weakCountedSet->size());
   2586 }
   2587 
   2588 template<typename Set>
   2589 void orderedSetHelper(bool strong)
   2590 {
   2591     HeapStats initialHeapStats;
   2592     clearOutOldGarbage(&initialHeapStats);
   2593     IntWrapper::s_destructorCalls = 0;
   2594 
   2595     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
   2596 
   2597     Persistent<Set> set1 = new Set();
   2598     Persistent<Set> set2 = new Set();
   2599 
   2600     const Set& constSet = *set1.get();
   2601 
   2602     keepNumbersAlive.append(IntWrapper::create(2));
   2603     keepNumbersAlive.append(IntWrapper::create(103));
   2604     keepNumbersAlive.append(IntWrapper::create(10));
   2605 
   2606     set1->add(IntWrapper::create(0));
   2607     set1->add(keepNumbersAlive[0]);
   2608     set1->add(keepNumbersAlive[1]);
   2609     set1->add(keepNumbersAlive[2]);
   2610 
   2611     set2->clear();
   2612     set2->add(IntWrapper::create(42));
   2613     set2->clear();
   2614 
   2615     EXPECT_EQ(4u, set1->size());
   2616     typename Set::iterator it(set1->begin());
   2617     typename Set::reverse_iterator reverse(set1->rbegin());
   2618     typename Set::const_iterator cit(constSet.begin());
   2619     typename Set::const_reverse_iterator creverse(constSet.rbegin());
   2620 
   2621     EXPECT_EQ(0, (*it)->value());
   2622     EXPECT_EQ(0, (*cit)->value());
   2623     ++it;
   2624     ++cit;
   2625     EXPECT_EQ(2, (*it)->value());
   2626     EXPECT_EQ(2, (*cit)->value());
   2627     --it;
   2628     --cit;
   2629     EXPECT_EQ(0, (*it)->value());
   2630     EXPECT_EQ(0, (*cit)->value());
   2631     ++it;
   2632     ++cit;
   2633     ++it;
   2634     ++cit;
   2635     EXPECT_EQ(103, (*it)->value());
   2636     EXPECT_EQ(103, (*cit)->value());
   2637     ++it;
   2638     ++cit;
   2639     EXPECT_EQ(10, (*it)->value());
   2640     EXPECT_EQ(10, (*cit)->value());
   2641     ++it;
   2642     ++cit;
   2643 
   2644     EXPECT_EQ(10, (*reverse)->value());
   2645     EXPECT_EQ(10, (*creverse)->value());
   2646     ++reverse;
   2647     ++creverse;
   2648     EXPECT_EQ(103, (*reverse)->value());
   2649     EXPECT_EQ(103, (*creverse)->value());
   2650     --reverse;
   2651     --creverse;
   2652     EXPECT_EQ(10, (*reverse)->value());
   2653     EXPECT_EQ(10, (*creverse)->value());
   2654     ++reverse;
   2655     ++creverse;
   2656     ++reverse;
   2657     ++creverse;
   2658     EXPECT_EQ(2, (*reverse)->value());
   2659     EXPECT_EQ(2, (*creverse)->value());
   2660     ++reverse;
   2661     ++creverse;
   2662     EXPECT_EQ(0, (*reverse)->value());
   2663     EXPECT_EQ(0, (*creverse)->value());
   2664     ++reverse;
   2665     ++creverse;
   2666 
   2667     EXPECT_EQ(set1->end(), it);
   2668     EXPECT_EQ(constSet.end(), cit);
   2669     EXPECT_EQ(set1->rend(), reverse);
   2670     EXPECT_EQ(constSet.rend(), creverse);
   2671 
   2672     typename Set::iterator iX(set2->begin());
   2673     EXPECT_EQ(set2->end(), iX);
   2674 
   2675     if (strong)
   2676         set1->remove(keepNumbersAlive[0]);
   2677 
   2678     keepNumbersAlive[0] = nullptr;
   2679 
   2680     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2681 
   2682     EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size());
   2683 
   2684     EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls);
   2685 
   2686     typename Set::iterator i2(set1->begin());
   2687     if (strong) {
   2688         EXPECT_EQ(0, (*i2)->value());
   2689         ++i2;
   2690         EXPECT_NE(set1->end(), i2);
   2691     }
   2692     EXPECT_EQ(103, (*i2)->value());
   2693     ++i2;
   2694     EXPECT_NE(set1->end(), i2);
   2695     EXPECT_EQ(10, (*i2)->value());
   2696     ++i2;
   2697     EXPECT_EQ(set1->end(), i2);
   2698 }
   2699 
   2700 TEST(HeapTest, HeapWeakLinkedHashSet)
   2701 {
   2702     orderedSetHelper<HeapLinkedHashSet<Member<IntWrapper> > >(true);
   2703     orderedSetHelper<HeapLinkedHashSet<WeakMember<IntWrapper> > >(false);
   2704     orderedSetHelper<HeapListHashSet<Member<IntWrapper> > >(true);
   2705 }
   2706 
   2707 class ThingWithDestructor {
   2708 public:
   2709     ThingWithDestructor()
   2710         : m_x(emptyValue)
   2711     {
   2712         s_liveThingsWithDestructor++;
   2713     }
   2714 
   2715     ThingWithDestructor(int x)
   2716         : m_x(x)
   2717     {
   2718         s_liveThingsWithDestructor++;
   2719     }
   2720 
   2721     ThingWithDestructor(const ThingWithDestructor&other)
   2722     {
   2723         *this = other;
   2724         s_liveThingsWithDestructor++;
   2725     }
   2726 
   2727     ~ThingWithDestructor()
   2728     {
   2729         s_liveThingsWithDestructor--;
   2730     }
   2731 
   2732     int value() { return m_x; }
   2733 
   2734     static int s_liveThingsWithDestructor;
   2735 
   2736     unsigned hash() { return IntHash<int>::hash(m_x); }
   2737 
   2738 private:
   2739     static const int emptyValue = 0;
   2740     int m_x;
   2741 };
   2742 
   2743 int ThingWithDestructor::s_liveThingsWithDestructor;
   2744 
   2745 struct ThingWithDestructorTraits : public HashTraits<ThingWithDestructor> {
   2746     static const bool needsDestruction = true;
   2747 };
   2748 
   2749 static void heapMapDestructorHelper(bool clearMaps)
   2750 {
   2751     HeapStats initialHeapStats;
   2752     clearOutOldGarbage(&initialHeapStats);
   2753     ThingWithDestructor::s_liveThingsWithDestructor = 0;
   2754 
   2755     typedef HeapHashMap<WeakMember<IntWrapper>, RefPtr<RefCountedAndGarbageCollected> > RefMap;
   2756 
   2757     typedef HeapHashMap<
   2758         WeakMember<IntWrapper>,
   2759         ThingWithDestructor,
   2760         DefaultHash<WeakMember<IntWrapper> >::Hash,
   2761         HashTraits<WeakMember<IntWrapper> >,
   2762         ThingWithDestructorTraits> Map;
   2763 
   2764     Persistent<Map> map(new Map());
   2765     Persistent<RefMap> refMap(new RefMap());
   2766 
   2767     Persistent<IntWrapper> luck(IntWrapper::create(103));
   2768 
   2769     int baseLine, refBaseLine;
   2770 
   2771     {
   2772         Map stackMap;
   2773         RefMap stackRefMap;
   2774 
   2775         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2776         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2777 
   2778         stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729));
   2779         stackMap.add(luck, ThingWithDestructor(8128));
   2780         stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
   2781         stackRefMap.add(luck, RefCountedAndGarbageCollected::create());
   2782 
   2783         baseLine = ThingWithDestructor::s_liveThingsWithDestructor;
   2784         refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
   2785 
   2786         // Although the heap maps are on-stack, we can't expect prompt
   2787         // finalization of the elements, so when they go out of scope here we
   2788         // will not necessarily have called the relevant destructors.
   2789     }
   2790 
   2791     // The RefCountedAndGarbageCollected things need an extra GC to discover
   2792     // that they are no longer ref counted.
   2793     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2794     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2795     EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
   2796     EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
   2797 
   2798     // Now use maps kept alive with persistents. Here we don't expect any
   2799     // destructors to be called before there have been GCs.
   2800 
   2801     map->add(IntWrapper::create(42), ThingWithDestructor(1729));
   2802     map->add(luck, ThingWithDestructor(8128));
   2803     refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
   2804     refMap->add(luck, RefCountedAndGarbageCollected::create());
   2805 
   2806     baseLine  =  ThingWithDestructor::s_liveThingsWithDestructor;
   2807     refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
   2808 
   2809     luck.clear();
   2810     if (clearMaps) {
   2811         map->clear(); // Clear map.
   2812         refMap->clear(); // Clear map.
   2813     } else {
   2814         map.clear(); // Clear Persistent handle, not map.
   2815         refMap.clear(); // Clear Persistent handle, not map.
   2816         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2817         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2818     }
   2819 
   2820     EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
   2821 
   2822     // Need a GC to make sure that the RefCountedAndGarbageCollected thing
   2823     // noticies it's been decremented to zero.
   2824     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2825     EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
   2826 }
   2827 
   2828 TEST(HeapTest, HeapMapDestructor)
   2829 {
   2830     heapMapDestructorHelper(true);
   2831     heapMapDestructorHelper(false);
   2832 }
   2833 
   2834 typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
   2835 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
   2836 typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
   2837 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
   2838 typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongLinkedSet;
   2839 typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedLinkedSet;
   2840 typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakLinkedSet;
   2841 typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakLinkedSet;
   2842 typedef HeapHashCountedSet<PairWeakStrong> WeakStrongCountedSet;
   2843 typedef HeapHashCountedSet<PairWeakUnwrapped> WeakUnwrappedCountedSet;
   2844 typedef HeapHashCountedSet<PairStrongWeak> StrongWeakCountedSet;
   2845 typedef HeapHashCountedSet<PairUnwrappedWeak> UnwrappedWeakCountedSet;
   2846 
   2847 template<typename T>
   2848 T& iteratorExtractor(WTF::KeyValuePair<T, unsigned>& pair)
   2849 {
   2850     return pair.key;
   2851 }
   2852 
   2853 template<typename T>
   2854 T& iteratorExtractor(T& notAPair)
   2855 {
   2856     return notAPair;
   2857 }
   2858 
   2859 template<typename WSSet, typename SWSet, typename WUSet, typename UWSet>
   2860 void checkPairSets(
   2861     Persistent<WSSet>& weakStrong,
   2862     Persistent<SWSet>& strongWeak,
   2863     Persistent<WUSet>& weakUnwrapped,
   2864     Persistent<UWSet>& unwrappedWeak,
   2865     bool ones,
   2866     Persistent<IntWrapper>& two)
   2867 {
   2868     typename WSSet::iterator itWS = weakStrong->begin();
   2869     typename SWSet::iterator itSW = strongWeak->begin();
   2870     typename WUSet::iterator itWU = weakUnwrapped->begin();
   2871     typename UWSet::iterator itUW = unwrappedWeak->begin();
   2872 
   2873     EXPECT_EQ(2u, weakStrong->size());
   2874     EXPECT_EQ(2u, strongWeak->size());
   2875     EXPECT_EQ(2u, weakUnwrapped->size());
   2876     EXPECT_EQ(2u, unwrappedWeak->size());
   2877 
   2878     PairWeakStrong p = iteratorExtractor(*itWS);
   2879     PairStrongWeak p2 = iteratorExtractor(*itSW);
   2880     PairWeakUnwrapped p3 = iteratorExtractor(*itWU);
   2881     PairUnwrappedWeak p4 = iteratorExtractor(*itUW);
   2882     if (p.first == two && p.second == two)
   2883         ++itWS;
   2884     if (p2.first == two && p2.second == two)
   2885         ++itSW;
   2886     if (p3.first == two && p3.second == 2)
   2887         ++itWU;
   2888     if (p4.first == 2 && p4.second == two)
   2889         ++itUW;
   2890     p = iteratorExtractor(*itWS);
   2891     p2 = iteratorExtractor(*itSW);
   2892     p3 = iteratorExtractor(*itWU);
   2893     p4 = iteratorExtractor(*itUW);
   2894     IntWrapper* nullWrapper = 0;
   2895     if (ones) {
   2896         EXPECT_EQ(p.first->value(), 1);
   2897         EXPECT_EQ(p2.second->value(), 1);
   2898         EXPECT_EQ(p3.first->value(), 1);
   2899         EXPECT_EQ(p4.second->value(), 1);
   2900     } else {
   2901         EXPECT_EQ(p.first, nullWrapper);
   2902         EXPECT_EQ(p2.second, nullWrapper);
   2903         EXPECT_EQ(p3.first, nullWrapper);
   2904         EXPECT_EQ(p4.second, nullWrapper);
   2905     }
   2906 
   2907     EXPECT_EQ(p.second->value(), 2);
   2908     EXPECT_EQ(p2.first->value(), 2);
   2909     EXPECT_EQ(p3.second, 2);
   2910     EXPECT_EQ(p4.first, 2);
   2911 
   2912     EXPECT_TRUE(weakStrong->contains(PairWeakStrong(&*two, &*two)));
   2913     EXPECT_TRUE(strongWeak->contains(PairStrongWeak(&*two, &*two)));
   2914     EXPECT_TRUE(weakUnwrapped->contains(PairWeakUnwrapped(&*two, 2)));
   2915     EXPECT_TRUE(unwrappedWeak->contains(PairUnwrappedWeak(2, &*two)));
   2916 }
   2917 
   2918 template<typename WSSet, typename SWSet, typename WUSet, typename UWSet>
   2919 void weakPairsHelper()
   2920 {
   2921     IntWrapper::s_destructorCalls = 0;
   2922 
   2923     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
   2924 
   2925     Persistent<WSSet> weakStrong = new WSSet();
   2926     Persistent<SWSet> strongWeak = new SWSet();
   2927     Persistent<WUSet> weakUnwrapped = new WUSet();
   2928     Persistent<UWSet> unwrappedWeak = new UWSet();
   2929 
   2930     Persistent<IntWrapper> two = IntWrapper::create(2);
   2931 
   2932     weakStrong->add(PairWeakStrong(IntWrapper::create(1), &*two));
   2933     weakStrong->add(PairWeakStrong(&*two, &*two));
   2934     strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1)));
   2935     strongWeak->add(PairStrongWeak(&*two, &*two));
   2936     weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2));
   2937     weakUnwrapped->add(PairWeakUnwrapped(&*two, 2));
   2938     unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1)));
   2939     unwrappedWeak->add(PairUnwrappedWeak(2, &*two));
   2940 
   2941     checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrapped, unwrappedWeak, true, two);
   2942 
   2943     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   2944     checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrapped, unwrappedWeak, false, two);
   2945 }
   2946 
   2947 TEST(HeapTest, HeapWeakPairs)
   2948 {
   2949     {
   2950         typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
   2951         typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
   2952         typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
   2953         typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
   2954         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
   2955     }
   2956 
   2957     {
   2958         typedef HeapListHashSet<PairWeakStrong> WeakStrongSet;
   2959         typedef HeapListHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
   2960         typedef HeapListHashSet<PairStrongWeak> StrongWeakSet;
   2961         typedef HeapListHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
   2962         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
   2963     }
   2964 
   2965     {
   2966         typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongSet;
   2967         typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
   2968         typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakSet;
   2969         typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
   2970         weakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet, UnwrappedWeakSet>();
   2971     }
   2972 }
   2973 
   2974 TEST(HeapTest, HeapWeakCollectionTypes)
   2975 {
   2976     HeapStats initialHeapSize;
   2977     IntWrapper::s_destructorCalls = 0;
   2978 
   2979     typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper> > WeakStrong;
   2980     typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper> > StrongWeak;
   2981     typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper> > WeakWeak;
   2982     typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
   2983     typedef HeapLinkedHashSet<WeakMember<IntWrapper> > WeakOrderedSet;
   2984 
   2985     clearOutOldGarbage(&initialHeapSize);
   2986 
   2987     const int weakStrongIndex = 0;
   2988     const int strongWeakIndex = 1;
   2989     const int weakWeakIndex = 2;
   2990     const int numberOfMapIndices = 3;
   2991     const int weakSetIndex = 3;
   2992     const int weakOrderedSetIndex = 4;
   2993     const int numberOfCollections = 5;
   2994 
   2995     for (int testRun = 0; testRun < 4; testRun++) {
   2996         for (int collectionNumber = 0; collectionNumber < numberOfCollections; collectionNumber++) {
   2997             bool deleteAfterwards = (testRun == 1);
   2998             bool addAfterwards = (testRun == 2);
   2999             bool testThatIteratorsMakeStrong = (testRun == 3);
   3000 
   3001             // The test doesn't work for strongWeak with deleting because we lost
   3002             // the key from the keepNumbersAlive array, so we can't do the lookup.
   3003             if (deleteAfterwards && collectionNumber == strongWeakIndex)
   3004                 continue;
   3005 
   3006             unsigned added = addAfterwards ? 100 : 0;
   3007 
   3008             Persistent<WeakStrong> weakStrong = new WeakStrong();
   3009             Persistent<StrongWeak> strongWeak = new StrongWeak();
   3010             Persistent<WeakWeak> weakWeak = new WeakWeak();
   3011 
   3012             Persistent<WeakSet> weakSet = new WeakSet();
   3013             Persistent<WeakOrderedSet> weakOrderedSet = new WeakOrderedSet();
   3014 
   3015             PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
   3016             for (int i = 0; i < 128; i += 2) {
   3017                 IntWrapper* wrapped = IntWrapper::create(i);
   3018                 IntWrapper* wrapped2 = IntWrapper::create(i + 1);
   3019                 keepNumbersAlive.append(wrapped);
   3020                 keepNumbersAlive.append(wrapped2);
   3021                 weakStrong->add(wrapped, wrapped2);
   3022                 strongWeak->add(wrapped2, wrapped);
   3023                 weakWeak->add(wrapped, wrapped2);
   3024                 weakSet->add(wrapped);
   3025                 weakOrderedSet->add(wrapped);
   3026             }
   3027 
   3028             EXPECT_EQ(64u, weakStrong->size());
   3029             EXPECT_EQ(64u, strongWeak->size());
   3030             EXPECT_EQ(64u, weakWeak->size());
   3031             EXPECT_EQ(64u, weakSet->size());
   3032             EXPECT_EQ(64u, weakOrderedSet->size());
   3033 
   3034             // Collect garbage. This should change nothing since we are keeping
   3035             // alive the IntWrapper objects.
   3036             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3037 
   3038             EXPECT_EQ(64u, weakStrong->size());
   3039             EXPECT_EQ(64u, strongWeak->size());
   3040             EXPECT_EQ(64u, weakWeak->size());
   3041             EXPECT_EQ(64u, weakSet->size());
   3042             EXPECT_EQ(64u, weakOrderedSet->size());
   3043 
   3044             for (int i = 0; i < 128; i += 2) {
   3045                 IntWrapper* wrapped = keepNumbersAlive[i];
   3046                 IntWrapper* wrapped2 = keepNumbersAlive[i + 1];
   3047                 EXPECT_EQ(wrapped2, weakStrong->get(wrapped));
   3048                 EXPECT_EQ(wrapped, strongWeak->get(wrapped2));
   3049                 EXPECT_EQ(wrapped2, weakWeak->get(wrapped));
   3050                 EXPECT_TRUE(weakSet->contains(wrapped));
   3051                 EXPECT_TRUE(weakOrderedSet->contains(wrapped));
   3052             }
   3053 
   3054             for (int i = 0; i < 128; i += 3)
   3055                 keepNumbersAlive[i] = nullptr;
   3056 
   3057             if (collectionNumber != weakStrongIndex)
   3058                 weakStrong->clear();
   3059             if (collectionNumber != strongWeakIndex)
   3060                 strongWeak->clear();
   3061             if (collectionNumber != weakWeakIndex)
   3062                 weakWeak->clear();
   3063             if (collectionNumber != weakSetIndex)
   3064                 weakSet->clear();
   3065             if (collectionNumber != weakOrderedSetIndex)
   3066                 weakOrderedSet->clear();
   3067 
   3068             if (testThatIteratorsMakeStrong) {
   3069                 WeakStrong::iterator it1 = weakStrong->begin();
   3070                 StrongWeak::iterator it2 = strongWeak->begin();
   3071                 WeakWeak::iterator it3 = weakWeak->begin();
   3072                 WeakSet::iterator it4 = weakSet->begin();
   3073                 WeakOrderedSet::iterator it5 = weakOrderedSet->begin();
   3074                 // Collect garbage. This should change nothing since the
   3075                 // iterators make the collections strong.
   3076                 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3077                 if (collectionNumber == weakStrongIndex) {
   3078                     EXPECT_EQ(64u, weakStrong->size());
   3079                     MapIteratorCheck(it1, weakStrong->end(), 64);
   3080                 } else if (collectionNumber == strongWeakIndex) {
   3081                     EXPECT_EQ(64u, strongWeak->size());
   3082                     MapIteratorCheck(it2, strongWeak->end(), 64);
   3083                 } else if (collectionNumber == weakWeakIndex) {
   3084                     EXPECT_EQ(64u, weakWeak->size());
   3085                     MapIteratorCheck(it3, weakWeak->end(), 64);
   3086                 } else if (collectionNumber == weakSetIndex) {
   3087                     EXPECT_EQ(64u, weakSet->size());
   3088                     SetIteratorCheck(it4, weakSet->end(), 64);
   3089                 } else if (collectionNumber == weakOrderedSetIndex) {
   3090                     EXPECT_EQ(64u, weakOrderedSet->size());
   3091                     SetIteratorCheck(it5, weakOrderedSet->end(), 64);
   3092                 }
   3093             } else {
   3094                 // Collect garbage. This causes weak processing to remove
   3095                 // things from the collections.
   3096                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3097                 unsigned count = 0;
   3098                 for (int i = 0; i < 128; i += 2) {
   3099                     bool firstAlive = keepNumbersAlive[i];
   3100                     bool secondAlive = keepNumbersAlive[i + 1];
   3101                     if (firstAlive && (collectionNumber == weakStrongIndex || collectionNumber == strongWeakIndex))
   3102                         secondAlive = true;
   3103                     if (firstAlive && secondAlive && collectionNumber < numberOfMapIndices) {
   3104                         if (collectionNumber == weakStrongIndex) {
   3105                             if (deleteAfterwards)
   3106                                 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAlive[i])->value());
   3107                         } else if (collectionNumber == strongWeakIndex) {
   3108                             if (deleteAfterwards)
   3109                                 EXPECT_EQ(i, strongWeak->take(keepNumbersAlive[i + 1])->value());
   3110                         } else if (collectionNumber == weakWeakIndex) {
   3111                             if (deleteAfterwards)
   3112                                 EXPECT_EQ(i + 1, weakWeak->take(keepNumbersAlive[i])->value());
   3113                         }
   3114                         if (!deleteAfterwards)
   3115                             count++;
   3116                     } else if (collectionNumber == weakSetIndex && firstAlive) {
   3117                         ASSERT_TRUE(weakSet->contains(keepNumbersAlive[i]));
   3118                         if (deleteAfterwards)
   3119                             weakSet->remove(keepNumbersAlive[i]);
   3120                         else
   3121                             count++;
   3122                     } else if (collectionNumber == weakOrderedSetIndex && firstAlive) {
   3123                         ASSERT_TRUE(weakOrderedSet->contains(keepNumbersAlive[i]));
   3124                         if (deleteAfterwards)
   3125                             weakOrderedSet->remove(keepNumbersAlive[i]);
   3126                         else
   3127                             count++;
   3128                     }
   3129                 }
   3130                 if (addAfterwards) {
   3131                     for (int i = 1000; i < 1100; i++) {
   3132                         IntWrapper* wrapped = IntWrapper::create(i);
   3133                         keepNumbersAlive.append(wrapped);
   3134                         weakStrong->add(wrapped, wrapped);
   3135                         strongWeak->add(wrapped, wrapped);
   3136                         weakWeak->add(wrapped, wrapped);
   3137                         weakSet->add(wrapped);
   3138                         weakOrderedSet->add(wrapped);
   3139                     }
   3140                 }
   3141                 if (collectionNumber == weakStrongIndex)
   3142                     EXPECT_EQ(count + added, weakStrong->size());
   3143                 else if (collectionNumber == strongWeakIndex)
   3144                     EXPECT_EQ(count + added, strongWeak->size());
   3145                 else if (collectionNumber == weakWeakIndex)
   3146                     EXPECT_EQ(count + added, weakWeak->size());
   3147                 else if (collectionNumber == weakSetIndex)
   3148                     EXPECT_EQ(count + added, weakSet->size());
   3149                 else if (collectionNumber == weakOrderedSetIndex)
   3150                     EXPECT_EQ(count + added, weakOrderedSet->size());
   3151                 WeakStrong::iterator it1 = weakStrong->begin();
   3152                 StrongWeak::iterator it2 = strongWeak->begin();
   3153                 WeakWeak::iterator it3 = weakWeak->begin();
   3154                 WeakSet::iterator it4 = weakSet->begin();
   3155                 WeakOrderedSet::iterator it5 = weakOrderedSet->begin();
   3156                 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == weakStrongIndex ? count : 0) + added);
   3157                 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == strongWeakIndex ? count : 0) + added);
   3158                 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weakWeakIndex ? count : 0) + added);
   3159                 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakSetIndex ? count : 0) + added);
   3160                 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber == weakOrderedSetIndex ? count : 0) + added);
   3161             }
   3162             for (unsigned i = 0; i < 128 + added; i++)
   3163                 keepNumbersAlive[i] = nullptr;
   3164             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3165             EXPECT_EQ(added, weakStrong->size());
   3166             EXPECT_EQ(added, strongWeak->size());
   3167             EXPECT_EQ(added, weakWeak->size());
   3168             EXPECT_EQ(added, weakSet->size());
   3169             EXPECT_EQ(added, weakOrderedSet->size());
   3170         }
   3171     }
   3172 }
   3173 
   3174 TEST(HeapTest, RefCountedGarbageCollected)
   3175 {
   3176     RefCountedAndGarbageCollected::s_destructorCalls = 0;
   3177     {
   3178         RefPtr<RefCountedAndGarbageCollected> refPtr3;
   3179         {
   3180             Persistent<RefCountedAndGarbageCollected> persistent;
   3181             {
   3182                 RefPtr<RefCountedAndGarbageCollected> refPtr1 = RefCountedAndGarbageCollected::create();
   3183                 RefPtr<RefCountedAndGarbageCollected> refPtr2 = RefCountedAndGarbageCollected::create();
   3184                 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3185                 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
   3186                 persistent = refPtr1.get();
   3187             }
   3188             // Reference count is zero for both objects but one of
   3189             // them is kept alive by a persistent handle.
   3190             Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3191             EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
   3192             refPtr3 = persistent.get();
   3193         }
   3194         // The persistent handle is gone but the ref count has been
   3195         // increased to 1.
   3196         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3197         EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
   3198     }
   3199     // Both persistent handle is gone and ref count is zero so the
   3200     // object can be collected.
   3201     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3202     EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls);
   3203 }
   3204 
   3205 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers)
   3206 {
   3207     RefCountedAndGarbageCollected::s_destructorCalls = 0;
   3208     RefCountedAndGarbageCollected2::s_destructorCalls = 0;
   3209     {
   3210         RefCountedAndGarbageCollected* pointer1 = 0;
   3211         RefCountedAndGarbageCollected2* pointer2 = 0;
   3212         {
   3213             RefPtr<RefCountedAndGarbageCollected> object1 = RefCountedAndGarbageCollected::create();
   3214             RefPtr<RefCountedAndGarbageCollected2> object2 = RefCountedAndGarbageCollected2::create();
   3215             pointer1 = object1.get();
   3216             pointer2 = object2.get();
   3217             void* objects[2] = { object1.get(), object2.get() };
   3218             RefCountedGarbageCollectedVisitor visitor(2, objects);
   3219             ThreadState::current()->visitPersistents(&visitor);
   3220             EXPECT_TRUE(visitor.validate());
   3221 
   3222             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3223             EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
   3224             EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
   3225         }
   3226         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3227         EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
   3228         EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
   3229 
   3230         // At this point, the reference counts of object1 and object2 are 0.
   3231         // Only pointer1 and pointer2 keep references to object1 and object2.
   3232         void* objects[] = { 0 };
   3233         RefCountedGarbageCollectedVisitor visitor(0, objects);
   3234         ThreadState::current()->visitPersistents(&visitor);
   3235         EXPECT_TRUE(visitor.validate());
   3236 
   3237         {
   3238             RefPtr<RefCountedAndGarbageCollected> object1(pointer1);
   3239             RefPtr<RefCountedAndGarbageCollected2> object2(pointer2);
   3240             void* objects[2] = { object1.get(), object2.get() };
   3241             RefCountedGarbageCollectedVisitor visitor(2, objects);
   3242             ThreadState::current()->visitPersistents(&visitor);
   3243             EXPECT_TRUE(visitor.validate());
   3244 
   3245             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3246             EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
   3247             EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
   3248         }
   3249 
   3250         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3251         EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
   3252         EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
   3253     }
   3254 
   3255     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3256     EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
   3257     EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls);
   3258 }
   3259 
   3260 TEST(HeapTest, WeakMembers)
   3261 {
   3262     Bar::s_live = 0;
   3263     {
   3264         Persistent<Bar> h1 = Bar::create();
   3265         Persistent<Weak> h4;
   3266         Persistent<WithWeakMember> h5;
   3267         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3268         ASSERT_EQ(1u, Bar::s_live); // h1 is live.
   3269         {
   3270             Bar* h2 = Bar::create();
   3271             Bar* h3 = Bar::create();
   3272             h4 = Weak::create(h2, h3);
   3273             h5 = WithWeakMember::create(h2, h3);
   3274             Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3275             EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive.
   3276             EXPECT_TRUE(h4->strongIsThere());
   3277             EXPECT_TRUE(h4->weakIsThere());
   3278             EXPECT_TRUE(h5->strongIsThere());
   3279             EXPECT_TRUE(h5->weakIsThere());
   3280         }
   3281         // h3 is collected, weak pointers from h4 and h5 don't keep it alive.
   3282         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3283         EXPECT_EQ(4u, Bar::s_live);
   3284         EXPECT_TRUE(h4->strongIsThere());
   3285         EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer.
   3286         EXPECT_TRUE(h5->strongIsThere());
   3287         EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer.
   3288         h1.release(); // Zero out h1.
   3289         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3290         EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left.
   3291         EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4.
   3292         EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5.
   3293     }
   3294     // h4 and h5 have gone out of scope now and they were keeping h2 alive.
   3295     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3296     EXPECT_EQ(0u, Bar::s_live); // All gone.
   3297 }
   3298 
   3299 TEST(HeapTest, FinalizationObserver)
   3300 {
   3301     Persistent<FinalizationObserver<Observable> > o;
   3302     {
   3303         Observable* foo = Observable::create(Bar::create());
   3304         // |o| observes |foo|.
   3305         o = FinalizationObserver<Observable>::create(foo);
   3306     }
   3307     // FinalizationObserver doesn't have a strong reference to |foo|. So |foo|
   3308     // and its member will be collected.
   3309     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3310     EXPECT_EQ(0u, Bar::s_live);
   3311     EXPECT_TRUE(o->didCallWillFinalize());
   3312 
   3313     FinalizationObserverWithHashMap::s_didCallWillFinalize = false;
   3314     Observable* foo = Observable::create(Bar::create());
   3315     FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWithHashMap::observe(*foo);
   3316     EXPECT_EQ(1u, map.size());
   3317     foo = 0;
   3318     // FinalizationObserverWithHashMap doesn't have a strong reference to
   3319     // |foo|. So |foo| and its member will be collected.
   3320     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3321     EXPECT_EQ(0u, Bar::s_live);
   3322     EXPECT_EQ(0u, map.size());
   3323     EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize);
   3324 }
   3325 
   3326 TEST(HeapTest, Comparisons)
   3327 {
   3328     Persistent<Bar> barPersistent = Bar::create();
   3329     Persistent<Foo> fooPersistent = Foo::create(barPersistent);
   3330     EXPECT_TRUE(barPersistent != fooPersistent);
   3331     barPersistent = fooPersistent;
   3332     EXPECT_TRUE(barPersistent == fooPersistent);
   3333 }
   3334 
   3335 TEST(HeapTest, CheckAndMarkPointer)
   3336 {
   3337     HeapStats initialHeapStats;
   3338     clearOutOldGarbage(&initialHeapStats);
   3339 
   3340     Vector<Address> objectAddresses;
   3341     Vector<Address> endAddresses;
   3342     Address largeObjectAddress;
   3343     Address largeObjectEndAddress;
   3344     CountingVisitor visitor;
   3345     for (int i = 0; i < 10; i++) {
   3346         SimpleObject* object = SimpleObject::create();
   3347         Address objectAddress = reinterpret_cast<Address>(object);
   3348         objectAddresses.append(objectAddress);
   3349         endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
   3350     }
   3351     LargeObject* largeObject = LargeObject::create();
   3352     largeObjectAddress = reinterpret_cast<Address>(largeObject);
   3353     largeObjectEndAddress = largeObjectAddress + sizeof(LargeObject) - 1;
   3354 
   3355     // This is a low-level test where we call checkAndMarkPointer. This method
   3356     // causes the object start bitmap to be computed which requires the heap
   3357     // to be in a consistent state (e.g. the free allocation area must be put
   3358     // into a free list header). However when we call makeConsistentForGC it
   3359     // also clears out the freelists so we have to rebuild those before trying
   3360     // to allocate anything again. We do this by forcing a GC after doing the
   3361     // checkAndMarkPointer tests.
   3362     {
   3363         TestGCScope scope(ThreadState::HeapPointersOnStack);
   3364         EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
   3365         Heap::makeConsistentForGC();
   3366         for (size_t i = 0; i < objectAddresses.size(); i++) {
   3367             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
   3368             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i]));
   3369         }
   3370         EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
   3371         visitor.reset();
   3372         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress));
   3373         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress));
   3374         EXPECT_EQ(2ul, visitor.count());
   3375         visitor.reset();
   3376     }
   3377     // This forces a GC without stack scanning which results in the objects
   3378     // being collected. This will also rebuild the above mentioned freelists,
   3379     // however we don't rely on that below since we don't have any allocations.
   3380     clearOutOldGarbage(&initialHeapStats);
   3381     {
   3382         TestGCScope scope(ThreadState::HeapPointersOnStack);
   3383         EXPECT_TRUE(scope.allThreadsParked());
   3384         Heap::makeConsistentForGC();
   3385         for (size_t i = 0; i < objectAddresses.size(); i++) {
   3386             // We would like to assert that checkAndMarkPointer returned false
   3387             // here because the pointers no longer point into a valid object
   3388             // (it's been freed by the GCs. But checkAndMarkPointer will return
   3389             // true for any pointer that points into a heap page, regardless of
   3390             // whether it points at a valid object (this ensures the
   3391             // correctness of the page-based on-heap address caches), so we
   3392             // can't make that assert.
   3393             Heap::checkAndMarkPointer(&visitor, objectAddresses[i]);
   3394             Heap::checkAndMarkPointer(&visitor, endAddresses[i]);
   3395         }
   3396         EXPECT_EQ(0ul, visitor.count());
   3397         Heap::checkAndMarkPointer(&visitor, largeObjectAddress);
   3398         Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress);
   3399         EXPECT_EQ(0ul, visitor.count());
   3400     }
   3401     // This round of GC is important to make sure that the object start
   3402     // bitmap are cleared out and that the free lists are rebuild.
   3403     clearOutOldGarbage(&initialHeapStats);
   3404 }
   3405 
   3406 TEST(HeapTest, VisitOffHeapCollections)
   3407 {
   3408     HeapStats initialHeapStats;
   3409     clearOutOldGarbage(&initialHeapStats);
   3410     IntWrapper::s_destructorCalls = 0;
   3411     Persistent<OffHeapContainer> container = OffHeapContainer::create();
   3412     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3413     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3414     container = nullptr;
   3415     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3416     EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls);
   3417 }
   3418 
   3419 TEST(HeapTest, PersistentHeapCollectionTypes)
   3420 {
   3421     HeapStats initialHeapSize;
   3422     IntWrapper::s_destructorCalls = 0;
   3423 
   3424     typedef HeapVector<Member<IntWrapper> > Vec;
   3425     typedef PersistentHeapVector<Member<IntWrapper> > PVec;
   3426     typedef PersistentHeapHashSet<Member<IntWrapper> > PSet;
   3427     typedef PersistentHeapListHashSet<Member<IntWrapper> > PListSet;
   3428     typedef PersistentHeapLinkedHashSet<Member<IntWrapper> > PLinkedSet;
   3429     typedef PersistentHeapHashMap<Member<IntWrapper>, Member<IntWrapper> > PMap;
   3430     typedef PersistentHeapDeque<Member<IntWrapper> > PDeque;
   3431 
   3432     clearOutOldGarbage(&initialHeapSize);
   3433     {
   3434         PVec pVec;
   3435         PDeque pDeque;
   3436         PSet pSet;
   3437         PListSet pListSet;
   3438         PLinkedSet pLinkedSet;
   3439         PMap pMap;
   3440 
   3441         IntWrapper* one(IntWrapper::create(1));
   3442         IntWrapper* two(IntWrapper::create(2));
   3443         IntWrapper* three(IntWrapper::create(3));
   3444         IntWrapper* four(IntWrapper::create(4));
   3445         IntWrapper* five(IntWrapper::create(5));
   3446         IntWrapper* six(IntWrapper::create(6));
   3447         IntWrapper* seven(IntWrapper::create(7));
   3448         IntWrapper* eight(IntWrapper::create(8));
   3449         IntWrapper* nine(IntWrapper::create(9));
   3450 
   3451         pVec.append(one);
   3452         pVec.append(two);
   3453 
   3454         pDeque.append(seven);
   3455         pDeque.append(two);
   3456 
   3457         Vec* vec = new Vec();
   3458         vec->swap(pVec);
   3459 
   3460         pVec.append(two);
   3461         pVec.append(three);
   3462 
   3463         pSet.add(four);
   3464         pListSet.add(eight);
   3465         pLinkedSet.add(nine);
   3466         pMap.add(five, six);
   3467 
   3468         // Collect |vec| and |one|.
   3469         vec = 0;
   3470         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3471         EXPECT_EQ(1, IntWrapper::s_destructorCalls);
   3472 
   3473         EXPECT_EQ(2u, pVec.size());
   3474         EXPECT_EQ(two, pVec.at(0));
   3475         EXPECT_EQ(three, pVec.at(1));
   3476 
   3477         EXPECT_EQ(2u, pDeque.size());
   3478         EXPECT_EQ(seven, pDeque.first());
   3479         EXPECT_EQ(seven, pDeque.takeFirst());
   3480         EXPECT_EQ(two, pDeque.first());
   3481 
   3482         EXPECT_EQ(1u, pDeque.size());
   3483 
   3484         EXPECT_EQ(1u, pSet.size());
   3485         EXPECT_TRUE(pSet.contains(four));
   3486 
   3487         EXPECT_EQ(1u, pListSet.size());
   3488         EXPECT_TRUE(pListSet.contains(eight));
   3489 
   3490         EXPECT_EQ(1u, pLinkedSet.size());
   3491         EXPECT_TRUE(pLinkedSet.contains(nine));
   3492 
   3493         EXPECT_EQ(1u, pMap.size());
   3494         EXPECT_EQ(six, pMap.get(five));
   3495     }
   3496 
   3497     // Collect previous roots.
   3498     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3499     EXPECT_EQ(9, IntWrapper::s_destructorCalls);
   3500 }
   3501 
   3502 TEST(HeapTest, CollectionNesting)
   3503 {
   3504     HeapStats initialStats;
   3505     clearOutOldGarbage(&initialStats);
   3506     int* key = &IntWrapper::s_destructorCalls;
   3507     IntWrapper::s_destructorCalls = 0;
   3508     typedef HeapVector<Member<IntWrapper> > IntVector;
   3509     typedef HeapDeque<Member<IntWrapper> > IntDeque;
   3510     HeapHashMap<void*, IntVector>* map = new HeapHashMap<void*, IntVector>();
   3511     HeapHashMap<void*, IntDeque>* map2 = new HeapHashMap<void*, IntDeque>();
   3512 
   3513     map->add(key, IntVector());
   3514     map2->add(key, IntDeque());
   3515 
   3516     HeapHashMap<void*, IntVector>::iterator it = map->find(key);
   3517     EXPECT_EQ(0u, map->get(key).size());
   3518 
   3519     HeapHashMap<void*, IntDeque>::iterator it2 = map2->find(key);
   3520     EXPECT_EQ(0u, map2->get(key).size());
   3521 
   3522     it->value.append(IntWrapper::create(42));
   3523     EXPECT_EQ(1u, map->get(key).size());
   3524 
   3525     it2->value.append(IntWrapper::create(42));
   3526     EXPECT_EQ(1u, map2->get(key).size());
   3527 
   3528     Persistent<HeapHashMap<void*, IntVector> > keepAlive(map);
   3529     Persistent<HeapHashMap<void*, IntDeque> > keepAlive2(map2);
   3530 
   3531     for (int i = 0; i < 100; i++) {
   3532         map->add(key + 1 + i, IntVector());
   3533         map2->add(key + 1 + i, IntDeque());
   3534     }
   3535 
   3536     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3537 
   3538     EXPECT_EQ(1u, map->get(key).size());
   3539     EXPECT_EQ(1u, map2->get(key).size());
   3540     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3541 
   3542     keepAlive = nullptr;
   3543     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3544     EXPECT_EQ(1, IntWrapper::s_destructorCalls);
   3545 }
   3546 
   3547 TEST(HeapTest, GarbageCollectedMixin)
   3548 {
   3549     HeapStats initialHeapStats;
   3550     clearOutOldGarbage(&initialHeapStats);
   3551 
   3552     Persistent<UseMixin> usemixin = UseMixin::create();
   3553     EXPECT_EQ(0, UseMixin::s_traceCount);
   3554     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3555     EXPECT_EQ(1, UseMixin::s_traceCount);
   3556 
   3557     Persistent<Mixin> mixin = usemixin;
   3558     usemixin = nullptr;
   3559     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3560     EXPECT_EQ(2, UseMixin::s_traceCount);
   3561 
   3562     PersistentHeapHashSet<WeakMember<Mixin> > weakMap;
   3563     weakMap.add(UseMixin::create());
   3564     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3565     EXPECT_EQ(0u, weakMap.size());
   3566 }
   3567 
   3568 TEST(HeapTest, CollectionNesting2)
   3569 {
   3570     HeapStats initialStats;
   3571     clearOutOldGarbage(&initialStats);
   3572     void* key = &IntWrapper::s_destructorCalls;
   3573     IntWrapper::s_destructorCalls = 0;
   3574     typedef HeapHashSet<Member<IntWrapper> > IntSet;
   3575     HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>();
   3576 
   3577     map->add(key, IntSet());
   3578 
   3579     HeapHashMap<void*, IntSet>::iterator it = map->find(key);
   3580     EXPECT_EQ(0u, map->get(key).size());
   3581 
   3582     it->value.add(IntWrapper::create(42));
   3583     EXPECT_EQ(1u, map->get(key).size());
   3584 
   3585     Persistent<HeapHashMap<void*, IntSet> > keepAlive(map);
   3586     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3587     EXPECT_EQ(1u, map->get(key).size());
   3588     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3589 }
   3590 
   3591 TEST(HeapTest, CollectionNesting3)
   3592 {
   3593     HeapStats initialStats;
   3594     clearOutOldGarbage(&initialStats);
   3595     IntWrapper::s_destructorCalls = 0;
   3596     typedef HeapVector<Member<IntWrapper> > IntVector;
   3597     typedef HeapDeque<Member<IntWrapper> > IntDeque;
   3598     HeapVector<IntVector>* vector = new HeapVector<IntVector>();
   3599     HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>();
   3600 
   3601     vector->append(IntVector());
   3602     deque->append(IntDeque());
   3603 
   3604     HeapVector<IntVector>::iterator it = vector->begin();
   3605     HeapDeque<IntDeque>::iterator it2 = deque->begin();
   3606     EXPECT_EQ(0u, it->size());
   3607     EXPECT_EQ(0u, it2->size());
   3608 
   3609     it->append(IntWrapper::create(42));
   3610     it2->append(IntWrapper::create(42));
   3611     EXPECT_EQ(1u, it->size());
   3612     EXPECT_EQ(1u, it2->size());
   3613 
   3614     Persistent<HeapVector<IntVector> > keepAlive(vector);
   3615     Persistent<HeapDeque<IntDeque> > keepAlive2(deque);
   3616     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3617     EXPECT_EQ(1u, it->size());
   3618     EXPECT_EQ(1u, it2->size());
   3619     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3620 }
   3621 
   3622 TEST(HeapTest, EmbeddedInVector)
   3623 {
   3624     HeapStats initialStats;
   3625     clearOutOldGarbage(&initialStats);
   3626     SimpleFinalizedObject::s_destructorCalls = 0;
   3627     {
   3628         PersistentHeapVector<VectorObject, 2> inlineVector;
   3629         PersistentHeapVector<VectorObject> outlineVector;
   3630         VectorObject i1, i2;
   3631         inlineVector.append(i1);
   3632         inlineVector.append(i2);
   3633 
   3634         VectorObject o1, o2;
   3635         outlineVector.append(o1);
   3636         outlineVector.append(o2);
   3637 
   3638         PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace;
   3639         VectorObjectInheritedTrace it1, it2;
   3640         vectorInheritedTrace.append(it1);
   3641         vectorInheritedTrace.append(it2);
   3642 
   3643         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3644         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
   3645 
   3646         // Since VectorObjectNoTrace has no trace method it will
   3647         // not be traced and hence be collected when doing GC.
   3648         // We trace items in a collection braced on the item's
   3649         // having a trace method. This is determined via the
   3650         // NeedsTracing trait in wtf/TypeTraits.h.
   3651         PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace;
   3652         VectorObjectNoTrace n1, n2;
   3653         vectorNoTrace.append(n1);
   3654         vectorNoTrace.append(n2);
   3655         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3656         EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
   3657     }
   3658     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3659     EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
   3660 }
   3661 
   3662 TEST(HeapTest, EmbeddedInDeque)
   3663 {
   3664     HeapStats initialStats;
   3665     clearOutOldGarbage(&initialStats);
   3666     SimpleFinalizedObject::s_destructorCalls = 0;
   3667     {
   3668         PersistentHeapDeque<VectorObject, 2> inlineDeque;
   3669         PersistentHeapDeque<VectorObject> outlineDeque;
   3670         VectorObject i1, i2;
   3671         inlineDeque.append(i1);
   3672         inlineDeque.append(i2);
   3673 
   3674         VectorObject o1, o2;
   3675         outlineDeque.append(o1);
   3676         outlineDeque.append(o2);
   3677 
   3678         PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace;
   3679         VectorObjectInheritedTrace it1, it2;
   3680         dequeInheritedTrace.append(it1);
   3681         dequeInheritedTrace.append(it2);
   3682 
   3683         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3684         EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls);
   3685 
   3686         // Since VectorObjectNoTrace has no trace method it will
   3687         // not be traced and hence be collected when doing GC.
   3688         // We trace items in a collection braced on the item's
   3689         // having a trace method. This is determined via the
   3690         // NeedsTracing trait in wtf/TypeTraits.h.
   3691         PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace;
   3692         VectorObjectNoTrace n1, n2;
   3693         dequeNoTrace.append(n1);
   3694         dequeNoTrace.append(n2);
   3695         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3696         EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
   3697     }
   3698     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3699     EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
   3700 }
   3701 
   3702 template<typename Set>
   3703 void rawPtrInHashHelper()
   3704 {
   3705     Set set;
   3706     set.add(new int(42));
   3707     set.add(new int(42));
   3708     EXPECT_EQ(2u, set.size());
   3709     for (typename Set::iterator it = set.begin(); it != set.end(); ++it)
   3710         EXPECT_EQ(42, **it);
   3711 }
   3712 
   3713 TEST(HeapTest, RawPtrInHash)
   3714 {
   3715     rawPtrInHashHelper<HashSet<RawPtr<int> > >();
   3716     rawPtrInHashHelper<ListHashSet<RawPtr<int> > >();
   3717     rawPtrInHashHelper<LinkedHashSet<RawPtr<int> > >();
   3718 }
   3719 
   3720 TEST(HeapTest, HeapTerminatedArray)
   3721 {
   3722     HeapStats initialHeapSize;
   3723     clearOutOldGarbage(&initialHeapSize);
   3724     IntWrapper::s_destructorCalls = 0;
   3725 
   3726     HeapTerminatedArray<TerminatedArrayItem>* arr = 0;
   3727 
   3728     const size_t prefixSize = 4;
   3729     const size_t suffixSize = 4;
   3730 
   3731     {
   3732         HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
   3733         builder.grow(prefixSize);
   3734         for (size_t i = 0; i < prefixSize; i++)
   3735             builder.append(TerminatedArrayItem(IntWrapper::create(i)));
   3736         arr = builder.release();
   3737     }
   3738 
   3739     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3740     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3741     EXPECT_EQ(prefixSize, arr->size());
   3742     for (size_t i = 0; i < prefixSize; i++)
   3743         EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
   3744 
   3745     {
   3746         HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
   3747         builder.grow(suffixSize);
   3748         for (size_t i = 0; i < suffixSize; i++)
   3749             builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i)));
   3750         arr = builder.release();
   3751     }
   3752 
   3753     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3754     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3755     EXPECT_EQ(prefixSize + suffixSize, arr->size());
   3756     for (size_t i = 0; i < prefixSize + suffixSize; i++)
   3757         EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
   3758 
   3759     {
   3760         Persistent<HeapTerminatedArray<TerminatedArrayItem> > persistentArr = arr;
   3761         arr = 0;
   3762         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3763         arr = persistentArr.get();
   3764         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3765         EXPECT_EQ(prefixSize + suffixSize, arr->size());
   3766         for (size_t i = 0; i < prefixSize + suffixSize; i++)
   3767             EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value()));
   3768     }
   3769 
   3770     arr = 0;
   3771     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3772     EXPECT_EQ(8, IntWrapper::s_destructorCalls);
   3773 }
   3774 
   3775 TEST(HeapTest, HeapLinkedStack)
   3776 {
   3777     HeapStats initialHeapSize;
   3778     clearOutOldGarbage(&initialHeapSize);
   3779     IntWrapper::s_destructorCalls = 0;
   3780 
   3781     HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<TerminatedArrayItem>();
   3782 
   3783     const size_t stackSize = 10;
   3784 
   3785     for (size_t i = 0; i < stackSize; i++)
   3786         stack->push(TerminatedArrayItem(IntWrapper::create(i)));
   3787 
   3788     Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3789     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3790     EXPECT_EQ(stackSize, stack->size());
   3791     while (!stack->isEmpty()) {
   3792         EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()->value()));
   3793         stack->pop();
   3794     }
   3795 
   3796     Persistent<HeapLinkedStack<TerminatedArrayItem> > pStack = stack;
   3797 
   3798     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3799     EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls));
   3800     EXPECT_EQ(0u, pStack->size());
   3801 }
   3802 
   3803 TEST(HeapTest, AllocationDuringFinalization)
   3804 {
   3805     HeapStats initialHeapSize;
   3806     clearOutOldGarbage(&initialHeapSize);
   3807     IntWrapper::s_destructorCalls = 0;
   3808     OneKiloByteObject::s_destructorCalls = 0;
   3809 
   3810     Persistent<IntWrapper> wrapper;
   3811     new FinalizationAllocator(&wrapper);
   3812 
   3813     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3814     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3815     // Check that the wrapper allocated during finalization is not
   3816     // swept away and zapped later in the same sweeping phase.
   3817     EXPECT_EQ(42, wrapper->value());
   3818 
   3819     wrapper.clear();
   3820     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3821     EXPECT_EQ(10, IntWrapper::s_destructorCalls);
   3822     EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls);
   3823 }
   3824 
   3825 class SimpleClassWithDestructor {
   3826 public:
   3827     SimpleClassWithDestructor() { }
   3828     ~SimpleClassWithDestructor()
   3829     {
   3830         s_wasDestructed = true;
   3831     }
   3832     static bool s_wasDestructed;
   3833 };
   3834 
   3835 bool SimpleClassWithDestructor::s_wasDestructed;
   3836 
   3837 class RefCountedWithDestructor : public RefCounted<RefCountedWithDestructor> {
   3838 public:
   3839     RefCountedWithDestructor() { }
   3840     ~RefCountedWithDestructor()
   3841     {
   3842         s_wasDestructed = true;
   3843     }
   3844     static bool s_wasDestructed;
   3845 };
   3846 
   3847 bool RefCountedWithDestructor::s_wasDestructed;
   3848 
   3849 template<typename Set>
   3850 void destructorsCalledOnGC(bool addLots)
   3851 {
   3852     RefCountedWithDestructor::s_wasDestructed = false;
   3853     {
   3854         Set set;
   3855         RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor();
   3856         set.add(adoptRef(hasDestructor));
   3857         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3858 
   3859         if (addLots) {
   3860             for (int i = 0; i < 1000; i++) {
   3861                 set.add(adoptRef(new RefCountedWithDestructor()));
   3862             }
   3863         }
   3864 
   3865         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3866         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   3867         EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3868     }
   3869     // The destructors of the sets don't call the destructors of the elements
   3870     // in the heap sets. You have to actually remove the elments, call clear()
   3871     // or have a GC to get the destructors called.
   3872     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3873     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3874     EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed);
   3875 }
   3876 
   3877 template<typename Set>
   3878 void destructorsCalledOnClear(bool addLots)
   3879 {
   3880     RefCountedWithDestructor::s_wasDestructed = false;
   3881     Set set;
   3882     RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor();
   3883     set.add(adoptRef(hasDestructor));
   3884     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3885 
   3886     if (addLots) {
   3887         for (int i = 0; i < 1000; i++) {
   3888             set.add(adoptRef(new RefCountedWithDestructor()));
   3889         }
   3890     }
   3891 
   3892     EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed);
   3893     set.clear();
   3894     EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed);
   3895 }
   3896 
   3897 TEST(HeapTest, DestructorsCalled)
   3898 {
   3899     HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map;
   3900     SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor();
   3901     map.add(hasDestructor, adoptPtr(hasDestructor));
   3902     SimpleClassWithDestructor::s_wasDestructed = false;
   3903     map.clear();
   3904     EXPECT_TRUE(SimpleClassWithDestructor::s_wasDestructed);
   3905 
   3906     destructorsCalledOnClear<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3907     destructorsCalledOnClear<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3908     destructorsCalledOnClear<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3909     destructorsCalledOnClear<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3910     destructorsCalledOnClear<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3911     destructorsCalledOnClear<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3912 
   3913     destructorsCalledOnGC<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3914     destructorsCalledOnGC<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3915     destructorsCalledOnGC<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(false);
   3916     destructorsCalledOnGC<HeapHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3917     destructorsCalledOnGC<HeapListHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3918     destructorsCalledOnGC<HeapLinkedHashSet<RefPtr<RefCountedWithDestructor> > >(true);
   3919 }
   3920 
   3921 class MixinA : public GarbageCollectedMixin {
   3922 public:
   3923     MixinA() : m_obj(IntWrapper::create(100)) { }
   3924     virtual void trace(Visitor* visitor)
   3925     {
   3926         visitor->trace(m_obj);
   3927     }
   3928     Member<IntWrapper> m_obj;
   3929 };
   3930 
   3931 class MixinB : public GarbageCollectedMixin {
   3932 public:
   3933     MixinB() : m_obj(IntWrapper::create(101)) { }
   3934     virtual void trace(Visitor* visitor)
   3935     {
   3936         visitor->trace(m_obj);
   3937     }
   3938     Member<IntWrapper> m_obj;
   3939 };
   3940 
   3941 class MultipleMixins : public GarbageCollected<MultipleMixins>, public MixinA, public MixinB {
   3942     USING_GARBAGE_COLLECTED_MIXIN(MultipleMixins);
   3943 public:
   3944     MultipleMixins() : m_obj(IntWrapper::create(102)) { }
   3945     virtual void trace(Visitor* visitor)
   3946     {
   3947         visitor->trace(m_obj);
   3948         MixinA::trace(visitor);
   3949         MixinB::trace(visitor);
   3950     }
   3951     Member<IntWrapper> m_obj;
   3952 };
   3953 
   3954 static const bool s_isMixinTrue = IsGarbageCollectedMixin<MultipleMixins>::value;
   3955 static const bool s_isMixinFalse = IsGarbageCollectedMixin<IntWrapper>::value;
   3956 
   3957 TEST(HeapTest, MultipleMixins)
   3958 {
   3959     EXPECT_TRUE(s_isMixinTrue);
   3960     EXPECT_FALSE(s_isMixinFalse);
   3961 
   3962     HeapStats initialHeapSize;
   3963     clearOutOldGarbage(&initialHeapSize);
   3964     IntWrapper::s_destructorCalls = 0;
   3965     MultipleMixins* obj = new MultipleMixins();
   3966     {
   3967         Persistent<MixinA> a = obj;
   3968         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3969         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3970     }
   3971     {
   3972         Persistent<MixinB> b = obj;
   3973         Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3974         EXPECT_EQ(0, IntWrapper::s_destructorCalls);
   3975     }
   3976     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   3977     EXPECT_EQ(3, IntWrapper::s_destructorCalls);
   3978 }
   3979 
   3980 class GCParkingThreadTester {
   3981 public:
   3982     static void test()
   3983     {
   3984         createThread(&sleeperMainFunc, 0, "SleepingThread");
   3985 
   3986         // Wait for the sleeper to run.
   3987         while (!s_sleeperRunning) {
   3988             yield();
   3989         }
   3990 
   3991         {
   3992             // Expect the first attempt to park the sleeping thread to fail
   3993             TestGCScope scope(ThreadState::NoHeapPointersOnStack);
   3994             EXPECT_FALSE(scope.allThreadsParked());
   3995         }
   3996 
   3997         s_sleeperDone = true;
   3998 
   3999         // Wait for the sleeper to finish.
   4000         while (s_sleeperRunning) {
   4001             // We enter the safepoint here since the sleeper thread will detach
   4002             // causing it to GC.
   4003             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
   4004             yield();
   4005         }
   4006         {
   4007             // Since the sleeper thread has detached this is the only thread.
   4008             TestGCScope scope(ThreadState::NoHeapPointersOnStack);
   4009             EXPECT_TRUE(scope.allThreadsParked());
   4010         }
   4011     }
   4012 
   4013 private:
   4014     static void sleeperMainFunc(void* data)
   4015     {
   4016         ThreadState::attach();
   4017         s_sleeperRunning = true;
   4018 
   4019         // Simulate a long running op that is not entering a safepoint.
   4020         while (!s_sleeperDone) {
   4021             yield();
   4022         }
   4023 
   4024         ThreadState::detach();
   4025         s_sleeperRunning = false;
   4026     }
   4027 
   4028     static volatile bool s_sleeperRunning;
   4029     static volatile bool s_sleeperDone;
   4030 };
   4031 
   4032 volatile bool GCParkingThreadTester::s_sleeperRunning = false;
   4033 volatile bool GCParkingThreadTester::s_sleeperDone = false;
   4034 
   4035 TEST(HeapTest, GCParkingTimeout)
   4036 {
   4037     GCParkingThreadTester::test();
   4038 }
   4039 
   4040 TEST(HeapTest, NeedsAdjustAndMark)
   4041 {
   4042     // class Mixin : public GarbageCollectedMixin {};
   4043     EXPECT_TRUE(NeedsAdjustAndMark<Mixin>::value);
   4044     EXPECT_TRUE(NeedsAdjustAndMark<const Mixin>::value);
   4045 
   4046     // class SimpleObject : public GarbageCollected<SimpleObject> {};
   4047     EXPECT_FALSE(NeedsAdjustAndMark<SimpleObject>::value);
   4048     EXPECT_FALSE(NeedsAdjustAndMark<const SimpleObject>::value);
   4049 
   4050     // class UseMixin : public SimpleObject, public Mixin {};
   4051     EXPECT_FALSE(NeedsAdjustAndMark<UseMixin>::value);
   4052     EXPECT_FALSE(NeedsAdjustAndMark<const UseMixin>::value);
   4053 }
   4054 
   4055 template<typename Set>
   4056 void setWithCustomWeaknessHandling()
   4057 {
   4058     typedef typename Set::iterator Iterator;
   4059     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
   4060     Persistent<Set> set1(new Set());
   4061     {
   4062         Set set2;
   4063         Set* set3 = new Set();
   4064         set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)));
   4065         set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)));
   4066         set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)));
   4067         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   4068         // The first set is pointed to from a persistent, so it's referenced, but
   4069         // the weak processing may have taken place.
   4070         if (set1->size()) {
   4071             Iterator i1 = set1->begin();
   4072             EXPECT_EQ(4, i1->first->value());
   4073             EXPECT_EQ(5, i1->second->value());
   4074         }
   4075         // The second set is on-stack, so its backing store must be referenced from
   4076         // the stack. That makes the weak references strong.
   4077         Iterator i2 = set2.begin();
   4078         EXPECT_EQ(0, i2->first->value());
   4079         EXPECT_EQ(1, i2->second->value());
   4080         // The third set is pointed to from the stack, so it's referenced, but the
   4081         // weak processing may have taken place.
   4082         if (set3->size()) {
   4083             Iterator i3 = set3->begin();
   4084             EXPECT_EQ(2, i3->first->value());
   4085             EXPECT_EQ(3, i3->second->value());
   4086         }
   4087     }
   4088     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4089     EXPECT_EQ(0u, set1->size());
   4090     set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt));
   4091     set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This one gets zapped at GC time because nothing holds the 103 alive.
   4092     set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103))); // This one gets zapped too.
   4093     set1->add(PairWithWeakHandling(livingInt, livingInt));
   4094     set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identical to the previous and doesn't add anything.
   4095     EXPECT_EQ(4u, set1->size());
   4096     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4097     EXPECT_EQ(2u, set1->size());
   4098     Iterator i1 = set1->begin();
   4099     EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt);
   4100     EXPECT_EQ(livingInt, i1->second);
   4101     ++i1;
   4102     EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt);
   4103     EXPECT_EQ(livingInt, i1->second);
   4104 }
   4105 
   4106 TEST(HeapTest, SetWithCustomWeaknessHandling)
   4107 {
   4108     setWithCustomWeaknessHandling<HeapHashSet<PairWithWeakHandling> >();
   4109     setWithCustomWeaknessHandling<HeapLinkedHashSet<PairWithWeakHandling> >();
   4110 }
   4111 
   4112 TEST(HeapTest, MapWithCustomWeaknessHandling)
   4113 {
   4114     typedef HeapHashMap<PairWithWeakHandling, RefPtr<OffHeapInt> > Map;
   4115     typedef Map::iterator Iterator;
   4116     HeapStats initialHeapSize;
   4117     clearOutOldGarbage(&initialHeapSize);
   4118     OffHeapInt::s_destructorCalls = 0;
   4119 
   4120     Persistent<Map> map1(new Map());
   4121     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
   4122     {
   4123         Map map2;
   4124         Map* map3 = new Map();
   4125         map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)), OffHeapInt::create(1001));
   4126         map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)), OffHeapInt::create(1002));
   4127         map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)), OffHeapInt::create(1003));
   4128         EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
   4129 
   4130         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   4131         // The first map2 is pointed to from a persistent, so it's referenced, but
   4132         // the weak processing may have taken place.
   4133         if (map1->size()) {
   4134             Iterator i1 = map1->begin();
   4135             EXPECT_EQ(4, i1->key.first->value());
   4136             EXPECT_EQ(5, i1->key.second->value());
   4137             EXPECT_EQ(1003, i1->value->value());
   4138         }
   4139         // The second map2 is on-stack, so its backing store must be referenced from
   4140         // the stack. That makes the weak references strong.
   4141         Iterator i2 = map2.begin();
   4142         EXPECT_EQ(0, i2->key.first->value());
   4143         EXPECT_EQ(1, i2->key.second->value());
   4144         EXPECT_EQ(1001, i2->value->value());
   4145         // The third map2 is pointed to from the stack, so it's referenced, but the
   4146         // weak processing may have taken place.
   4147         if (map3->size()) {
   4148             Iterator i3 = map3->begin();
   4149             EXPECT_EQ(2, i3->key.first->value());
   4150             EXPECT_EQ(3, i3->key.second->value());
   4151             EXPECT_EQ(1002, i3->value->value());
   4152         }
   4153     }
   4154     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4155 
   4156     EXPECT_EQ(0u, map1->size());
   4157     EXPECT_EQ(3, OffHeapInt::s_destructorCalls);
   4158 
   4159     OffHeapInt::s_destructorCalls = 0;
   4160 
   4161     map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapInt::create(2000));
   4162     map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapInt::create(2001)); // This one gets zapped at GC time because nothing holds the 103 alive.
   4163     map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103)), OffHeapInt::create(2002)); // This one gets zapped too.
   4164     RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003));
   4165     map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt);
   4166     map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one is identical to the previous and doesn't add anything.
   4167     dupeInt.clear();
   4168 
   4169     EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
   4170     EXPECT_EQ(4u, map1->size());
   4171     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4172     EXPECT_EQ(2, OffHeapInt::s_destructorCalls);
   4173     EXPECT_EQ(2u, map1->size());
   4174     Iterator i1 = map1->begin();
   4175     EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt);
   4176     EXPECT_EQ(livingInt, i1->key.second);
   4177     ++i1;
   4178     EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt);
   4179     EXPECT_EQ(livingInt, i1->key.second);
   4180 }
   4181 
   4182 TEST(HeapTest, MapWithCustomWeaknessHandling2)
   4183 {
   4184     typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map;
   4185     typedef Map::iterator Iterator;
   4186     HeapStats initialHeapSize;
   4187     clearOutOldGarbage(&initialHeapSize);
   4188     OffHeapInt::s_destructorCalls = 0;
   4189 
   4190     Persistent<Map> map1(new Map());
   4191     Persistent<IntWrapper> livingInt(IntWrapper::create(42));
   4192 
   4193     {
   4194         Map map2;
   4195         Map* map3 = new Map();
   4196         map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(1)));
   4197         map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create(3)));
   4198         map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create(5)));
   4199         EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
   4200 
   4201         Heap::collectGarbage(ThreadState::HeapPointersOnStack);
   4202         // The first map2 is pointed to from a persistent, so it's referenced, but
   4203         // the weak processing may have taken place.
   4204         if (map1->size()) {
   4205             Iterator i1 = map1->begin();
   4206             EXPECT_EQ(4, i1->value.first->value());
   4207             EXPECT_EQ(5, i1->value.second->value());
   4208             EXPECT_EQ(1003, i1->key->value());
   4209         }
   4210         // The second map2 is on-stack, so its backing store must be referenced from
   4211         // the stack. That makes the weak references strong.
   4212         Iterator i2 = map2.begin();
   4213         EXPECT_EQ(0, i2->value.first->value());
   4214         EXPECT_EQ(1, i2->value.second->value());
   4215         EXPECT_EQ(1001, i2->key->value());
   4216         // The third map2 is pointed to from the stack, so it's referenced, but the
   4217         // weak processing may have taken place.
   4218         if (map3->size()) {
   4219             Iterator i3 = map3->begin();
   4220             EXPECT_EQ(2, i3->value.first->value());
   4221             EXPECT_EQ(3, i3->value.second->value());
   4222             EXPECT_EQ(1002, i3->key->value());
   4223         }
   4224     }
   4225     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4226 
   4227     EXPECT_EQ(0u, map1->size());
   4228     EXPECT_EQ(3, OffHeapInt::s_destructorCalls);
   4229 
   4230     OffHeapInt::s_destructorCalls = 0;
   4231 
   4232     map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(103), livingInt));
   4233     map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This one gets zapped at GC time because nothing holds the 103 alive.
   4234     map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103))); // This one gets zapped too.
   4235     RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003));
   4236     map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt));
   4237     map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one is identical to the previous and doesn't add anything.
   4238     dupeInt.clear();
   4239 
   4240     EXPECT_EQ(0, OffHeapInt::s_destructorCalls);
   4241     EXPECT_EQ(4u, map1->size());
   4242     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4243     EXPECT_EQ(2, OffHeapInt::s_destructorCalls);
   4244     EXPECT_EQ(2u, map1->size());
   4245     Iterator i1 = map1->begin();
   4246     EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt);
   4247     EXPECT_EQ(livingInt, i1->value.second);
   4248     ++i1;
   4249     EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt);
   4250     EXPECT_EQ(livingInt, i1->value.second);
   4251 }
   4252 
   4253 TEST(HeapTest, Bind)
   4254 {
   4255     Closure closure = bind(&Bar::trace, Bar::create(), static_cast<Visitor*>(0));
   4256     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4257     // The closure should have a persistent handle to the Bar.
   4258     EXPECT_EQ(1u, Bar::s_live);
   4259 
   4260     Closure closure2 = bind(&Bar::trace, RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0));
   4261     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4262     // The closure should have a persistent handle to the Bar.
   4263     EXPECT_EQ(2u, Bar::s_live);
   4264     // RawPtr<OffHeapInt> should not make Persistent.
   4265     Closure closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt>(OffHeapInt::create(1).get()));
   4266 
   4267     UseMixin::s_traceCount = 0;
   4268     Mixin* mixin = UseMixin::create();
   4269     Closure mixinClosure = bind(&Mixin::trace, mixin, static_cast<Visitor*>(0));
   4270     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4271     // The closure should have a persistent handle to the mixin.
   4272     EXPECT_EQ(1, UseMixin::s_traceCount);
   4273 }
   4274 
   4275 typedef HeapHashSet<WeakMember<IntWrapper> > WeakSet;
   4276 
   4277 // These special traits will remove a set from a map when the set is empty.
   4278 struct EmptyClearingHastSetTraits : HashTraits<WeakSet> {
   4279     static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCollections;
   4280     static bool shouldRemoveFromCollection(Visitor* visitor, WeakSet& set)
   4281     {
   4282         return set.isEmpty(); // Remove this set from any maps it is in.
   4283     }
   4284     static void traceInCollection(Visitor* visitor, WeakSet& set, WebCore::ShouldWeakPointersBeMarkedStrongly strongify)
   4285     {
   4286         // We just trace normally, which will invoke the normal weak handling
   4287         // of the set, removing individual items.
   4288         set.trace(visitor);
   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>, EmptyClearingHastSetTraits> 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     if (map->size() == 1u) {
   4338         // If the weak processing for the set ran after the weak processing for
   4339         // the map, then the set was not empty, and so the entry in the map was
   4340         // not removed yet.
   4341         WeakSet& set = map->begin()->value;
   4342         EXPECT_EQ(0u, set.size());
   4343     }
   4344 
   4345     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
   4346     EXPECT_EQ(0u, map->size());
   4347 }
   4348 
   4349 } // WebCore namespace
   4350