| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "platform/heap/Visitor.h" | 41 #include "platform/heap/Visitor.h" |
| 42 #include "public/platform/Platform.h" | 42 #include "public/platform/Platform.h" |
| 43 #include "public/platform/WebTraceLocation.h" | 43 #include "public/platform/WebTraceLocation.h" |
| 44 #include "wtf/HashTraits.h" | 44 #include "wtf/HashTraits.h" |
| 45 #include "wtf/LinkedHashSet.h" | 45 #include "wtf/LinkedHashSet.h" |
| 46 | 46 |
| 47 #include <gtest/gtest.h> | 47 #include <gtest/gtest.h> |
| 48 | 48 |
| 49 namespace blink { | 49 namespace blink { |
| 50 | 50 |
| 51 static void preciselyCollectGarbage() |
| 52 { |
| 53 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
| 54 } |
| 55 |
| 56 static void conservativelyCollectGarbage() |
| 57 { |
| 58 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
| 59 } |
| 60 |
| 51 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { | 61 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { |
| 52 public: | 62 public: |
| 53 static IntWrapper* create(int x) | 63 static IntWrapper* create(int x) |
| 54 { | 64 { |
| 55 return new IntWrapper(x); | 65 return new IntWrapper(x); |
| 56 } | 66 } |
| 57 | 67 |
| 58 virtual ~IntWrapper() | 68 virtual ~IntWrapper() |
| 59 { | 69 { |
| 60 ++s_destructorCalls; | 70 ++s_destructorCalls; |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 static const int s_arraySize = 1000; | 413 static const int s_arraySize = 1000; |
| 404 int8_t m_array[s_arraySize]; | 414 int8_t m_array[s_arraySize]; |
| 405 }; | 415 }; |
| 406 | 416 |
| 407 // Do several GCs to make sure that later GCs don't free up old memory from | 417 // Do several GCs to make sure that later GCs don't free up old memory from |
| 408 // previously run tests in this process. | 418 // previously run tests in this process. |
| 409 static void clearOutOldGarbage() | 419 static void clearOutOldGarbage() |
| 410 { | 420 { |
| 411 while (true) { | 421 while (true) { |
| 412 size_t used = Heap::objectPayloadSizeForTesting(); | 422 size_t used = Heap::objectPayloadSizeForTesting(); |
| 413 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 423 preciselyCollectGarbage(); |
| 414 if (Heap::objectPayloadSizeForTesting() >= used) | 424 if (Heap::objectPayloadSizeForTesting() >= used) |
| 415 break; | 425 break; |
| 416 } | 426 } |
| 417 } | 427 } |
| 418 | 428 |
| 419 class OffHeapInt : public RefCounted<OffHeapInt> { | 429 class OffHeapInt : public RefCounted<OffHeapInt> { |
| 420 public: | 430 public: |
| 421 static RefPtr<OffHeapInt> create(int x) | 431 static RefPtr<OffHeapInt> create(int x) |
| 422 { | 432 { |
| 423 return adoptRef(new OffHeapInt(x)); | 433 return adoptRef(new OffHeapInt(x)); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 for (int i = 0; i < numberOfAllocations; i++) { | 533 for (int i = 0; i < numberOfAllocations; i++) { |
| 524 wrapper = IntWrapper::create(0x0bbac0de); | 534 wrapper = IntWrapper::create(0x0bbac0de); |
| 525 if (!(i % 10)) { | 535 if (!(i % 10)) { |
| 526 globalPersistent = createGlobalPersistent(0x0ed0cabb); | 536 globalPersistent = createGlobalPersistent(0x0ed0cabb); |
| 527 } | 537 } |
| 528 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 538 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
| 529 Platform::current()->yieldCurrentThread(); | 539 Platform::current()->yieldCurrentThread(); |
| 530 } | 540 } |
| 531 | 541 |
| 532 if (gcCount < gcPerThread) { | 542 if (gcCount < gcPerThread) { |
| 533 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGC); | 543 preciselyCollectGarbage(); |
| 534 gcCount++; | 544 gcCount++; |
| 535 atomicIncrement(&m_gcCount); | 545 atomicIncrement(&m_gcCount); |
| 536 } | 546 } |
| 537 | 547 |
| 538 // Taking snapshot shouldn't have any bad side effect. | 548 // Taking snapshot shouldn't have any bad side effect. |
| 539 // TODO(haraken): This snapshot GC causes crashes, so disable | 549 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 540 // it at the moment. Fix the crash and enable it. | 550 // it at the moment. Fix the crash and enable it. |
| 541 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
adState::TakeSnapshot, Heap::ForcedGC); | 551 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
adState::TakeSnapshot, Heap::ForcedGC); |
| 542 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); | 552 preciselyCollectGarbage(); |
| 543 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 553 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
| 544 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 554 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
| 545 } | 555 } |
| 546 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 556 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
| 547 Platform::current()->yieldCurrentThread(); | 557 Platform::current()->yieldCurrentThread(); |
| 548 } | 558 } |
| 549 | 559 |
| 550 // Intentionally leak the cross-thread persistent so as to verify | 560 // Intentionally leak the cross-thread persistent so as to verify |
| 551 // that later GCs correctly handle cross-thread persistents that | 561 // that later GCs correctly handle cross-thread persistents that |
| 552 // refer to finalized objects after their heaps have been detached | 562 // refer to finalized objects after their heaps have been detached |
| (...skipping 25 matching lines...) Expand all Loading... |
| 578 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 588 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
| 579 | 589 |
| 580 for (int i = 0; i < numberOfAllocations; i++) { | 590 for (int i = 0; i < numberOfAllocations; i++) { |
| 581 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 591 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| 582 weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 592 weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| 583 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 593 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
| 584 Platform::current()->yieldCurrentThread(); | 594 Platform::current()->yieldCurrentThread(); |
| 585 } | 595 } |
| 586 | 596 |
| 587 if (gcCount < gcPerThread) { | 597 if (gcCount < gcPerThread) { |
| 588 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGC); | 598 preciselyCollectGarbage(); |
| 589 gcCount++; | 599 gcCount++; |
| 590 atomicIncrement(&m_gcCount); | 600 atomicIncrement(&m_gcCount); |
| 591 } | 601 } |
| 592 | 602 |
| 593 // Taking snapshot shouldn't have any bad side effect. | 603 // Taking snapshot shouldn't have any bad side effect. |
| 594 // TODO(haraken): This snapshot GC causes crashes, so disable | 604 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 595 // it at the moment. Fix the crash and enable it. | 605 // it at the moment. Fix the crash and enable it. |
| 596 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
adState::TakeSnapshot, Heap::ForcedGC); | 606 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
adState::TakeSnapshot, Heap::ForcedGC); |
| 597 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); | 607 preciselyCollectGarbage(); |
| 598 EXPECT_TRUE(weakMap->isEmpty()); | 608 EXPECT_TRUE(weakMap->isEmpty()); |
| 599 EXPECT_TRUE(weakMap2.isEmpty()); | 609 EXPECT_TRUE(weakMap2.isEmpty()); |
| 600 } | 610 } |
| 601 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 611 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
| 602 Platform::current()->yieldCurrentThread(); | 612 Platform::current()->yieldCurrentThread(); |
| 603 } | 613 } |
| 604 ThreadState::detach(); | 614 ThreadState::detach(); |
| 605 atomicDecrement(&m_threadsToFinish); | 615 atomicDecrement(&m_threadsToFinish); |
| 606 } | 616 } |
| 607 }; | 617 }; |
| (...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 { | 1409 { |
| 1400 #if !ENABLE(OILPAN) | 1410 #if !ENABLE(OILPAN) |
| 1401 m_pointsBack->setBackPointer(0); | 1411 m_pointsBack->setBackPointer(0); |
| 1402 #endif | 1412 #endif |
| 1403 --s_aliveCount; | 1413 --s_aliveCount; |
| 1404 } | 1414 } |
| 1405 | 1415 |
| 1406 void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* poin
tsBack, int superClassCount) | 1416 void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* poin
tsBack, int superClassCount) |
| 1407 { | 1417 { |
| 1408 RefPtrWillBeRawPtr<SuperClass> target = targetPass; | 1418 RefPtrWillBeRawPtr<SuperClass> target = targetPass; |
| 1409 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 1419 conservativelyCollectGarbage(); |
| 1410 EXPECT_EQ(pointsBack, target->pointsBack()); | 1420 EXPECT_EQ(pointsBack, target->pointsBack()); |
| 1411 EXPECT_EQ(superClassCount, SuperClass::s_aliveCount); | 1421 EXPECT_EQ(superClassCount, SuperClass::s_aliveCount); |
| 1412 } | 1422 } |
| 1413 | 1423 |
| 1414 DEFINE_INLINE_VIRTUAL_TRACE() | 1424 DEFINE_INLINE_VIRTUAL_TRACE() |
| 1415 { | 1425 { |
| 1416 visitor->trace(m_pointsBack); | 1426 visitor->trace(m_pointsBack); |
| 1417 } | 1427 } |
| 1418 | 1428 |
| 1419 PointsBack* pointsBack() const { return m_pointsBack.get(); } | 1429 PointsBack* pointsBack() const { return m_pointsBack.get(); } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 | 1687 |
| 1678 private: | 1688 private: |
| 1679 Persistent<IntWrapper>* m_wrapper; | 1689 Persistent<IntWrapper>* m_wrapper; |
| 1680 }; | 1690 }; |
| 1681 | 1691 |
| 1682 TEST(HeapTest, Transition) | 1692 TEST(HeapTest, Transition) |
| 1683 { | 1693 { |
| 1684 { | 1694 { |
| 1685 RefPtrWillBePersistent<TransitionRefCounted> refCounted = TransitionRefC
ounted::create(); | 1695 RefPtrWillBePersistent<TransitionRefCounted> refCounted = TransitionRefC
ounted::create(); |
| 1686 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); | 1696 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); |
| 1687 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 1697 preciselyCollectGarbage(); |
| 1688 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); | 1698 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); |
| 1689 } | 1699 } |
| 1690 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1700 preciselyCollectGarbage(); |
| 1691 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); | 1701 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); |
| 1692 | 1702 |
| 1693 RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create(); | 1703 RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create(); |
| 1694 RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create(); | 1704 RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create(); |
| 1695 RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBac
k1); | 1705 RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBac
k1); |
| 1696 RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2); | 1706 RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2); |
| 1697 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1707 EXPECT_EQ(2, PointsBack::s_aliveCount); |
| 1698 EXPECT_EQ(2, SuperClass::s_aliveCount); | 1708 EXPECT_EQ(2, SuperClass::s_aliveCount); |
| 1699 EXPECT_EQ(1, SubClass::s_aliveCount); | 1709 EXPECT_EQ(1, SubClass::s_aliveCount); |
| 1700 EXPECT_EQ(1, SubData::s_aliveCount); | 1710 EXPECT_EQ(1, SubData::s_aliveCount); |
| 1701 | 1711 |
| 1702 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1712 preciselyCollectGarbage(); |
| 1703 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); | 1713 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); |
| 1704 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1714 EXPECT_EQ(2, PointsBack::s_aliveCount); |
| 1705 EXPECT_EQ(2, SuperClass::s_aliveCount); | 1715 EXPECT_EQ(2, SuperClass::s_aliveCount); |
| 1706 EXPECT_EQ(1, SubClass::s_aliveCount); | 1716 EXPECT_EQ(1, SubClass::s_aliveCount); |
| 1707 EXPECT_EQ(1, SubData::s_aliveCount); | 1717 EXPECT_EQ(1, SubData::s_aliveCount); |
| 1708 | 1718 |
| 1709 superClass->doStuff(superClass.release(), pointsBack1.get(), 2); | 1719 superClass->doStuff(superClass.release(), pointsBack1.get(), 2); |
| 1710 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1720 preciselyCollectGarbage(); |
| 1711 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1721 EXPECT_EQ(2, PointsBack::s_aliveCount); |
| 1712 EXPECT_EQ(1, SuperClass::s_aliveCount); | 1722 EXPECT_EQ(1, SuperClass::s_aliveCount); |
| 1713 EXPECT_EQ(1, SubClass::s_aliveCount); | 1723 EXPECT_EQ(1, SubClass::s_aliveCount); |
| 1714 EXPECT_EQ(1, SubData::s_aliveCount); | 1724 EXPECT_EQ(1, SubData::s_aliveCount); |
| 1715 EXPECT_EQ(0, pointsBack1->backPointer()); | 1725 EXPECT_EQ(0, pointsBack1->backPointer()); |
| 1716 | 1726 |
| 1717 pointsBack1.release(); | 1727 pointsBack1.release(); |
| 1718 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1728 preciselyCollectGarbage(); |
| 1719 EXPECT_EQ(1, PointsBack::s_aliveCount); | 1729 EXPECT_EQ(1, PointsBack::s_aliveCount); |
| 1720 EXPECT_EQ(1, SuperClass::s_aliveCount); | 1730 EXPECT_EQ(1, SuperClass::s_aliveCount); |
| 1721 EXPECT_EQ(1, SubClass::s_aliveCount); | 1731 EXPECT_EQ(1, SubClass::s_aliveCount); |
| 1722 EXPECT_EQ(1, SubData::s_aliveCount); | 1732 EXPECT_EQ(1, SubData::s_aliveCount); |
| 1723 | 1733 |
| 1724 subClass->doStuff(subClass.release(), pointsBack2.get(), 1); | 1734 subClass->doStuff(subClass.release(), pointsBack2.get(), 1); |
| 1725 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1735 preciselyCollectGarbage(); |
| 1726 EXPECT_EQ(1, PointsBack::s_aliveCount); | 1736 EXPECT_EQ(1, PointsBack::s_aliveCount); |
| 1727 EXPECT_EQ(0, SuperClass::s_aliveCount); | 1737 EXPECT_EQ(0, SuperClass::s_aliveCount); |
| 1728 EXPECT_EQ(0, SubClass::s_aliveCount); | 1738 EXPECT_EQ(0, SubClass::s_aliveCount); |
| 1729 EXPECT_EQ(0, SubData::s_aliveCount); | 1739 EXPECT_EQ(0, SubData::s_aliveCount); |
| 1730 EXPECT_EQ(0, pointsBack2->backPointer()); | 1740 EXPECT_EQ(0, pointsBack2->backPointer()); |
| 1731 | 1741 |
| 1732 pointsBack2.release(); | 1742 pointsBack2.release(); |
| 1733 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1743 preciselyCollectGarbage(); |
| 1734 EXPECT_EQ(0, PointsBack::s_aliveCount); | 1744 EXPECT_EQ(0, PointsBack::s_aliveCount); |
| 1735 EXPECT_EQ(0, SuperClass::s_aliveCount); | 1745 EXPECT_EQ(0, SuperClass::s_aliveCount); |
| 1736 EXPECT_EQ(0, SubClass::s_aliveCount); | 1746 EXPECT_EQ(0, SubClass::s_aliveCount); |
| 1737 EXPECT_EQ(0, SubData::s_aliveCount); | 1747 EXPECT_EQ(0, SubData::s_aliveCount); |
| 1738 | 1748 |
| 1739 EXPECT_TRUE(superClass == subClass); | 1749 EXPECT_TRUE(superClass == subClass); |
| 1740 } | 1750 } |
| 1741 | 1751 |
| 1742 TEST(HeapTest, Threading) | 1752 TEST(HeapTest, Threading) |
| 1743 { | 1753 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 | 1790 |
| 1781 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1791 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); |
| 1782 if (testPagesAllocated) | 1792 if (testPagesAllocated) |
| 1783 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); | 1793 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); |
| 1784 | 1794 |
| 1785 EXPECT_EQ(alloc32->get(0), 40); | 1795 EXPECT_EQ(alloc32->get(0), 40); |
| 1786 EXPECT_EQ(alloc32->get(31), 40); | 1796 EXPECT_EQ(alloc32->get(31), 40); |
| 1787 EXPECT_EQ(alloc64->get(0), 27); | 1797 EXPECT_EQ(alloc64->get(0), 27); |
| 1788 EXPECT_EQ(alloc64->get(63), 27); | 1798 EXPECT_EQ(alloc64->get(63), 27); |
| 1789 | 1799 |
| 1790 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 1800 conservativelyCollectGarbage(); |
| 1791 | 1801 |
| 1792 EXPECT_EQ(alloc32->get(0), 40); | 1802 EXPECT_EQ(alloc32->get(0), 40); |
| 1793 EXPECT_EQ(alloc32->get(31), 40); | 1803 EXPECT_EQ(alloc32->get(31), 40); |
| 1794 EXPECT_EQ(alloc64->get(0), 27); | 1804 EXPECT_EQ(alloc64->get(0), 27); |
| 1795 EXPECT_EQ(alloc64->get(63), 27); | 1805 EXPECT_EQ(alloc64->get(63), 27); |
| 1796 } | 1806 } |
| 1797 | 1807 |
| 1798 clearOutOldGarbage(); | 1808 clearOutOldGarbage(); |
| 1799 size_t total = 0; | 1809 size_t total = 0; |
| 1800 size_t slack = 0; | 1810 size_t slack = 0; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 EXPECT_EQ(42, array->at(42)); | 1901 EXPECT_EQ(42, array->at(42)); |
| 1892 EXPECT_EQ(0, array->at(128)); | 1902 EXPECT_EQ(0, array->at(128)); |
| 1893 EXPECT_EQ(999 % 128, array->at(999)); | 1903 EXPECT_EQ(999 % 128, array->at(999)); |
| 1894 } | 1904 } |
| 1895 | 1905 |
| 1896 TEST(HeapTest, SimplePersistent) | 1906 TEST(HeapTest, SimplePersistent) |
| 1897 { | 1907 { |
| 1898 Persistent<TraceCounter> traceCounter = TraceCounter::create(); | 1908 Persistent<TraceCounter> traceCounter = TraceCounter::create(); |
| 1899 EXPECT_EQ(0, traceCounter->traceCount()); | 1909 EXPECT_EQ(0, traceCounter->traceCount()); |
| 1900 | 1910 |
| 1901 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1911 preciselyCollectGarbage(); |
| 1902 EXPECT_EQ(1, traceCounter->traceCount()); | 1912 EXPECT_EQ(1, traceCounter->traceCount()); |
| 1903 | 1913 |
| 1904 Persistent<ClassWithMember> classWithMember = ClassWithMember::create(); | 1914 Persistent<ClassWithMember> classWithMember = ClassWithMember::create(); |
| 1905 EXPECT_EQ(0, classWithMember->traceCount()); | 1915 EXPECT_EQ(0, classWithMember->traceCount()); |
| 1906 | 1916 |
| 1907 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1917 preciselyCollectGarbage(); |
| 1908 EXPECT_EQ(1, classWithMember->traceCount()); | 1918 EXPECT_EQ(1, classWithMember->traceCount()); |
| 1909 EXPECT_EQ(2, traceCounter->traceCount()); | 1919 EXPECT_EQ(2, traceCounter->traceCount()); |
| 1910 } | 1920 } |
| 1911 | 1921 |
| 1912 TEST(HeapTest, SimpleFinalization) | 1922 TEST(HeapTest, SimpleFinalization) |
| 1913 { | 1923 { |
| 1914 { | 1924 { |
| 1915 Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::cre
ate(); | 1925 Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::cre
ate(); |
| 1916 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1926 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1917 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 1927 preciselyCollectGarbage(); |
| 1918 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1928 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1919 } | 1929 } |
| 1920 | 1930 |
| 1921 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1931 preciselyCollectGarbage(); |
| 1922 EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls); | 1932 EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls); |
| 1923 } | 1933 } |
| 1924 | 1934 |
| 1925 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 1935 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 1926 TEST(HeapTest, FreelistReuse) | 1936 TEST(HeapTest, FreelistReuse) |
| 1927 { | 1937 { |
| 1928 clearOutOldGarbage(); | 1938 clearOutOldGarbage(); |
| 1929 | 1939 |
| 1930 for (int i = 0; i < 100; i++) | 1940 for (int i = 0; i < 100; i++) |
| 1931 new IntWrapper(i); | 1941 new IntWrapper(i); |
| 1932 IntWrapper* p1 = new IntWrapper(100); | 1942 IntWrapper* p1 = new IntWrapper(100); |
| 1933 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1943 preciselyCollectGarbage(); |
| 1934 // In non-production builds, we delay reusing freed memory for at least | 1944 // In non-production builds, we delay reusing freed memory for at least |
| 1935 // one GC cycle. | 1945 // one GC cycle. |
| 1936 for (int i = 0; i < 100; i++) { | 1946 for (int i = 0; i < 100; i++) { |
| 1937 IntWrapper* p2 = new IntWrapper(i); | 1947 IntWrapper* p2 = new IntWrapper(i); |
| 1938 EXPECT_NE(p1, p2); | 1948 EXPECT_NE(p1, p2); |
| 1939 } | 1949 } |
| 1940 | 1950 |
| 1941 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1951 preciselyCollectGarbage(); |
| 1942 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1952 preciselyCollectGarbage(); |
| 1943 // Now the freed memory in the first GC should be reused. | 1953 // Now the freed memory in the first GC should be reused. |
| 1944 bool reusedMemoryFound = false; | 1954 bool reusedMemoryFound = false; |
| 1945 for (int i = 0; i < 10000; i++) { | 1955 for (int i = 0; i < 10000; i++) { |
| 1946 IntWrapper* p2 = new IntWrapper(i); | 1956 IntWrapper* p2 = new IntWrapper(i); |
| 1947 if (p1 == p2) { | 1957 if (p1 == p2) { |
| 1948 reusedMemoryFound = true; | 1958 reusedMemoryFound = true; |
| 1949 break; | 1959 break; |
| 1950 } | 1960 } |
| 1951 } | 1961 } |
| 1952 EXPECT_TRUE(reusedMemoryFound); | 1962 EXPECT_TRUE(reusedMemoryFound); |
| 1953 } | 1963 } |
| 1954 #endif | 1964 #endif |
| 1955 | 1965 |
| 1956 #if ENABLE(LAZY_SWEEPING) | 1966 #if ENABLE(LAZY_SWEEPING) |
| 1957 TEST(HeapTest, LazySweepingPages) | 1967 TEST(HeapTest, LazySweepingPages) |
| 1958 { | 1968 { |
| 1959 clearOutOldGarbage(); | 1969 clearOutOldGarbage(); |
| 1960 | 1970 |
| 1961 SimpleFinalizedObject::s_destructorCalls = 0; | 1971 SimpleFinalizedObject::s_destructorCalls = 0; |
| 1962 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1972 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1963 for (int i = 0; i < 1000; i++) | 1973 for (int i = 0; i < 1000; i++) |
| 1964 SimpleFinalizedObject::create(); | 1974 SimpleFinalizedObject::create(); |
| 1965 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); | 1975 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
| 1966 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1976 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1967 for (int i = 0; i < 10000; i++) | 1977 for (int i = 0; i < 10000; i++) |
| 1968 SimpleFinalizedObject::create(); | 1978 SimpleFinalizedObject::create(); |
| 1969 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); | 1979 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); |
| 1970 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1980 preciselyCollectGarbage(); |
| 1971 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); | 1981 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); |
| 1972 } | 1982 } |
| 1973 | 1983 |
| 1974 TEST(HeapTest, LazySweepingLargeObjectPages) | 1984 TEST(HeapTest, LazySweepingLargeObjectPages) |
| 1975 { | 1985 { |
| 1976 clearOutOldGarbage(); | 1986 clearOutOldGarbage(); |
| 1977 | 1987 |
| 1978 // Create free lists that can be reused for IntWrappers created in | 1988 // Create free lists that can be reused for IntWrappers created in |
| 1979 // LargeHeapObject::create(). | 1989 // LargeHeapObject::create(). |
| 1980 Persistent<IntWrapper> p1 = new IntWrapper(1); | 1990 Persistent<IntWrapper> p1 = new IntWrapper(1); |
| 1981 for (int i = 0; i < 100; i++) { | 1991 for (int i = 0; i < 100; i++) { |
| 1982 new IntWrapper(i); | 1992 new IntWrapper(i); |
| 1983 } | 1993 } |
| 1984 Persistent<IntWrapper> p2 = new IntWrapper(2); | 1994 Persistent<IntWrapper> p2 = new IntWrapper(2); |
| 1985 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1995 preciselyCollectGarbage(); |
| 1986 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 1996 preciselyCollectGarbage(); |
| 1987 | 1997 |
| 1988 LargeHeapObject::s_destructorCalls = 0; | 1998 LargeHeapObject::s_destructorCalls = 0; |
| 1989 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 1999 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 1990 for (int i = 0; i < 10; i++) | 2000 for (int i = 0; i < 10; i++) |
| 1991 LargeHeapObject::create(); | 2001 LargeHeapObject::create(); |
| 1992 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); | 2002 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
| 1993 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 2003 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 1994 for (int i = 0; i < 10; i++) { | 2004 for (int i = 0; i < 10; i++) { |
| 1995 LargeHeapObject::create(); | 2005 LargeHeapObject::create(); |
| 1996 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); | 2006 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); |
| 1997 } | 2007 } |
| 1998 LargeHeapObject::create(); | 2008 LargeHeapObject::create(); |
| 1999 LargeHeapObject::create(); | 2009 LargeHeapObject::create(); |
| 2000 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2010 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2001 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); | 2011 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
| 2002 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2012 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2003 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2013 preciselyCollectGarbage(); |
| 2004 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); | 2014 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); |
| 2005 } | 2015 } |
| 2006 | 2016 |
| 2007 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
nalizedEagerObjectBase> { | 2017 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
nalizedEagerObjectBase> { |
| 2008 public: | 2018 public: |
| 2009 virtual ~SimpleFinalizedEagerObjectBase() { } | 2019 virtual ~SimpleFinalizedEagerObjectBase() { } |
| 2010 DEFINE_INLINE_TRACE() { } | 2020 DEFINE_INLINE_TRACE() { } |
| 2011 | 2021 |
| 2012 EAGERLY_FINALIZE(); | 2022 EAGERLY_FINALIZE(); |
| 2013 protected: | 2023 protected: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 HeapTestSubClass* t1 = HeapTestSubClass::create(); | 2096 HeapTestSubClass* t1 = HeapTestSubClass::create(); |
| 2087 HeapTestSubClass* t2 = HeapTestSubClass::create(); | 2097 HeapTestSubClass* t2 = HeapTestSubClass::create(); |
| 2088 HeapTestSuperClass* t3 = HeapTestSuperClass::create(); | 2098 HeapTestSuperClass* t3 = HeapTestSuperClass::create(); |
| 2089 // FIXME(oilpan): Ignore unused variables. | 2099 // FIXME(oilpan): Ignore unused variables. |
| 2090 (void)t1; | 2100 (void)t1; |
| 2091 (void)t2; | 2101 (void)t2; |
| 2092 (void)t3; | 2102 (void)t3; |
| 2093 } | 2103 } |
| 2094 // Nothing is marked so the GC should free everything and call | 2104 // Nothing is marked so the GC should free everything and call |
| 2095 // the finalizer on all three objects. | 2105 // the finalizer on all three objects. |
| 2096 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2106 preciselyCollectGarbage(); |
| 2097 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); | 2107 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); |
| 2098 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); | 2108 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); |
| 2099 // Destructors not called again when GCing again. | 2109 // Destructors not called again when GCing again. |
| 2100 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2110 preciselyCollectGarbage(); |
| 2101 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); | 2111 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); |
| 2102 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); | 2112 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); |
| 2103 } | 2113 } |
| 2104 | 2114 |
| 2105 TEST(HeapTest, TypedHeapSanity) | 2115 TEST(HeapTest, TypedHeapSanity) |
| 2106 { | 2116 { |
| 2107 // We use TraceCounter for allocating an object on the general heap. | 2117 // We use TraceCounter for allocating an object on the general heap. |
| 2108 Persistent<TraceCounter> generalHeapObject = TraceCounter::create(); | 2118 Persistent<TraceCounter> generalHeapObject = TraceCounter::create(); |
| 2109 Persistent<IntNode> typedHeapObject = IntNode::create(0); | 2119 Persistent<IntNode> typedHeapObject = IntNode::create(0); |
| 2110 EXPECT_NE(pageFromObject(generalHeapObject.get()), | 2120 EXPECT_NE(pageFromObject(generalHeapObject.get()), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2124 } | 2134 } |
| 2125 | 2135 |
| 2126 TEST(HeapTest, Members) | 2136 TEST(HeapTest, Members) |
| 2127 { | 2137 { |
| 2128 Bar::s_live = 0; | 2138 Bar::s_live = 0; |
| 2129 { | 2139 { |
| 2130 Persistent<Baz> h1; | 2140 Persistent<Baz> h1; |
| 2131 Persistent<Baz> h2; | 2141 Persistent<Baz> h2; |
| 2132 { | 2142 { |
| 2133 h1 = Baz::create(Bar::create()); | 2143 h1 = Baz::create(Bar::create()); |
| 2134 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 2144 preciselyCollectGarbage(); |
| 2135 EXPECT_EQ(1u, Bar::s_live); | 2145 EXPECT_EQ(1u, Bar::s_live); |
| 2136 h2 = Baz::create(Bar::create()); | 2146 h2 = Baz::create(Bar::create()); |
| 2137 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 2147 preciselyCollectGarbage(); |
| 2138 EXPECT_EQ(2u, Bar::s_live); | 2148 EXPECT_EQ(2u, Bar::s_live); |
| 2139 } | 2149 } |
| 2140 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2150 preciselyCollectGarbage(); |
| 2141 EXPECT_EQ(2u, Bar::s_live); | 2151 EXPECT_EQ(2u, Bar::s_live); |
| 2142 h1->clear(); | 2152 h1->clear(); |
| 2143 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2153 preciselyCollectGarbage(); |
| 2144 EXPECT_EQ(1u, Bar::s_live); | 2154 EXPECT_EQ(1u, Bar::s_live); |
| 2145 } | 2155 } |
| 2146 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2156 preciselyCollectGarbage(); |
| 2147 EXPECT_EQ(0u, Bar::s_live); | 2157 EXPECT_EQ(0u, Bar::s_live); |
| 2148 } | 2158 } |
| 2149 | 2159 |
| 2150 TEST(HeapTest, MarkTest) | 2160 TEST(HeapTest, MarkTest) |
| 2151 { | 2161 { |
| 2152 { | 2162 { |
| 2153 Bar::s_live = 0; | 2163 Bar::s_live = 0; |
| 2154 Persistent<Bar> bar = Bar::create(); | 2164 Persistent<Bar> bar = Bar::create(); |
| 2155 ASSERT(ThreadState::current()->findPageFromAddress(bar)); | 2165 ASSERT(ThreadState::current()->findPageFromAddress(bar)); |
| 2156 EXPECT_EQ(1u, Bar::s_live); | 2166 EXPECT_EQ(1u, Bar::s_live); |
| 2157 { | 2167 { |
| 2158 Foo* foo = Foo::create(bar); | 2168 Foo* foo = Foo::create(bar); |
| 2159 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 2169 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
| 2160 EXPECT_EQ(2u, Bar::s_live); | 2170 EXPECT_EQ(2u, Bar::s_live); |
| 2161 EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Addre
ss>(bar.get())); | 2171 EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Addre
ss>(bar.get())); |
| 2162 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); | 2172 conservativelyCollectGarbage(); |
| 2163 EXPECT_TRUE(foo != bar); // To make sure foo is kept alive. | 2173 EXPECT_TRUE(foo != bar); // To make sure foo is kept alive. |
| 2164 EXPECT_EQ(2u, Bar::s_live); | 2174 EXPECT_EQ(2u, Bar::s_live); |
| 2165 } | 2175 } |
| 2166 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2176 preciselyCollectGarbage(); |
| 2167 EXPECT_EQ(1u, Bar::s_live); | 2177 EXPECT_EQ(1u, Bar::s_live); |
| 2168 } | 2178 } |
| 2169 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2179 preciselyCollectGarbage(); |
| 2170 EXPECT_EQ(0u, Bar::s_live); | 2180 EXPECT_EQ(0u, Bar::s_live); |
| 2171 } | 2181 } |
| 2172 | 2182 |
| 2173 TEST(HeapTest, DeepTest) | 2183 TEST(HeapTest, DeepTest) |
| 2174 { | 2184 { |
| 2175 const unsigned depth = 100000; | 2185 const unsigned depth = 100000; |
| 2176 Bar::s_live = 0; | 2186 Bar::s_live = 0; |
| 2177 { | 2187 { |
| 2178 Bar* bar = Bar::create(); | 2188 Bar* bar = Bar::create(); |
| 2179 ASSERT(ThreadState::current()->findPageFromAddress(bar)); | 2189 ASSERT(ThreadState::current()->findPageFromAddress(bar)); |
| 2180 Foo* foo = Foo::create(bar); | 2190 Foo* foo = Foo::create(bar); |
| 2181 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 2191 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
| 2182 EXPECT_EQ(2u, Bar::s_live); | 2192 EXPECT_EQ(2u, Bar::s_live); |
| 2183 for (unsigned i = 0; i < depth; i++) { | 2193 for (unsigned i = 0; i < depth; i++) { |
| 2184 Foo* foo2 = Foo::create(foo); | 2194 Foo* foo2 = Foo::create(foo); |
| 2185 foo = foo2; | 2195 foo = foo2; |
| 2186 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 2196 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
| 2187 } | 2197 } |
| 2188 EXPECT_EQ(depth + 2, Bar::s_live); | 2198 EXPECT_EQ(depth + 2, Bar::s_live); |
| 2189 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2199 conservativelyCollectGarbage(); |
| 2190 EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive. | 2200 EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive. |
| 2191 EXPECT_EQ(depth + 2, Bar::s_live); | 2201 EXPECT_EQ(depth + 2, Bar::s_live); |
| 2192 } | 2202 } |
| 2193 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2203 preciselyCollectGarbage(); |
| 2194 EXPECT_EQ(0u, Bar::s_live); | 2204 EXPECT_EQ(0u, Bar::s_live); |
| 2195 } | 2205 } |
| 2196 | 2206 |
| 2197 TEST(HeapTest, WideTest) | 2207 TEST(HeapTest, WideTest) |
| 2198 { | 2208 { |
| 2199 Bar::s_live = 0; | 2209 Bar::s_live = 0; |
| 2200 { | 2210 { |
| 2201 Bars* bars = Bars::create(); | 2211 Bars* bars = Bars::create(); |
| 2202 unsigned width = Bars::width; | 2212 unsigned width = Bars::width; |
| 2203 EXPECT_EQ(width + 1, Bar::s_live); | 2213 EXPECT_EQ(width + 1, Bar::s_live); |
| 2204 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2214 conservativelyCollectGarbage(); |
| 2205 EXPECT_EQ(width + 1, Bar::s_live); | 2215 EXPECT_EQ(width + 1, Bar::s_live); |
| 2206 // Use bars here to make sure that it will be on the stack | 2216 // Use bars here to make sure that it will be on the stack |
| 2207 // for the conservative stack scan to find. | 2217 // for the conservative stack scan to find. |
| 2208 EXPECT_EQ(width, bars->getWidth()); | 2218 EXPECT_EQ(width, bars->getWidth()); |
| 2209 } | 2219 } |
| 2210 EXPECT_EQ(Bars::width + 1, Bar::s_live); | 2220 EXPECT_EQ(Bars::width + 1, Bar::s_live); |
| 2211 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2221 preciselyCollectGarbage(); |
| 2212 EXPECT_EQ(0u, Bar::s_live); | 2222 EXPECT_EQ(0u, Bar::s_live); |
| 2213 } | 2223 } |
| 2214 | 2224 |
| 2215 TEST(HeapTest, HashMapOfMembers) | 2225 TEST(HeapTest, HashMapOfMembers) |
| 2216 { | 2226 { |
| 2217 IntWrapper::s_destructorCalls = 0; | 2227 IntWrapper::s_destructorCalls = 0; |
| 2218 | 2228 |
| 2219 clearOutOldGarbage(); | 2229 clearOutOldGarbage(); |
| 2220 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2230 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
| 2221 { | 2231 { |
| 2222 typedef HeapHashMap< | 2232 typedef HeapHashMap< |
| 2223 Member<IntWrapper>, | 2233 Member<IntWrapper>, |
| 2224 Member<IntWrapper>, | 2234 Member<IntWrapper>, |
| 2225 DefaultHash<Member<IntWrapper>>::Hash, | 2235 DefaultHash<Member<IntWrapper>>::Hash, |
| 2226 HashTraits<Member<IntWrapper>>, | 2236 HashTraits<Member<IntWrapper>>, |
| 2227 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; | 2237 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; |
| 2228 | 2238 |
| 2229 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); | 2239 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); |
| 2230 | 2240 |
| 2231 map->clear(); | 2241 map->clear(); |
| 2232 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); | 2242 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); |
| 2233 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); | 2243 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); |
| 2234 | 2244 |
| 2235 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2245 preciselyCollectGarbage(); |
| 2236 size_t afterGC = Heap::objectPayloadSizeForTesting(); | 2246 size_t afterGC = Heap::objectPayloadSizeForTesting(); |
| 2237 EXPECT_EQ(afterGC, afterSetWasCreated); | 2247 EXPECT_EQ(afterGC, afterSetWasCreated); |
| 2238 | 2248 |
| 2239 // If the additions below cause garbage collections, these | 2249 // If the additions below cause garbage collections, these |
| 2240 // pointers should be found by conservative stack scanning. | 2250 // pointers should be found by conservative stack scanning. |
| 2241 IntWrapper* one(IntWrapper::create(1)); | 2251 IntWrapper* one(IntWrapper::create(1)); |
| 2242 IntWrapper* anotherOne(IntWrapper::create(1)); | 2252 IntWrapper* anotherOne(IntWrapper::create(1)); |
| 2243 | 2253 |
| 2244 map->add(one, one); | 2254 map->add(one, one); |
| 2245 | 2255 |
| 2246 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); | 2256 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); |
| 2247 EXPECT_TRUE(afterOneAdd > afterGC); | 2257 EXPECT_TRUE(afterOneAdd > afterGC); |
| 2248 | 2258 |
| 2249 HeapObjectIdentityMap::iterator it(map->begin()); | 2259 HeapObjectIdentityMap::iterator it(map->begin()); |
| 2250 HeapObjectIdentityMap::iterator it2(map->begin()); | 2260 HeapObjectIdentityMap::iterator it2(map->begin()); |
| 2251 ++it; | 2261 ++it; |
| 2252 ++it2; | 2262 ++it2; |
| 2253 | 2263 |
| 2254 map->add(anotherOne, one); | 2264 map->add(anotherOne, one); |
| 2255 | 2265 |
| 2256 // The addition above can cause an allocation of a new | 2266 // The addition above can cause an allocation of a new |
| 2257 // backing store. We therefore garbage collect before | 2267 // backing store. We therefore garbage collect before |
| 2258 // taking the heap stats in order to get rid of the old | 2268 // taking the heap stats in order to get rid of the old |
| 2259 // backing store. We make sure to not use conservative | 2269 // backing store. We make sure to not use conservative |
| 2260 // stack scanning as that could find a pointer to the | 2270 // stack scanning as that could find a pointer to the |
| 2261 // old backing. | 2271 // old backing. |
| 2262 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2272 preciselyCollectGarbage(); |
| 2263 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); | 2273 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); |
| 2264 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); | 2274 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); |
| 2265 | 2275 |
| 2266 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. | 2276 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. |
| 2267 | 2277 |
| 2268 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2278 preciselyCollectGarbage(); |
| 2269 EXPECT_TRUE(map->contains(one)); | 2279 EXPECT_TRUE(map->contains(one)); |
| 2270 EXPECT_TRUE(map->contains(anotherOne)); | 2280 EXPECT_TRUE(map->contains(anotherOne)); |
| 2271 | 2281 |
| 2272 IntWrapper* gotten(map->get(one)); | 2282 IntWrapper* gotten(map->get(one)); |
| 2273 EXPECT_EQ(gotten->value(), one->value()); | 2283 EXPECT_EQ(gotten->value(), one->value()); |
| 2274 EXPECT_EQ(gotten, one); | 2284 EXPECT_EQ(gotten, one); |
| 2275 | 2285 |
| 2276 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); | 2286 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); |
| 2277 EXPECT_EQ(afterGC2, afterAddAndGC); | 2287 EXPECT_EQ(afterGC2, afterAddAndGC); |
| 2278 | 2288 |
| 2279 IntWrapper* dozen = 0; | 2289 IntWrapper* dozen = 0; |
| 2280 | 2290 |
| 2281 for (int i = 1; i < 1000; i++) { // 999 iterations. | 2291 for (int i = 1; i < 1000; i++) { // 999 iterations. |
| 2282 IntWrapper* iWrapper(IntWrapper::create(i)); | 2292 IntWrapper* iWrapper(IntWrapper::create(i)); |
| 2283 IntWrapper* iSquared(IntWrapper::create(i * i)); | 2293 IntWrapper* iSquared(IntWrapper::create(i * i)); |
| 2284 map->add(iWrapper, iSquared); | 2294 map->add(iWrapper, iSquared); |
| 2285 if (i == 12) | 2295 if (i == 12) |
| 2286 dozen = iWrapper; | 2296 dozen = iWrapper; |
| 2287 } | 2297 } |
| 2288 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); | 2298 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); |
| 2289 EXPECT_TRUE(afterAdding1000 > afterGC2); | 2299 EXPECT_TRUE(afterAdding1000 > afterGC2); |
| 2290 | 2300 |
| 2291 IntWrapper* gross(map->get(dozen)); | 2301 IntWrapper* gross(map->get(dozen)); |
| 2292 EXPECT_EQ(gross->value(), 144); | 2302 EXPECT_EQ(gross->value(), 144); |
| 2293 | 2303 |
| 2294 // This should clear out any junk backings created by all the adds. | 2304 // This should clear out any junk backings created by all the adds. |
| 2295 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2305 preciselyCollectGarbage(); |
| 2296 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); | 2306 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); |
| 2297 EXPECT_TRUE(afterGC3 <= afterAdding1000); | 2307 EXPECT_TRUE(afterGC3 <= afterAdding1000); |
| 2298 } | 2308 } |
| 2299 | 2309 |
| 2300 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2310 preciselyCollectGarbage(); |
| 2301 // The objects 'one', anotherOne, and the 999 other pairs. | 2311 // The objects 'one', anotherOne, and the 999 other pairs. |
| 2302 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); | 2312 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); |
| 2303 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); | 2313 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); |
| 2304 EXPECT_EQ(afterGC4, initialObjectPayloadSize); | 2314 EXPECT_EQ(afterGC4, initialObjectPayloadSize); |
| 2305 } | 2315 } |
| 2306 | 2316 |
| 2307 TEST(HeapTest, NestedAllocation) | 2317 TEST(HeapTest, NestedAllocation) |
| 2308 { | 2318 { |
| 2309 clearOutOldGarbage(); | 2319 clearOutOldGarbage(); |
| 2310 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2320 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 clearOutOldGarbage(); | 2372 clearOutOldGarbage(); |
| 2363 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); | 2373 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); |
| 2364 EXPECT_EQ(10, IntWrapper::s_destructorCalls); | 2374 EXPECT_EQ(10, IntWrapper::s_destructorCalls); |
| 2365 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2375 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2366 } | 2376 } |
| 2367 clearOutOldGarbage(); | 2377 clearOutOldGarbage(); |
| 2368 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; | 2378 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; |
| 2369 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); | 2379 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); |
| 2370 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 2380 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
| 2371 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); | 2381 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); |
| 2372 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2382 preciselyCollectGarbage(); |
| 2373 } | 2383 } |
| 2374 | 2384 |
| 2375 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; | 2385 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; |
| 2376 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; | 2386 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; |
| 2377 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; | 2387 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; |
| 2378 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; | 2388 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; |
| 2379 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; | 2389 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; |
| 2380 typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak; | 2390 typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak; |
| 2381 | 2391 |
| 2382 class Container : public GarbageCollected<Container> { | 2392 class Container : public GarbageCollected<Container> { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 IntWrapper* one = IntWrapper::create(1); | 2449 IntWrapper* one = IntWrapper::create(1); |
| 2440 IntWrapper* two = IntWrapper::create(2); | 2450 IntWrapper* two = IntWrapper::create(2); |
| 2441 IntWrapper* three = IntWrapper::create(3); | 2451 IntWrapper* three = IntWrapper::create(3); |
| 2442 IntWrapper* four = IntWrapper::create(4); | 2452 IntWrapper* four = IntWrapper::create(4); |
| 2443 IntWrapper* five = IntWrapper::create(5); | 2453 IntWrapper* five = IntWrapper::create(5); |
| 2444 IntWrapper* six = IntWrapper::create(6); | 2454 IntWrapper* six = IntWrapper::create(6); |
| 2445 { | 2455 { |
| 2446 HeapVector<Member<IntWrapper>, 2> vector; | 2456 HeapVector<Member<IntWrapper>, 2> vector; |
| 2447 vector.append(one); | 2457 vector.append(one); |
| 2448 vector.append(two); | 2458 vector.append(two); |
| 2449 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2459 conservativelyCollectGarbage(); |
| 2450 EXPECT_TRUE(vector.contains(one)); | 2460 EXPECT_TRUE(vector.contains(one)); |
| 2451 EXPECT_TRUE(vector.contains(two)); | 2461 EXPECT_TRUE(vector.contains(two)); |
| 2452 | 2462 |
| 2453 vector.append(three); | 2463 vector.append(three); |
| 2454 vector.append(four); | 2464 vector.append(four); |
| 2455 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2465 conservativelyCollectGarbage(); |
| 2456 EXPECT_TRUE(vector.contains(one)); | 2466 EXPECT_TRUE(vector.contains(one)); |
| 2457 EXPECT_TRUE(vector.contains(two)); | 2467 EXPECT_TRUE(vector.contains(two)); |
| 2458 EXPECT_TRUE(vector.contains(three)); | 2468 EXPECT_TRUE(vector.contains(three)); |
| 2459 EXPECT_TRUE(vector.contains(four)); | 2469 EXPECT_TRUE(vector.contains(four)); |
| 2460 | 2470 |
| 2461 vector.shrink(1); | 2471 vector.shrink(1); |
| 2462 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2472 conservativelyCollectGarbage(); |
| 2463 EXPECT_TRUE(vector.contains(one)); | 2473 EXPECT_TRUE(vector.contains(one)); |
| 2464 EXPECT_FALSE(vector.contains(two)); | 2474 EXPECT_FALSE(vector.contains(two)); |
| 2465 EXPECT_FALSE(vector.contains(three)); | 2475 EXPECT_FALSE(vector.contains(three)); |
| 2466 EXPECT_FALSE(vector.contains(four)); | 2476 EXPECT_FALSE(vector.contains(four)); |
| 2467 } | 2477 } |
| 2468 { | 2478 { |
| 2469 HeapVector<Member<IntWrapper>, 2> vector1; | 2479 HeapVector<Member<IntWrapper>, 2> vector1; |
| 2470 HeapVector<Member<IntWrapper>, 2> vector2; | 2480 HeapVector<Member<IntWrapper>, 2> vector2; |
| 2471 | 2481 |
| 2472 vector1.append(one); | 2482 vector1.append(one); |
| 2473 vector2.append(two); | 2483 vector2.append(two); |
| 2474 vector1.swap(vector2); | 2484 vector1.swap(vector2); |
| 2475 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2485 conservativelyCollectGarbage(); |
| 2476 EXPECT_TRUE(vector1.contains(two)); | 2486 EXPECT_TRUE(vector1.contains(two)); |
| 2477 EXPECT_TRUE(vector2.contains(one)); | 2487 EXPECT_TRUE(vector2.contains(one)); |
| 2478 } | 2488 } |
| 2479 { | 2489 { |
| 2480 HeapVector<Member<IntWrapper>, 2> vector1; | 2490 HeapVector<Member<IntWrapper>, 2> vector1; |
| 2481 HeapVector<Member<IntWrapper>, 2> vector2; | 2491 HeapVector<Member<IntWrapper>, 2> vector2; |
| 2482 | 2492 |
| 2483 vector1.append(one); | 2493 vector1.append(one); |
| 2484 vector1.append(two); | 2494 vector1.append(two); |
| 2485 vector2.append(three); | 2495 vector2.append(three); |
| 2486 vector2.append(four); | 2496 vector2.append(four); |
| 2487 vector2.append(five); | 2497 vector2.append(five); |
| 2488 vector2.append(six); | 2498 vector2.append(six); |
| 2489 vector1.swap(vector2); | 2499 vector1.swap(vector2); |
| 2490 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 2500 conservativelyCollectGarbage(); |
| 2491 EXPECT_TRUE(vector1.contains(three)); | 2501 EXPECT_TRUE(vector1.contains(three)); |
| 2492 EXPECT_TRUE(vector1.contains(four)); | 2502 EXPECT_TRUE(vector1.contains(four)); |
| 2493 EXPECT_TRUE(vector1.contains(five)); | 2503 EXPECT_TRUE(vector1.contains(five)); |
| 2494 EXPECT_TRUE(vector1.contains(six)); | 2504 EXPECT_TRUE(vector1.contains(six)); |
| 2495 EXPECT_TRUE(vector2.contains(one)); | 2505 EXPECT_TRUE(vector2.contains(one)); |
| 2496 EXPECT_TRUE(vector2.contains(two)); | 2506 EXPECT_TRUE(vector2.contains(two)); |
| 2497 } | 2507 } |
| 2498 } | 2508 } |
| 2499 | 2509 |
| 2500 TEST(HeapTest, HeapVectorShrinkCapacity) | 2510 TEST(HeapTest, HeapVectorShrinkCapacity) |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2673 vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD)); | 2683 vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD)); |
| 2674 dequeUW->append(PairUnwrappedWrapped(1, &*oneF)); | 2684 dequeUW->append(PairUnwrappedWrapped(1, &*oneF)); |
| 2675 dequeUW2->append(PairUnwrappedWrapped(103, &*threeF)); | 2685 dequeUW2->append(PairUnwrappedWrapped(103, &*threeF)); |
| 2676 dequeUW2->append(PairUnwrappedWrapped(104, &*fourF)); | 2686 dequeUW2->append(PairUnwrappedWrapped(104, &*fourF)); |
| 2677 dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF)); | 2687 dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF)); |
| 2678 | 2688 |
| 2679 EXPECT_TRUE(dequeContains(*deque, oneB)); | 2689 EXPECT_TRUE(dequeContains(*deque, oneB)); |
| 2680 | 2690 |
| 2681 // Collect garbage. This should change nothing since we are keeping | 2691 // Collect garbage. This should change nothing since we are keeping |
| 2682 // alive the IntWrapper objects with on-stack pointers. | 2692 // alive the IntWrapper objects with on-stack pointers. |
| 2683 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); | 2693 conservativelyCollectGarbage(); |
| 2684 | 2694 |
| 2685 EXPECT_TRUE(dequeContains(*deque, oneB)); | 2695 EXPECT_TRUE(dequeContains(*deque, oneB)); |
| 2686 | 2696 |
| 2687 EXPECT_EQ(0u, memberMember->size()); | 2697 EXPECT_EQ(0u, memberMember->size()); |
| 2688 EXPECT_EQ(4u, memberMember2->size()); | 2698 EXPECT_EQ(4u, memberMember2->size()); |
| 2689 EXPECT_EQ(4u, primitiveMember->size()); | 2699 EXPECT_EQ(4u, primitiveMember->size()); |
| 2690 EXPECT_EQ(4u, memberPrimitive->size()); | 2700 EXPECT_EQ(4u, memberPrimitive->size()); |
| 2691 EXPECT_EQ(1u, set->size()); | 2701 EXPECT_EQ(1u, set->size()); |
| 2692 EXPECT_EQ(4u, set2->size()); | 2702 EXPECT_EQ(4u, set2->size()); |
| 2693 EXPECT_EQ(1u, set3->size()); | 2703 EXPECT_EQ(1u, set3->size()); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2795 EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45
))); | 2805 EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45
))); |
| 2796 EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42
))); | 2806 EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42
))); |
| 2797 EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE,
43))); | 2807 EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE,
43))); |
| 2798 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*thre
eF))); | 2808 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*thre
eF))); |
| 2799 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*four
F))); | 2809 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*four
F))); |
| 2800 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*five
F))); | 2810 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*five
F))); |
| 2801 EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)
)); | 2811 EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)
)); |
| 2802 EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*th
reeF))); | 2812 EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*th
reeF))); |
| 2803 } | 2813 } |
| 2804 | 2814 |
| 2805 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 2815 preciselyCollectGarbage(); |
| 2806 | 2816 |
| 2807 EXPECT_EQ(4u, memberMember->size()); | 2817 EXPECT_EQ(4u, memberMember->size()); |
| 2808 EXPECT_EQ(0u, memberMember2->size()); | 2818 EXPECT_EQ(0u, memberMember2->size()); |
| 2809 EXPECT_EQ(4u, primitiveMember->size()); | 2819 EXPECT_EQ(4u, primitiveMember->size()); |
| 2810 EXPECT_EQ(4u, memberPrimitive->size()); | 2820 EXPECT_EQ(4u, memberPrimitive->size()); |
| 2811 EXPECT_EQ(4u, set->size()); | 2821 EXPECT_EQ(4u, set->size()); |
| 2812 EXPECT_EQ(1u, set2->size()); | 2822 EXPECT_EQ(1u, set2->size()); |
| 2813 EXPECT_EQ(1u, set3->size()); | 2823 EXPECT_EQ(1u, set3->size()); |
| 2814 EXPECT_EQ(2u, vector->size()); | 2824 EXPECT_EQ(2u, vector->size()); |
| 2815 EXPECT_EQ(1u, vector2->size()); | 2825 EXPECT_EQ(1u, vector2->size()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2829 EXPECT_TRUE(set->contains(two)); | 2839 EXPECT_TRUE(set->contains(two)); |
| 2830 EXPECT_FALSE(set->contains(oneB)); | 2840 EXPECT_FALSE(set->contains(oneB)); |
| 2831 EXPECT_TRUE(set2->contains(oneB)); | 2841 EXPECT_TRUE(set2->contains(oneB)); |
| 2832 EXPECT_TRUE(set3->contains(oneB)); | 2842 EXPECT_TRUE(set3->contains(oneB)); |
| 2833 EXPECT_EQ(2u, set3->find(oneB)->value); | 2843 EXPECT_EQ(2u, set3->find(oneB)->value); |
| 2834 EXPECT_EQ(3, vector->at(0)->value()); | 2844 EXPECT_EQ(3, vector->at(0)->value()); |
| 2835 EXPECT_EQ(4, vector->at(1)->value()); | 2845 EXPECT_EQ(4, vector->at(1)->value()); |
| 2836 EXPECT_EQ(3, deque->begin()->get()->value()); | 2846 EXPECT_EQ(3, deque->begin()->get()->value()); |
| 2837 } | 2847 } |
| 2838 | 2848 |
| 2839 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2849 preciselyCollectGarbage(); |
| 2840 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2850 preciselyCollectGarbage(); |
| 2841 | 2851 |
| 2842 EXPECT_EQ(4u, memberMember->size()); | 2852 EXPECT_EQ(4u, memberMember->size()); |
| 2843 EXPECT_EQ(4u, primitiveMember->size()); | 2853 EXPECT_EQ(4u, primitiveMember->size()); |
| 2844 EXPECT_EQ(4u, memberPrimitive->size()); | 2854 EXPECT_EQ(4u, memberPrimitive->size()); |
| 2845 EXPECT_EQ(4u, set->size()); | 2855 EXPECT_EQ(4u, set->size()); |
| 2846 EXPECT_EQ(1u, set2->size()); | 2856 EXPECT_EQ(1u, set2->size()); |
| 2847 EXPECT_EQ(2u, vector->size()); | 2857 EXPECT_EQ(2u, vector->size()); |
| 2848 EXPECT_EQ(1u, vector2->size()); | 2858 EXPECT_EQ(1u, vector2->size()); |
| 2849 EXPECT_EQ(3u, vectorWU->size()); | 2859 EXPECT_EQ(3u, vectorWU->size()); |
| 2850 EXPECT_EQ(1u, vectorWU2->size()); | 2860 EXPECT_EQ(1u, vectorWU2->size()); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2961 EXPECT_EQ(2u, weakWeak->size()); | 2971 EXPECT_EQ(2u, weakWeak->size()); |
| 2962 EXPECT_EQ(4u, weakSet->size()); | 2972 EXPECT_EQ(4u, weakSet->size()); |
| 2963 EXPECT_EQ(4u, weakCountedSet->size()); | 2973 EXPECT_EQ(4u, weakCountedSet->size()); |
| 2964 EXPECT_EQ(3u, weakCountedSet->find(two)->value); | 2974 EXPECT_EQ(3u, weakCountedSet->find(two)->value); |
| 2965 weakCountedSet->remove(two); | 2975 weakCountedSet->remove(two); |
| 2966 EXPECT_EQ(2u, weakCountedSet->find(two)->value); | 2976 EXPECT_EQ(2u, weakCountedSet->find(two)->value); |
| 2967 } | 2977 } |
| 2968 | 2978 |
| 2969 keepNumbersAlive[0] = nullptr; | 2979 keepNumbersAlive[0] = nullptr; |
| 2970 | 2980 |
| 2971 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 2981 preciselyCollectGarbage(); |
| 2972 | 2982 |
| 2973 EXPECT_EQ(0u, weakStrong->size()); | 2983 EXPECT_EQ(0u, weakStrong->size()); |
| 2974 EXPECT_EQ(0u, strongWeak->size()); | 2984 EXPECT_EQ(0u, strongWeak->size()); |
| 2975 EXPECT_EQ(0u, weakWeak->size()); | 2985 EXPECT_EQ(0u, weakWeak->size()); |
| 2976 EXPECT_EQ(2u, weakSet->size()); | 2986 EXPECT_EQ(2u, weakSet->size()); |
| 2977 EXPECT_EQ(2u, weakCountedSet->size()); | 2987 EXPECT_EQ(2u, weakCountedSet->size()); |
| 2978 } | 2988 } |
| 2979 | 2989 |
| 2980 template<typename Set> | 2990 template<typename Set> |
| 2981 void orderedSetHelper(bool strong) | 2991 void orderedSetHelper(bool strong) |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3061 EXPECT_EQ(constSet.rend(), creverse); | 3071 EXPECT_EQ(constSet.rend(), creverse); |
| 3062 | 3072 |
| 3063 typename Set::iterator iX(set2->begin()); | 3073 typename Set::iterator iX(set2->begin()); |
| 3064 EXPECT_EQ(set2->end(), iX); | 3074 EXPECT_EQ(set2->end(), iX); |
| 3065 | 3075 |
| 3066 if (strong) | 3076 if (strong) |
| 3067 set1->remove(keepNumbersAlive[0]); | 3077 set1->remove(keepNumbersAlive[0]); |
| 3068 | 3078 |
| 3069 keepNumbersAlive[0] = nullptr; | 3079 keepNumbersAlive[0] = nullptr; |
| 3070 | 3080 |
| 3071 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3081 preciselyCollectGarbage(); |
| 3072 | 3082 |
| 3073 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size()); | 3083 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size()); |
| 3074 | 3084 |
| 3075 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls); | 3085 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls); |
| 3076 | 3086 |
| 3077 typename Set::iterator i2(set1->begin()); | 3087 typename Set::iterator i2(set1->begin()); |
| 3078 if (strong) { | 3088 if (strong) { |
| 3079 EXPECT_EQ(0, (*i2)->value()); | 3089 EXPECT_EQ(0, (*i2)->value()); |
| 3080 ++i2; | 3090 ++i2; |
| 3081 EXPECT_NE(set1->end(), i2); | 3091 EXPECT_NE(set1->end(), i2); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3150 Persistent<RefMap> refMap(new RefMap()); | 3160 Persistent<RefMap> refMap(new RefMap()); |
| 3151 | 3161 |
| 3152 Persistent<IntWrapper> luck(IntWrapper::create(103)); | 3162 Persistent<IntWrapper> luck(IntWrapper::create(103)); |
| 3153 | 3163 |
| 3154 int baseLine, refBaseLine; | 3164 int baseLine, refBaseLine; |
| 3155 | 3165 |
| 3156 { | 3166 { |
| 3157 Map stackMap; | 3167 Map stackMap; |
| 3158 RefMap stackRefMap; | 3168 RefMap stackRefMap; |
| 3159 | 3169 |
| 3160 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3170 preciselyCollectGarbage(); |
| 3161 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3171 preciselyCollectGarbage(); |
| 3162 | 3172 |
| 3163 stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729)); | 3173 stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729)); |
| 3164 stackMap.add(luck, ThingWithDestructor(8128)); | 3174 stackMap.add(luck, ThingWithDestructor(8128)); |
| 3165 stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::c
reate()); | 3175 stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::c
reate()); |
| 3166 stackRefMap.add(luck, RefCountedAndGarbageCollected::create()); | 3176 stackRefMap.add(luck, RefCountedAndGarbageCollected::create()); |
| 3167 | 3177 |
| 3168 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; | 3178 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; |
| 3169 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; | 3179 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; |
| 3170 | 3180 |
| 3171 // Although the heap maps are on-stack, we can't expect prompt | 3181 // Although the heap maps are on-stack, we can't expect prompt |
| 3172 // finalization of the elements, so when they go out of scope here we | 3182 // finalization of the elements, so when they go out of scope here we |
| 3173 // will not necessarily have called the relevant destructors. | 3183 // will not necessarily have called the relevant destructors. |
| 3174 } | 3184 } |
| 3175 | 3185 |
| 3176 // The RefCountedAndGarbageCollected things need an extra GC to discover | 3186 // The RefCountedAndGarbageCollected things need an extra GC to discover |
| 3177 // that they are no longer ref counted. | 3187 // that they are no longer ref counted. |
| 3178 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3188 preciselyCollectGarbage(); |
| 3179 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3189 preciselyCollectGarbage(); |
| 3180 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); | 3190 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); |
| 3181 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; | 3191 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; |
| 3182 | 3192 |
| 3183 // Now use maps kept alive with persistents. Here we don't expect any | 3193 // Now use maps kept alive with persistents. Here we don't expect any |
| 3184 // destructors to be called before there have been GCs. | 3194 // destructors to be called before there have been GCs. |
| 3185 | 3195 |
| 3186 map->add(IntWrapper::create(42), ThingWithDestructor(1729)); | 3196 map->add(IntWrapper::create(42), ThingWithDestructor(1729)); |
| 3187 map->add(luck, ThingWithDestructor(8128)); | 3197 map->add(luck, ThingWithDestructor(8128)); |
| 3188 refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create())
; | 3198 refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create())
; |
| 3189 refMap->add(luck, RefCountedAndGarbageCollected::create()); | 3199 refMap->add(luck, RefCountedAndGarbageCollected::create()); |
| 3190 | 3200 |
| 3191 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; | 3201 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; |
| 3192 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; | 3202 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; |
| 3193 | 3203 |
| 3194 luck.clear(); | 3204 luck.clear(); |
| 3195 if (clearMaps) { | 3205 if (clearMaps) { |
| 3196 map->clear(); // Clear map. | 3206 map->clear(); // Clear map. |
| 3197 refMap->clear(); // Clear map. | 3207 refMap->clear(); // Clear map. |
| 3198 } else { | 3208 } else { |
| 3199 map.clear(); // Clear Persistent handle, not map. | 3209 map.clear(); // Clear Persistent handle, not map. |
| 3200 refMap.clear(); // Clear Persistent handle, not map. | 3210 refMap.clear(); // Clear Persistent handle, not map. |
| 3201 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3211 preciselyCollectGarbage(); |
| 3202 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3212 preciselyCollectGarbage(); |
| 3203 } | 3213 } |
| 3204 | 3214 |
| 3205 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); | 3215 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); |
| 3206 | 3216 |
| 3207 // Need a GC to make sure that the RefCountedAndGarbageCollected thing | 3217 // Need a GC to make sure that the RefCountedAndGarbageCollected thing |
| 3208 // noticies it's been decremented to zero. | 3218 // noticies it's been decremented to zero. |
| 3209 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3219 preciselyCollectGarbage(); |
| 3210 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; | 3220 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; |
| 3211 } | 3221 } |
| 3212 | 3222 |
| 3213 TEST(HeapTest, HeapMapDestructor) | 3223 TEST(HeapTest, HeapMapDestructor) |
| 3214 { | 3224 { |
| 3215 heapMapDestructorHelper(true); | 3225 heapMapDestructorHelper(true); |
| 3216 heapMapDestructorHelper(false); | 3226 heapMapDestructorHelper(false); |
| 3217 } | 3227 } |
| 3218 | 3228 |
| 3219 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; | 3229 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 weakStrong->add(PairWeakStrong(&*two, &*two)); | 3328 weakStrong->add(PairWeakStrong(&*two, &*two)); |
| 3319 strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1))); | 3329 strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1))); |
| 3320 strongWeak->add(PairStrongWeak(&*two, &*two)); | 3330 strongWeak->add(PairStrongWeak(&*two, &*two)); |
| 3321 weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2)); | 3331 weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2)); |
| 3322 weakUnwrapped->add(PairWeakUnwrapped(&*two, 2)); | 3332 weakUnwrapped->add(PairWeakUnwrapped(&*two, 2)); |
| 3323 unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1))); | 3333 unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1))); |
| 3324 unwrappedWeak->add(PairUnwrappedWeak(2, &*two)); | 3334 unwrappedWeak->add(PairUnwrappedWeak(2, &*two)); |
| 3325 | 3335 |
| 3326 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, true, two); | 3336 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, true, two); |
| 3327 | 3337 |
| 3328 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3338 preciselyCollectGarbage(); |
| 3329 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, false, two); | 3339 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, false, two); |
| 3330 } | 3340 } |
| 3331 | 3341 |
| 3332 TEST(HeapTest, HeapWeakPairs) | 3342 TEST(HeapTest, HeapWeakPairs) |
| 3333 { | 3343 { |
| 3334 { | 3344 { |
| 3335 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; | 3345 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; |
| 3336 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet; | 3346 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet; |
| 3337 typedef HeapHashSet<PairStrongWeak> StrongWeakSet; | 3347 typedef HeapHashSet<PairStrongWeak> StrongWeakSet; |
| 3338 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet; | 3348 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3410 } | 3420 } |
| 3411 | 3421 |
| 3412 EXPECT_EQ(64u, weakStrong->size()); | 3422 EXPECT_EQ(64u, weakStrong->size()); |
| 3413 EXPECT_EQ(64u, strongWeak->size()); | 3423 EXPECT_EQ(64u, strongWeak->size()); |
| 3414 EXPECT_EQ(64u, weakWeak->size()); | 3424 EXPECT_EQ(64u, weakWeak->size()); |
| 3415 EXPECT_EQ(64u, weakSet->size()); | 3425 EXPECT_EQ(64u, weakSet->size()); |
| 3416 EXPECT_EQ(64u, weakOrderedSet->size()); | 3426 EXPECT_EQ(64u, weakOrderedSet->size()); |
| 3417 | 3427 |
| 3418 // Collect garbage. This should change nothing since we are keeping | 3428 // Collect garbage. This should change nothing since we are keeping |
| 3419 // alive the IntWrapper objects. | 3429 // alive the IntWrapper objects. |
| 3420 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 3430 preciselyCollectGarbage(); |
| 3421 | 3431 |
| 3422 EXPECT_EQ(64u, weakStrong->size()); | 3432 EXPECT_EQ(64u, weakStrong->size()); |
| 3423 EXPECT_EQ(64u, strongWeak->size()); | 3433 EXPECT_EQ(64u, strongWeak->size()); |
| 3424 EXPECT_EQ(64u, weakWeak->size()); | 3434 EXPECT_EQ(64u, weakWeak->size()); |
| 3425 EXPECT_EQ(64u, weakSet->size()); | 3435 EXPECT_EQ(64u, weakSet->size()); |
| 3426 EXPECT_EQ(64u, weakOrderedSet->size()); | 3436 EXPECT_EQ(64u, weakOrderedSet->size()); |
| 3427 | 3437 |
| 3428 for (int i = 0; i < 128; i += 2) { | 3438 for (int i = 0; i < 128; i += 2) { |
| 3429 IntWrapper* wrapped = keepNumbersAlive[i]; | 3439 IntWrapper* wrapped = keepNumbersAlive[i]; |
| 3430 IntWrapper* wrapped2 = keepNumbersAlive[i + 1]; | 3440 IntWrapper* wrapped2 = keepNumbersAlive[i + 1]; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3450 weakOrderedSet->clear(); | 3460 weakOrderedSet->clear(); |
| 3451 | 3461 |
| 3452 if (testThatIteratorsMakeStrong) { | 3462 if (testThatIteratorsMakeStrong) { |
| 3453 WeakStrong::iterator it1 = weakStrong->begin(); | 3463 WeakStrong::iterator it1 = weakStrong->begin(); |
| 3454 StrongWeak::iterator it2 = strongWeak->begin(); | 3464 StrongWeak::iterator it2 = strongWeak->begin(); |
| 3455 WeakWeak::iterator it3 = weakWeak->begin(); | 3465 WeakWeak::iterator it3 = weakWeak->begin(); |
| 3456 WeakSet::iterator it4 = weakSet->begin(); | 3466 WeakSet::iterator it4 = weakSet->begin(); |
| 3457 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); | 3467 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); |
| 3458 // Collect garbage. This should change nothing since the | 3468 // Collect garbage. This should change nothing since the |
| 3459 // iterators make the collections strong. | 3469 // iterators make the collections strong. |
| 3460 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGC); | 3470 conservativelyCollectGarbage(); |
| 3461 if (collectionNumber == weakStrongIndex) { | 3471 if (collectionNumber == weakStrongIndex) { |
| 3462 EXPECT_EQ(64u, weakStrong->size()); | 3472 EXPECT_EQ(64u, weakStrong->size()); |
| 3463 MapIteratorCheck(it1, weakStrong->end(), 64); | 3473 MapIteratorCheck(it1, weakStrong->end(), 64); |
| 3464 } else if (collectionNumber == strongWeakIndex) { | 3474 } else if (collectionNumber == strongWeakIndex) { |
| 3465 EXPECT_EQ(64u, strongWeak->size()); | 3475 EXPECT_EQ(64u, strongWeak->size()); |
| 3466 MapIteratorCheck(it2, strongWeak->end(), 64); | 3476 MapIteratorCheck(it2, strongWeak->end(), 64); |
| 3467 } else if (collectionNumber == weakWeakIndex) { | 3477 } else if (collectionNumber == weakWeakIndex) { |
| 3468 EXPECT_EQ(64u, weakWeak->size()); | 3478 EXPECT_EQ(64u, weakWeak->size()); |
| 3469 MapIteratorCheck(it3, weakWeak->end(), 64); | 3479 MapIteratorCheck(it3, weakWeak->end(), 64); |
| 3470 } else if (collectionNumber == weakSetIndex) { | 3480 } else if (collectionNumber == weakSetIndex) { |
| 3471 EXPECT_EQ(64u, weakSet->size()); | 3481 EXPECT_EQ(64u, weakSet->size()); |
| 3472 SetIteratorCheck(it4, weakSet->end(), 64); | 3482 SetIteratorCheck(it4, weakSet->end(), 64); |
| 3473 } else if (collectionNumber == weakOrderedSetIndex) { | 3483 } else if (collectionNumber == weakOrderedSetIndex) { |
| 3474 EXPECT_EQ(64u, weakOrderedSet->size()); | 3484 EXPECT_EQ(64u, weakOrderedSet->size()); |
| 3475 SetIteratorCheck(it5, weakOrderedSet->end(), 64); | 3485 SetIteratorCheck(it5, weakOrderedSet->end(), 64); |
| 3476 } | 3486 } |
| 3477 } else { | 3487 } else { |
| 3478 // Collect garbage. This causes weak processing to remove | 3488 // Collect garbage. This causes weak processing to remove |
| 3479 // things from the collections. | 3489 // things from the collections. |
| 3480 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); | 3490 preciselyCollectGarbage(); |
| 3481 unsigned count = 0; | 3491 unsigned count = 0; |
| 3482 for (int i = 0; i < 128; i += 2) { | 3492 for (int i = 0; i < 128; i += 2) { |
| 3483 bool firstAlive = keepNumbersAlive[i]; | 3493 bool firstAlive = keepNumbersAlive[i]; |
| 3484 bool secondAlive = keepNumbersAlive[i + 1]; | 3494 bool secondAlive = keepNumbersAlive[i + 1]; |
| 3485 if (firstAlive && (collectionNumber == weakStrongIndex || co
llectionNumber == strongWeakIndex)) | 3495 if (firstAlive && (collectionNumber == weakStrongIndex || co
llectionNumber == strongWeakIndex)) |
| 3486 secondAlive = true; | 3496 secondAlive = true; |
| 3487 if (firstAlive && secondAlive && collectionNumber < numberOf
MapIndices) { | 3497 if (firstAlive && secondAlive && collectionNumber < numberOf
MapIndices) { |
| 3488 if (collectionNumber == weakStrongIndex) { | 3498 if (collectionNumber == weakStrongIndex) { |
| 3489 if (deleteAfterwards) | 3499 if (deleteAfterwards) |
| 3490 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAli
ve[i])->value()); | 3500 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAli
ve[i])->value()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 WeakSet::iterator it4 = weakSet->begin(); | 3548 WeakSet::iterator it4 = weakSet->begin(); |
| 3539 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); | 3549 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); |
| 3540 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == we
akStrongIndex ? count : 0) + added); | 3550 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == we
akStrongIndex ? count : 0) + added); |
| 3541 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == st
rongWeakIndex ? count : 0) + added); | 3551 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == st
rongWeakIndex ? count : 0) + added); |
| 3542 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weak
WeakIndex ? count : 0) + added); | 3552 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weak
WeakIndex ? count : 0) + added); |
| 3543 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakS
etIndex ? count : 0) + added); | 3553 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakS
etIndex ? count : 0) + added); |
| 3544 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber =
= weakOrderedSetIndex ? count : 0) + added); | 3554 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber =
= weakOrderedSetIndex ? count : 0) + added); |
| 3545 } | 3555 } |
| 3546 for (unsigned i = 0; i < 128 + added; i++) | 3556 for (unsigned i = 0; i < 128 + added; i++) |
| 3547 keepNumbersAlive[i] = nullptr; | 3557 keepNumbersAlive[i] = nullptr; |
| 3548 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 3558 preciselyCollectGarbage(); |
| 3549 EXPECT_EQ(0u, weakStrong->size()); | 3559 EXPECT_EQ(0u, weakStrong->size()); |
| 3550 EXPECT_EQ(0u, strongWeak->size()); | 3560 EXPECT_EQ(0u, strongWeak->size()); |
| 3551 EXPECT_EQ(0u, weakWeak->size()); | 3561 EXPECT_EQ(0u, weakWeak->size()); |
| 3552 EXPECT_EQ(0u, weakSet->size()); | 3562 EXPECT_EQ(0u, weakSet->size()); |
| 3553 EXPECT_EQ(0u, weakOrderedSet->size()); | 3563 EXPECT_EQ(0u, weakOrderedSet->size()); |
| 3554 } | 3564 } |
| 3555 } | 3565 } |
| 3556 } | 3566 } |
| 3557 | 3567 |
| 3558 TEST(HeapTest, RefCountedGarbageCollected) | 3568 TEST(HeapTest, RefCountedGarbageCollected) |
| 3559 { | 3569 { |
| 3560 RefCountedAndGarbageCollected::s_destructorCalls = 0; | 3570 RefCountedAndGarbageCollected::s_destructorCalls = 0; |
| 3561 { | 3571 { |
| 3562 RefPtr<RefCountedAndGarbageCollected> refPtr3; | 3572 RefPtr<RefCountedAndGarbageCollected> refPtr3; |
| 3563 { | 3573 { |
| 3564 Persistent<RefCountedAndGarbageCollected> persistent; | 3574 Persistent<RefCountedAndGarbageCollected> persistent; |
| 3565 { | 3575 { |
| 3566 Persistent<RefCountedAndGarbageCollected> refPtr1 = RefCountedAn
dGarbageCollected::create(); | 3576 Persistent<RefCountedAndGarbageCollected> refPtr1 = RefCountedAn
dGarbageCollected::create(); |
| 3567 Persistent<RefCountedAndGarbageCollected> refPtr2 = RefCountedAn
dGarbageCollected::create(); | 3577 Persistent<RefCountedAndGarbageCollected> refPtr2 = RefCountedAn
dGarbageCollected::create(); |
| 3568 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); | 3578 preciselyCollectGarbage(); |
| 3569 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3579 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3570 persistent = refPtr1.get(); | 3580 persistent = refPtr1.get(); |
| 3571 } | 3581 } |
| 3572 // Reference count is zero for both objects but one of | 3582 // Reference count is zero for both objects but one of |
| 3573 // them is kept alive by a persistent handle. | 3583 // them is kept alive by a persistent handle. |
| 3574 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 3584 preciselyCollectGarbage(); |
| 3575 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3585 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3576 refPtr3 = persistent.get(); | 3586 refPtr3 = persistent.get(); |
| 3577 } | 3587 } |
| 3578 // The persistent handle is gone but the ref count has been | 3588 // The persistent handle is gone but the ref count has been |
| 3579 // increased to 1. | 3589 // increased to 1. |
| 3580 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3590 preciselyCollectGarbage(); |
| 3581 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3591 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3582 } | 3592 } |
| 3583 // Both persistent handle is gone and ref count is zero so the | 3593 // Both persistent handle is gone and ref count is zero so the |
| 3584 // object can be collected. | 3594 // object can be collected. |
| 3585 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3595 preciselyCollectGarbage(); |
| 3586 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); | 3596 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3587 } | 3597 } |
| 3588 | 3598 |
| 3589 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) | 3599 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) |
| 3590 { | 3600 { |
| 3591 RefCountedAndGarbageCollected::s_destructorCalls = 0; | 3601 RefCountedAndGarbageCollected::s_destructorCalls = 0; |
| 3592 RefCountedAndGarbageCollected2::s_destructorCalls = 0; | 3602 RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
| 3593 { | 3603 { |
| 3594 RefCountedAndGarbageCollected* pointer1 = 0; | 3604 RefCountedAndGarbageCollected* pointer1 = 0; |
| 3595 RefCountedAndGarbageCollected2* pointer2 = 0; | 3605 RefCountedAndGarbageCollected2* pointer2 = 0; |
| 3596 { | 3606 { |
| 3597 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); | 3607 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); |
| 3598 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); | 3608 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); |
| 3599 pointer1 = object1.get(); | 3609 pointer1 = object1.get(); |
| 3600 pointer2 = object2.get(); | 3610 pointer2 = object2.get(); |
| 3601 void* objects[2] = { object1.get(), object2.get() }; | 3611 void* objects[2] = { object1.get(), object2.get() }; |
| 3602 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3612 RefCountedGarbageCollectedVisitor visitor(2, objects); |
| 3603 ThreadState::current()->visitPersistents(&visitor); | 3613 ThreadState::current()->visitPersistents(&visitor); |
| 3604 EXPECT_TRUE(visitor.validate()); | 3614 EXPECT_TRUE(visitor.validate()); |
| 3605 | 3615 |
| 3606 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); | 3616 conservativelyCollectGarbage(); |
| 3607 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3617 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3608 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3618 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3609 } | 3619 } |
| 3610 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 3620 conservativelyCollectGarbage(); |
| 3611 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3621 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3612 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3622 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3613 | 3623 |
| 3614 // At this point, the reference counts of object1 and object2 are 0. | 3624 // At this point, the reference counts of object1 and object2 are 0. |
| 3615 // Only pointer1 and pointer2 keep references to object1 and object2. | 3625 // Only pointer1 and pointer2 keep references to object1 and object2. |
| 3616 void* objects[] = { 0 }; | 3626 void* objects[] = { 0 }; |
| 3617 RefCountedGarbageCollectedVisitor visitor(0, objects); | 3627 RefCountedGarbageCollectedVisitor visitor(0, objects); |
| 3618 ThreadState::current()->visitPersistents(&visitor); | 3628 ThreadState::current()->visitPersistents(&visitor); |
| 3619 EXPECT_TRUE(visitor.validate()); | 3629 EXPECT_TRUE(visitor.validate()); |
| 3620 | 3630 |
| 3621 { | 3631 { |
| 3622 Persistent<RefCountedAndGarbageCollected> object1(pointer1); | 3632 Persistent<RefCountedAndGarbageCollected> object1(pointer1); |
| 3623 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); | 3633 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); |
| 3624 void* objects[2] = { object1.get(), object2.get() }; | 3634 void* objects[2] = { object1.get(), object2.get() }; |
| 3625 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3635 RefCountedGarbageCollectedVisitor visitor(2, objects); |
| 3626 ThreadState::current()->visitPersistents(&visitor); | 3636 ThreadState::current()->visitPersistents(&visitor); |
| 3627 EXPECT_TRUE(visitor.validate()); | 3637 EXPECT_TRUE(visitor.validate()); |
| 3628 | 3638 |
| 3629 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); | 3639 conservativelyCollectGarbage(); |
| 3630 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3640 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3631 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3641 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3632 } | 3642 } |
| 3633 | 3643 |
| 3634 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 3644 conservativelyCollectGarbage(); |
| 3635 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3645 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3636 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3646 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3637 } | 3647 } |
| 3638 | 3648 |
| 3639 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3649 preciselyCollectGarbage(); |
| 3640 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3650 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3641 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); | 3651 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3642 } | 3652 } |
| 3643 | 3653 |
| 3644 TEST(HeapTest, WeakMembers) | 3654 TEST(HeapTest, WeakMembers) |
| 3645 { | 3655 { |
| 3646 Bar::s_live = 0; | 3656 Bar::s_live = 0; |
| 3647 { | 3657 { |
| 3648 Persistent<Bar> h1 = Bar::create(); | 3658 Persistent<Bar> h1 = Bar::create(); |
| 3649 Persistent<Weak> h4; | 3659 Persistent<Weak> h4; |
| 3650 Persistent<WithWeakMember> h5; | 3660 Persistent<WithWeakMember> h5; |
| 3651 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3661 preciselyCollectGarbage(); |
| 3652 ASSERT_EQ(1u, Bar::s_live); // h1 is live. | 3662 ASSERT_EQ(1u, Bar::s_live); // h1 is live. |
| 3653 { | 3663 { |
| 3654 Bar* h2 = Bar::create(); | 3664 Bar* h2 = Bar::create(); |
| 3655 Bar* h3 = Bar::create(); | 3665 Bar* h3 = Bar::create(); |
| 3656 h4 = Weak::create(h2, h3); | 3666 h4 = Weak::create(h2, h3); |
| 3657 h5 = WithWeakMember::create(h2, h3); | 3667 h5 = WithWeakMember::create(h2, h3); |
| 3658 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); | 3668 conservativelyCollectGarbage(); |
| 3659 EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive. | 3669 EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive. |
| 3660 EXPECT_FALSE(h3->hasBeenFinalized()); | 3670 EXPECT_FALSE(h3->hasBeenFinalized()); |
| 3661 EXPECT_TRUE(h4->strongIsThere()); | 3671 EXPECT_TRUE(h4->strongIsThere()); |
| 3662 EXPECT_TRUE(h4->weakIsThere()); | 3672 EXPECT_TRUE(h4->weakIsThere()); |
| 3663 EXPECT_TRUE(h5->strongIsThere()); | 3673 EXPECT_TRUE(h5->strongIsThere()); |
| 3664 EXPECT_TRUE(h5->weakIsThere()); | 3674 EXPECT_TRUE(h5->weakIsThere()); |
| 3665 } | 3675 } |
| 3666 // h3 is collected, weak pointers from h4 and h5 don't keep it alive. | 3676 // h3 is collected, weak pointers from h4 and h5 don't keep it alive. |
| 3667 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3677 preciselyCollectGarbage(); |
| 3668 EXPECT_EQ(4u, Bar::s_live); | 3678 EXPECT_EQ(4u, Bar::s_live); |
| 3669 EXPECT_TRUE(h4->strongIsThere()); | 3679 EXPECT_TRUE(h4->strongIsThere()); |
| 3670 EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer. | 3680 EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer. |
| 3671 EXPECT_TRUE(h5->strongIsThere()); | 3681 EXPECT_TRUE(h5->strongIsThere()); |
| 3672 EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer. | 3682 EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer. |
| 3673 h1.release(); // Zero out h1. | 3683 h1.release(); // Zero out h1. |
| 3674 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3684 preciselyCollectGarbage(); |
| 3675 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left. | 3685 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left. |
| 3676 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4. | 3686 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4. |
| 3677 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5. | 3687 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5. |
| 3678 } | 3688 } |
| 3679 // h4 and h5 have gone out of scope now and they were keeping h2 alive. | 3689 // h4 and h5 have gone out of scope now and they were keeping h2 alive. |
| 3680 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3690 preciselyCollectGarbage(); |
| 3681 EXPECT_EQ(0u, Bar::s_live); // All gone. | 3691 EXPECT_EQ(0u, Bar::s_live); // All gone. |
| 3682 } | 3692 } |
| 3683 | 3693 |
| 3684 TEST(HeapTest, FinalizationObserver) | 3694 TEST(HeapTest, FinalizationObserver) |
| 3685 { | 3695 { |
| 3686 Persistent<FinalizationObserver<Observable>> o; | 3696 Persistent<FinalizationObserver<Observable>> o; |
| 3687 { | 3697 { |
| 3688 Observable* foo = Observable::create(Bar::create()); | 3698 Observable* foo = Observable::create(Bar::create()); |
| 3689 // |o| observes |foo|. | 3699 // |o| observes |foo|. |
| 3690 o = FinalizationObserver<Observable>::create(foo); | 3700 o = FinalizationObserver<Observable>::create(foo); |
| 3691 } | 3701 } |
| 3692 // FinalizationObserver doesn't have a strong reference to |foo|. So |foo| | 3702 // FinalizationObserver doesn't have a strong reference to |foo|. So |foo| |
| 3693 // and its member will be collected. | 3703 // and its member will be collected. |
| 3694 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3704 preciselyCollectGarbage(); |
| 3695 EXPECT_EQ(0u, Bar::s_live); | 3705 EXPECT_EQ(0u, Bar::s_live); |
| 3696 EXPECT_TRUE(o->didCallWillFinalize()); | 3706 EXPECT_TRUE(o->didCallWillFinalize()); |
| 3697 | 3707 |
| 3698 FinalizationObserverWithHashMap::s_didCallWillFinalize = false; | 3708 FinalizationObserverWithHashMap::s_didCallWillFinalize = false; |
| 3699 Observable* foo = Observable::create(Bar::create()); | 3709 Observable* foo = Observable::create(Bar::create()); |
| 3700 FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWith
HashMap::observe(*foo); | 3710 FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWith
HashMap::observe(*foo); |
| 3701 EXPECT_EQ(1u, map.size()); | 3711 EXPECT_EQ(1u, map.size()); |
| 3702 foo = 0; | 3712 foo = 0; |
| 3703 // FinalizationObserverWithHashMap doesn't have a strong reference to | 3713 // FinalizationObserverWithHashMap doesn't have a strong reference to |
| 3704 // |foo|. So |foo| and its member will be collected. | 3714 // |foo|. So |foo| and its member will be collected. |
| 3705 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3715 preciselyCollectGarbage(); |
| 3706 EXPECT_EQ(0u, Bar::s_live); | 3716 EXPECT_EQ(0u, Bar::s_live); |
| 3707 EXPECT_EQ(0u, map.size()); | 3717 EXPECT_EQ(0u, map.size()); |
| 3708 EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize); | 3718 EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize); |
| 3709 | 3719 |
| 3710 FinalizationObserverWithHashMap::clearObservers(); | 3720 FinalizationObserverWithHashMap::clearObservers(); |
| 3711 } | 3721 } |
| 3712 | 3722 |
| 3713 TEST(HeapTest, PreFinalizer) | 3723 TEST(HeapTest, PreFinalizer) |
| 3714 { | 3724 { |
| 3715 Observable::s_willFinalizeWasCalled = false; | 3725 Observable::s_willFinalizeWasCalled = false; |
| 3716 { | 3726 { |
| 3717 Observable* foo = Observable::create(Bar::create()); | 3727 Observable* foo = Observable::create(Bar::create()); |
| 3718 ThreadState::current()->registerPreFinalizer(foo); | 3728 ThreadState::current()->registerPreFinalizer(foo); |
| 3719 } | 3729 } |
| 3720 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3730 preciselyCollectGarbage(); |
| 3721 EXPECT_TRUE(Observable::s_willFinalizeWasCalled); | 3731 EXPECT_TRUE(Observable::s_willFinalizeWasCalled); |
| 3722 } | 3732 } |
| 3723 | 3733 |
| 3724 TEST(HeapTest, PreFinalizerIsNotCalledIfUnregistered) | 3734 TEST(HeapTest, PreFinalizerIsNotCalledIfUnregistered) |
| 3725 { | 3735 { |
| 3726 Observable::s_willFinalizeWasCalled = false; | 3736 Observable::s_willFinalizeWasCalled = false; |
| 3727 { | 3737 { |
| 3728 Observable* foo = Observable::create(Bar::create()); | 3738 Observable* foo = Observable::create(Bar::create()); |
| 3729 ThreadState::current()->registerPreFinalizer(foo); | 3739 ThreadState::current()->registerPreFinalizer(foo); |
| 3730 ThreadState::current()->unregisterPreFinalizer(foo); | 3740 ThreadState::current()->unregisterPreFinalizer(foo); |
| 3731 } | 3741 } |
| 3732 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3742 preciselyCollectGarbage(); |
| 3733 EXPECT_FALSE(Observable::s_willFinalizeWasCalled); | 3743 EXPECT_FALSE(Observable::s_willFinalizeWasCalled); |
| 3734 } | 3744 } |
| 3735 | 3745 |
| 3736 TEST(HeapTest, PreFinalizerUnregistersItself) | 3746 TEST(HeapTest, PreFinalizerUnregistersItself) |
| 3737 { | 3747 { |
| 3738 ObservableWithPreFinalizer::s_disposeWasCalled = false; | 3748 ObservableWithPreFinalizer::s_disposeWasCalled = false; |
| 3739 ObservableWithPreFinalizer::create(); | 3749 ObservableWithPreFinalizer::create(); |
| 3740 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3750 preciselyCollectGarbage(); |
| 3741 EXPECT_TRUE(ObservableWithPreFinalizer::s_disposeWasCalled); | 3751 EXPECT_TRUE(ObservableWithPreFinalizer::s_disposeWasCalled); |
| 3742 // Don't crash, and assertions don't fail. | 3752 // Don't crash, and assertions don't fail. |
| 3743 } | 3753 } |
| 3744 | 3754 |
| 3745 TEST(HeapTest, NestedPreFinalizer) | 3755 TEST(HeapTest, NestedPreFinalizer) |
| 3746 { | 3756 { |
| 3747 s_disposeWasCalledForPreFinalizerBase = false; | 3757 s_disposeWasCalledForPreFinalizerBase = false; |
| 3748 s_disposeWasCalledForPreFinalizerSubClass = false; | 3758 s_disposeWasCalledForPreFinalizerSubClass = false; |
| 3749 s_disposeWasCalledForPreFinalizerMixin = false; | 3759 s_disposeWasCalledForPreFinalizerMixin = false; |
| 3750 PreFinalizerSubClass::create(); | 3760 PreFinalizerSubClass::create(); |
| 3751 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3761 preciselyCollectGarbage(); |
| 3752 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerBase); | 3762 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerBase); |
| 3753 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerSubClass); | 3763 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerSubClass); |
| 3754 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerMixin); | 3764 EXPECT_TRUE(s_disposeWasCalledForPreFinalizerMixin); |
| 3755 // Don't crash, and assertions don't fail. | 3765 // Don't crash, and assertions don't fail. |
| 3756 } | 3766 } |
| 3757 | 3767 |
| 3758 TEST(HeapTest, Comparisons) | 3768 TEST(HeapTest, Comparisons) |
| 3759 { | 3769 { |
| 3760 Persistent<Bar> barPersistent = Bar::create(); | 3770 Persistent<Bar> barPersistent = Bar::create(); |
| 3761 Persistent<Foo> fooPersistent = Foo::create(barPersistent); | 3771 Persistent<Foo> fooPersistent = Foo::create(barPersistent); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3882 pVec.append(three); | 3892 pVec.append(three); |
| 3883 | 3893 |
| 3884 pSet.add(four); | 3894 pSet.add(four); |
| 3885 pListSet.add(eight); | 3895 pListSet.add(eight); |
| 3886 pLinkedSet.add(nine); | 3896 pLinkedSet.add(nine); |
| 3887 pMap.add(five, six); | 3897 pMap.add(five, six); |
| 3888 wpMap.add(ten, eleven); | 3898 wpMap.add(ten, eleven); |
| 3889 | 3899 |
| 3890 // Collect |vec| and |one|. | 3900 // Collect |vec| and |one|. |
| 3891 vec = 0; | 3901 vec = 0; |
| 3892 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3902 preciselyCollectGarbage(); |
| 3893 EXPECT_EQ(1, IntWrapper::s_destructorCalls); | 3903 EXPECT_EQ(1, IntWrapper::s_destructorCalls); |
| 3894 | 3904 |
| 3895 EXPECT_EQ(2u, pVec.size()); | 3905 EXPECT_EQ(2u, pVec.size()); |
| 3896 EXPECT_EQ(two, pVec.at(0)); | 3906 EXPECT_EQ(two, pVec.at(0)); |
| 3897 EXPECT_EQ(three, pVec.at(1)); | 3907 EXPECT_EQ(three, pVec.at(1)); |
| 3898 | 3908 |
| 3899 EXPECT_EQ(2u, pDeque.size()); | 3909 EXPECT_EQ(2u, pDeque.size()); |
| 3900 EXPECT_EQ(seven, pDeque.first()); | 3910 EXPECT_EQ(seven, pDeque.first()); |
| 3901 EXPECT_EQ(seven, pDeque.takeFirst()); | 3911 EXPECT_EQ(seven, pDeque.takeFirst()); |
| 3902 EXPECT_EQ(two, pDeque.first()); | 3912 EXPECT_EQ(two, pDeque.first()); |
| 3903 | 3913 |
| 3904 EXPECT_EQ(1u, pDeque.size()); | 3914 EXPECT_EQ(1u, pDeque.size()); |
| 3905 | 3915 |
| 3906 EXPECT_EQ(1u, pSet.size()); | 3916 EXPECT_EQ(1u, pSet.size()); |
| 3907 EXPECT_TRUE(pSet.contains(four)); | 3917 EXPECT_TRUE(pSet.contains(four)); |
| 3908 | 3918 |
| 3909 EXPECT_EQ(1u, pListSet.size()); | 3919 EXPECT_EQ(1u, pListSet.size()); |
| 3910 EXPECT_TRUE(pListSet.contains(eight)); | 3920 EXPECT_TRUE(pListSet.contains(eight)); |
| 3911 | 3921 |
| 3912 EXPECT_EQ(1u, pLinkedSet.size()); | 3922 EXPECT_EQ(1u, pLinkedSet.size()); |
| 3913 EXPECT_TRUE(pLinkedSet.contains(nine)); | 3923 EXPECT_TRUE(pLinkedSet.contains(nine)); |
| 3914 | 3924 |
| 3915 EXPECT_EQ(1u, pMap.size()); | 3925 EXPECT_EQ(1u, pMap.size()); |
| 3916 EXPECT_EQ(six, pMap.get(five)); | 3926 EXPECT_EQ(six, pMap.get(five)); |
| 3917 | 3927 |
| 3918 EXPECT_EQ(1u, wpMap.size()); | 3928 EXPECT_EQ(1u, wpMap.size()); |
| 3919 EXPECT_EQ(eleven, wpMap.get(ten)); | 3929 EXPECT_EQ(eleven, wpMap.get(ten)); |
| 3920 ten.clear(); | 3930 ten.clear(); |
| 3921 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 3931 preciselyCollectGarbage(); |
| 3922 EXPECT_EQ(0u, wpMap.size()); | 3932 EXPECT_EQ(0u, wpMap.size()); |
| 3923 } | 3933 } |
| 3924 | 3934 |
| 3925 // Collect previous roots. | 3935 // Collect previous roots. |
| 3926 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3936 preciselyCollectGarbage(); |
| 3927 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 3937 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
| 3928 } | 3938 } |
| 3929 | 3939 |
| 3930 TEST(HeapTest, CollectionNesting) | 3940 TEST(HeapTest, CollectionNesting) |
| 3931 { | 3941 { |
| 3932 clearOutOldGarbage(); | 3942 clearOutOldGarbage(); |
| 3933 int* key = &IntWrapper::s_destructorCalls; | 3943 int* key = &IntWrapper::s_destructorCalls; |
| 3934 IntWrapper::s_destructorCalls = 0; | 3944 IntWrapper::s_destructorCalls = 0; |
| 3935 typedef HeapVector<Member<IntWrapper>> IntVector; | 3945 typedef HeapVector<Member<IntWrapper>> IntVector; |
| 3936 typedef HeapDeque<Member<IntWrapper>> IntDeque; | 3946 typedef HeapDeque<Member<IntWrapper>> IntDeque; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3955 EXPECT_EQ(1u, map2->get(key).size()); | 3965 EXPECT_EQ(1u, map2->get(key).size()); |
| 3956 | 3966 |
| 3957 Persistent<HeapHashMap<void*, IntVector>> keepAlive(map); | 3967 Persistent<HeapHashMap<void*, IntVector>> keepAlive(map); |
| 3958 Persistent<HeapHashMap<void*, IntDeque>> keepAlive2(map2); | 3968 Persistent<HeapHashMap<void*, IntDeque>> keepAlive2(map2); |
| 3959 | 3969 |
| 3960 for (int i = 0; i < 100; i++) { | 3970 for (int i = 0; i < 100; i++) { |
| 3961 map->add(key + 1 + i, IntVector()); | 3971 map->add(key + 1 + i, IntVector()); |
| 3962 map2->add(key + 1 + i, IntDeque()); | 3972 map2->add(key + 1 + i, IntDeque()); |
| 3963 } | 3973 } |
| 3964 | 3974 |
| 3965 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3975 preciselyCollectGarbage(); |
| 3966 | 3976 |
| 3967 EXPECT_EQ(1u, map->get(key).size()); | 3977 EXPECT_EQ(1u, map->get(key).size()); |
| 3968 EXPECT_EQ(1u, map2->get(key).size()); | 3978 EXPECT_EQ(1u, map2->get(key).size()); |
| 3969 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3979 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 3970 | 3980 |
| 3971 keepAlive = nullptr; | 3981 keepAlive = nullptr; |
| 3972 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3982 preciselyCollectGarbage(); |
| 3973 EXPECT_EQ(1, IntWrapper::s_destructorCalls); | 3983 EXPECT_EQ(1, IntWrapper::s_destructorCalls); |
| 3974 } | 3984 } |
| 3975 | 3985 |
| 3976 TEST(HeapTest, GarbageCollectedMixin) | 3986 TEST(HeapTest, GarbageCollectedMixin) |
| 3977 { | 3987 { |
| 3978 clearOutOldGarbage(); | 3988 clearOutOldGarbage(); |
| 3979 | 3989 |
| 3980 Persistent<UseMixin> usemixin = UseMixin::create(); | 3990 Persistent<UseMixin> usemixin = UseMixin::create(); |
| 3981 EXPECT_EQ(0, UseMixin::s_traceCount); | 3991 EXPECT_EQ(0, UseMixin::s_traceCount); |
| 3982 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3992 preciselyCollectGarbage(); |
| 3983 EXPECT_EQ(1, UseMixin::s_traceCount); | 3993 EXPECT_EQ(1, UseMixin::s_traceCount); |
| 3984 | 3994 |
| 3985 Persistent<Mixin> mixin = usemixin; | 3995 Persistent<Mixin> mixin = usemixin; |
| 3986 usemixin = nullptr; | 3996 usemixin = nullptr; |
| 3987 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 3997 preciselyCollectGarbage(); |
| 3988 EXPECT_EQ(2, UseMixin::s_traceCount); | 3998 EXPECT_EQ(2, UseMixin::s_traceCount); |
| 3989 | 3999 |
| 3990 PersistentHeapHashSet<WeakMember<Mixin>> weakMap; | 4000 PersistentHeapHashSet<WeakMember<Mixin>> weakMap; |
| 3991 weakMap.add(UseMixin::create()); | 4001 weakMap.add(UseMixin::create()); |
| 3992 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4002 preciselyCollectGarbage(); |
| 3993 EXPECT_EQ(0u, weakMap.size()); | 4003 EXPECT_EQ(0u, weakMap.size()); |
| 3994 } | 4004 } |
| 3995 | 4005 |
| 3996 TEST(HeapTest, CollectionNesting2) | 4006 TEST(HeapTest, CollectionNesting2) |
| 3997 { | 4007 { |
| 3998 clearOutOldGarbage(); | 4008 clearOutOldGarbage(); |
| 3999 void* key = &IntWrapper::s_destructorCalls; | 4009 void* key = &IntWrapper::s_destructorCalls; |
| 4000 IntWrapper::s_destructorCalls = 0; | 4010 IntWrapper::s_destructorCalls = 0; |
| 4001 typedef HeapHashSet<Member<IntWrapper>> IntSet; | 4011 typedef HeapHashSet<Member<IntWrapper>> IntSet; |
| 4002 HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>(); | 4012 HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>(); |
| 4003 | 4013 |
| 4004 map->add(key, IntSet()); | 4014 map->add(key, IntSet()); |
| 4005 | 4015 |
| 4006 HeapHashMap<void*, IntSet>::iterator it = map->find(key); | 4016 HeapHashMap<void*, IntSet>::iterator it = map->find(key); |
| 4007 EXPECT_EQ(0u, map->get(key).size()); | 4017 EXPECT_EQ(0u, map->get(key).size()); |
| 4008 | 4018 |
| 4009 it->value.add(IntWrapper::create(42)); | 4019 it->value.add(IntWrapper::create(42)); |
| 4010 EXPECT_EQ(1u, map->get(key).size()); | 4020 EXPECT_EQ(1u, map->get(key).size()); |
| 4011 | 4021 |
| 4012 Persistent<HeapHashMap<void*, IntSet>> keepAlive(map); | 4022 Persistent<HeapHashMap<void*, IntSet>> keepAlive(map); |
| 4013 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4023 preciselyCollectGarbage(); |
| 4014 EXPECT_EQ(1u, map->get(key).size()); | 4024 EXPECT_EQ(1u, map->get(key).size()); |
| 4015 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4025 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4016 } | 4026 } |
| 4017 | 4027 |
| 4018 TEST(HeapTest, CollectionNesting3) | 4028 TEST(HeapTest, CollectionNesting3) |
| 4019 { | 4029 { |
| 4020 clearOutOldGarbage(); | 4030 clearOutOldGarbage(); |
| 4021 IntWrapper::s_destructorCalls = 0; | 4031 IntWrapper::s_destructorCalls = 0; |
| 4022 typedef HeapVector<Member<IntWrapper>> IntVector; | 4032 typedef HeapVector<Member<IntWrapper>> IntVector; |
| 4023 typedef HeapDeque<Member<IntWrapper>> IntDeque; | 4033 typedef HeapDeque<Member<IntWrapper>> IntDeque; |
| 4024 HeapVector<IntVector>* vector = new HeapVector<IntVector>(); | 4034 HeapVector<IntVector>* vector = new HeapVector<IntVector>(); |
| 4025 HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>(); | 4035 HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>(); |
| 4026 | 4036 |
| 4027 vector->append(IntVector()); | 4037 vector->append(IntVector()); |
| 4028 deque->append(IntDeque()); | 4038 deque->append(IntDeque()); |
| 4029 | 4039 |
| 4030 HeapVector<IntVector>::iterator it = vector->begin(); | 4040 HeapVector<IntVector>::iterator it = vector->begin(); |
| 4031 HeapDeque<IntDeque>::iterator it2 = deque->begin(); | 4041 HeapDeque<IntDeque>::iterator it2 = deque->begin(); |
| 4032 EXPECT_EQ(0u, it->size()); | 4042 EXPECT_EQ(0u, it->size()); |
| 4033 EXPECT_EQ(0u, it2->size()); | 4043 EXPECT_EQ(0u, it2->size()); |
| 4034 | 4044 |
| 4035 it->append(IntWrapper::create(42)); | 4045 it->append(IntWrapper::create(42)); |
| 4036 it2->append(IntWrapper::create(42)); | 4046 it2->append(IntWrapper::create(42)); |
| 4037 EXPECT_EQ(1u, it->size()); | 4047 EXPECT_EQ(1u, it->size()); |
| 4038 EXPECT_EQ(1u, it2->size()); | 4048 EXPECT_EQ(1u, it2->size()); |
| 4039 | 4049 |
| 4040 Persistent<HeapVector<IntVector>> keepAlive(vector); | 4050 Persistent<HeapVector<IntVector>> keepAlive(vector); |
| 4041 Persistent<HeapDeque<IntDeque>> keepAlive2(deque); | 4051 Persistent<HeapDeque<IntDeque>> keepAlive2(deque); |
| 4042 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4052 preciselyCollectGarbage(); |
| 4043 EXPECT_EQ(1u, it->size()); | 4053 EXPECT_EQ(1u, it->size()); |
| 4044 EXPECT_EQ(1u, it2->size()); | 4054 EXPECT_EQ(1u, it2->size()); |
| 4045 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4055 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4046 } | 4056 } |
| 4047 | 4057 |
| 4048 TEST(HeapTest, EmbeddedInVector) | 4058 TEST(HeapTest, EmbeddedInVector) |
| 4049 { | 4059 { |
| 4050 clearOutOldGarbage(); | 4060 clearOutOldGarbage(); |
| 4051 SimpleFinalizedObject::s_destructorCalls = 0; | 4061 SimpleFinalizedObject::s_destructorCalls = 0; |
| 4052 { | 4062 { |
| 4053 PersistentHeapVector<VectorObject, 2> inlineVector; | 4063 PersistentHeapVector<VectorObject, 2> inlineVector; |
| 4054 PersistentHeapVector<VectorObject> outlineVector; | 4064 PersistentHeapVector<VectorObject> outlineVector; |
| 4055 VectorObject i1, i2; | 4065 VectorObject i1, i2; |
| 4056 inlineVector.append(i1); | 4066 inlineVector.append(i1); |
| 4057 inlineVector.append(i2); | 4067 inlineVector.append(i2); |
| 4058 | 4068 |
| 4059 VectorObject o1, o2; | 4069 VectorObject o1, o2; |
| 4060 outlineVector.append(o1); | 4070 outlineVector.append(o1); |
| 4061 outlineVector.append(o2); | 4071 outlineVector.append(o2); |
| 4062 | 4072 |
| 4063 PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace; | 4073 PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace; |
| 4064 VectorObjectInheritedTrace it1, it2; | 4074 VectorObjectInheritedTrace it1, it2; |
| 4065 vectorInheritedTrace.append(it1); | 4075 vectorInheritedTrace.append(it1); |
| 4066 vectorInheritedTrace.append(it2); | 4076 vectorInheritedTrace.append(it2); |
| 4067 | 4077 |
| 4068 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4078 preciselyCollectGarbage(); |
| 4069 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 4079 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 4070 | 4080 |
| 4071 // Since VectorObjectNoTrace has no trace method it will | 4081 // Since VectorObjectNoTrace has no trace method it will |
| 4072 // not be traced and hence be collected when doing GC. | 4082 // not be traced and hence be collected when doing GC. |
| 4073 // We trace items in a collection braced on the item's | 4083 // We trace items in a collection braced on the item's |
| 4074 // having a trace method. This is determined via the | 4084 // having a trace method. This is determined via the |
| 4075 // NeedsTracing trait in wtf/TypeTraits.h. | 4085 // NeedsTracing trait in wtf/TypeTraits.h. |
| 4076 PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace; | 4086 PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace; |
| 4077 VectorObjectNoTrace n1, n2; | 4087 VectorObjectNoTrace n1, n2; |
| 4078 vectorNoTrace.append(n1); | 4088 vectorNoTrace.append(n1); |
| 4079 vectorNoTrace.append(n2); | 4089 vectorNoTrace.append(n2); |
| 4080 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4090 preciselyCollectGarbage(); |
| 4081 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); | 4091 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); |
| 4082 } | 4092 } |
| 4083 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4093 preciselyCollectGarbage(); |
| 4084 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); | 4094 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); |
| 4085 } | 4095 } |
| 4086 | 4096 |
| 4087 TEST(HeapTest, EmbeddedInDeque) | 4097 TEST(HeapTest, EmbeddedInDeque) |
| 4088 { | 4098 { |
| 4089 clearOutOldGarbage(); | 4099 clearOutOldGarbage(); |
| 4090 SimpleFinalizedObject::s_destructorCalls = 0; | 4100 SimpleFinalizedObject::s_destructorCalls = 0; |
| 4091 { | 4101 { |
| 4092 PersistentHeapDeque<VectorObject, 2> inlineDeque; | 4102 PersistentHeapDeque<VectorObject, 2> inlineDeque; |
| 4093 PersistentHeapDeque<VectorObject> outlineDeque; | 4103 PersistentHeapDeque<VectorObject> outlineDeque; |
| 4094 VectorObject i1, i2; | 4104 VectorObject i1, i2; |
| 4095 inlineDeque.append(i1); | 4105 inlineDeque.append(i1); |
| 4096 inlineDeque.append(i2); | 4106 inlineDeque.append(i2); |
| 4097 | 4107 |
| 4098 VectorObject o1, o2; | 4108 VectorObject o1, o2; |
| 4099 outlineDeque.append(o1); | 4109 outlineDeque.append(o1); |
| 4100 outlineDeque.append(o2); | 4110 outlineDeque.append(o2); |
| 4101 | 4111 |
| 4102 PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace; | 4112 PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace; |
| 4103 VectorObjectInheritedTrace it1, it2; | 4113 VectorObjectInheritedTrace it1, it2; |
| 4104 dequeInheritedTrace.append(it1); | 4114 dequeInheritedTrace.append(it1); |
| 4105 dequeInheritedTrace.append(it2); | 4115 dequeInheritedTrace.append(it2); |
| 4106 | 4116 |
| 4107 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4117 preciselyCollectGarbage(); |
| 4108 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 4118 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 4109 | 4119 |
| 4110 // Since VectorObjectNoTrace has no trace method it will | 4120 // Since VectorObjectNoTrace has no trace method it will |
| 4111 // not be traced and hence be collected when doing GC. | 4121 // not be traced and hence be collected when doing GC. |
| 4112 // We trace items in a collection braced on the item's | 4122 // We trace items in a collection braced on the item's |
| 4113 // having a trace method. This is determined via the | 4123 // having a trace method. This is determined via the |
| 4114 // NeedsTracing trait in wtf/TypeTraits.h. | 4124 // NeedsTracing trait in wtf/TypeTraits.h. |
| 4115 PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace; | 4125 PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace; |
| 4116 VectorObjectNoTrace n1, n2; | 4126 VectorObjectNoTrace n1, n2; |
| 4117 dequeNoTrace.append(n1); | 4127 dequeNoTrace.append(n1); |
| 4118 dequeNoTrace.append(n2); | 4128 dequeNoTrace.append(n2); |
| 4119 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4129 preciselyCollectGarbage(); |
| 4120 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); | 4130 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); |
| 4121 } | 4131 } |
| 4122 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4132 preciselyCollectGarbage(); |
| 4123 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); | 4133 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); |
| 4124 } | 4134 } |
| 4125 | 4135 |
| 4126 class InlinedVectorObject { | 4136 class InlinedVectorObject { |
| 4127 ALLOW_ONLY_INLINE_ALLOCATION(); | 4137 ALLOW_ONLY_INLINE_ALLOCATION(); |
| 4128 public: | 4138 public: |
| 4129 InlinedVectorObject() | 4139 InlinedVectorObject() |
| 4130 { | 4140 { |
| 4131 } | 4141 } |
| 4132 ~InlinedVectorObject() | 4142 ~InlinedVectorObject() |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4223 TEST(HeapTest, VectorDestructors) | 4233 TEST(HeapTest, VectorDestructors) |
| 4224 { | 4234 { |
| 4225 clearOutOldGarbage(); | 4235 clearOutOldGarbage(); |
| 4226 InlinedVectorObject::s_destructorCalls = 0; | 4236 InlinedVectorObject::s_destructorCalls = 0; |
| 4227 { | 4237 { |
| 4228 HeapVector<InlinedVectorObject> vector; | 4238 HeapVector<InlinedVectorObject> vector; |
| 4229 InlinedVectorObject i1, i2; | 4239 InlinedVectorObject i1, i2; |
| 4230 vector.append(i1); | 4240 vector.append(i1); |
| 4231 vector.append(i2); | 4241 vector.append(i2); |
| 4232 } | 4242 } |
| 4233 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4243 preciselyCollectGarbage(); |
| 4234 // This is not EXPECT_EQ but EXPECT_LE because a HeapVectorBacking calls | 4244 // This is not EXPECT_EQ but EXPECT_LE because a HeapVectorBacking calls |
| 4235 // destructors for all elements in (not the size but) the capacity of | 4245 // destructors for all elements in (not the size but) the capacity of |
| 4236 // the vector. Thus the number of destructors called becomes larger | 4246 // the vector. Thus the number of destructors called becomes larger |
| 4237 // than the actual number of objects in the vector. | 4247 // than the actual number of objects in the vector. |
| 4238 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); | 4248 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); |
| 4239 | 4249 |
| 4240 InlinedVectorObject::s_destructorCalls = 0; | 4250 InlinedVectorObject::s_destructorCalls = 0; |
| 4241 { | 4251 { |
| 4242 HeapVector<InlinedVectorObject, 1> vector; | 4252 HeapVector<InlinedVectorObject, 1> vector; |
| 4243 InlinedVectorObject i1, i2; | 4253 InlinedVectorObject i1, i2; |
| 4244 vector.append(i1); | 4254 vector.append(i1); |
| 4245 vector.append(i2); // This allocates an out-of-line buffer. | 4255 vector.append(i2); // This allocates an out-of-line buffer. |
| 4246 } | 4256 } |
| 4247 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4257 preciselyCollectGarbage(); |
| 4248 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); | 4258 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); |
| 4249 | 4259 |
| 4250 InlinedVectorObject::s_destructorCalls = 0; | 4260 InlinedVectorObject::s_destructorCalls = 0; |
| 4251 { | 4261 { |
| 4252 HeapVector<InlinedVectorObject, 2> vector; | 4262 HeapVector<InlinedVectorObject, 2> vector; |
| 4253 InlinedVectorObject i1, i2; | 4263 InlinedVectorObject i1, i2; |
| 4254 vector.append(i1); | 4264 vector.append(i1); |
| 4255 vector.append(i2); | 4265 vector.append(i2); |
| 4256 } | 4266 } |
| 4257 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4267 preciselyCollectGarbage(); |
| 4258 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); | 4268 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls); |
| 4259 | 4269 |
| 4260 InlinedVectorObject::s_destructorCalls = 0; | 4270 InlinedVectorObject::s_destructorCalls = 0; |
| 4261 { | 4271 { |
| 4262 Persistent<InlinedVectorObjectWrapper> vectorWrapper = new InlinedVector
ObjectWrapper(); | 4272 Persistent<InlinedVectorObjectWrapper> vectorWrapper = new InlinedVector
ObjectWrapper(); |
| 4263 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4273 conservativelyCollectGarbage(); |
| 4264 EXPECT_EQ(2, InlinedVectorObject::s_destructorCalls); | 4274 EXPECT_EQ(2, InlinedVectorObject::s_destructorCalls); |
| 4265 } | 4275 } |
| 4266 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4276 preciselyCollectGarbage(); |
| 4267 EXPECT_LE(8, InlinedVectorObject::s_destructorCalls); | 4277 EXPECT_LE(8, InlinedVectorObject::s_destructorCalls); |
| 4268 } | 4278 } |
| 4269 | 4279 |
| 4270 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables | 4280 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables |
| 4271 // Vector<>s with inline capacity, enable this test. | 4281 // Vector<>s with inline capacity, enable this test. |
| 4272 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) | 4282 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) |
| 4273 TEST(HeapTest, VectorDestructorsWithVtable) | 4283 TEST(HeapTest, VectorDestructorsWithVtable) |
| 4274 { | 4284 { |
| 4275 clearOutOldGarbage(); | 4285 clearOutOldGarbage(); |
| 4276 InlinedVectorObjectWithVtable::s_destructorCalls = 0; | 4286 InlinedVectorObjectWithVtable::s_destructorCalls = 0; |
| 4277 { | 4287 { |
| 4278 HeapVector<InlinedVectorObjectWithVtable> vector; | 4288 HeapVector<InlinedVectorObjectWithVtable> vector; |
| 4279 InlinedVectorObjectWithVtable i1, i2; | 4289 InlinedVectorObjectWithVtable i1, i2; |
| 4280 vector.append(i1); | 4290 vector.append(i1); |
| 4281 vector.append(i2); | 4291 vector.append(i2); |
| 4282 } | 4292 } |
| 4283 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4293 preciselyCollectGarbage(); |
| 4284 EXPECT_EQ(4, InlinedVectorObjectWithVtable::s_destructorCalls); | 4294 EXPECT_EQ(4, InlinedVectorObjectWithVtable::s_destructorCalls); |
| 4285 | 4295 |
| 4286 InlinedVectorObjectWithVtable::s_destructorCalls = 0; | 4296 InlinedVectorObjectWithVtable::s_destructorCalls = 0; |
| 4287 { | 4297 { |
| 4288 HeapVector<InlinedVectorObjectWithVtable, 1> vector; | 4298 HeapVector<InlinedVectorObjectWithVtable, 1> vector; |
| 4289 InlinedVectorObjectWithVtable i1, i2; | 4299 InlinedVectorObjectWithVtable i1, i2; |
| 4290 vector.append(i1); | 4300 vector.append(i1); |
| 4291 vector.append(i2); // This allocates an out-of-line buffer. | 4301 vector.append(i2); // This allocates an out-of-line buffer. |
| 4292 } | 4302 } |
| 4293 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4303 preciselyCollectGarbage(); |
| 4294 EXPECT_EQ(5, InlinedVectorObjectWithVtable::s_destructorCalls); | 4304 EXPECT_EQ(5, InlinedVectorObjectWithVtable::s_destructorCalls); |
| 4295 | 4305 |
| 4296 InlinedVectorObjectWithVtable::s_destructorCalls = 0; | 4306 InlinedVectorObjectWithVtable::s_destructorCalls = 0; |
| 4297 { | 4307 { |
| 4298 HeapVector<InlinedVectorObjectWithVtable, 2> vector; | 4308 HeapVector<InlinedVectorObjectWithVtable, 2> vector; |
| 4299 InlinedVectorObjectWithVtable i1, i2; | 4309 InlinedVectorObjectWithVtable i1, i2; |
| 4300 vector.append(i1); | 4310 vector.append(i1); |
| 4301 vector.append(i2); | 4311 vector.append(i2); |
| 4302 } | 4312 } |
| 4303 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4313 preciselyCollectGarbage(); |
| 4304 EXPECT_EQ(4, InlinedVectorObjectWithVtable::s_destructorCalls); | 4314 EXPECT_EQ(4, InlinedVectorObjectWithVtable::s_destructorCalls); |
| 4305 | 4315 |
| 4306 InlinedVectorObjectWithVtable::s_destructorCalls = 0; | 4316 InlinedVectorObjectWithVtable::s_destructorCalls = 0; |
| 4307 { | 4317 { |
| 4308 Persistent<InlinedVectorObjectWithVtableWrapper> vectorWrapper = new Inl
inedVectorObjectWithVtableWrapper(); | 4318 Persistent<InlinedVectorObjectWithVtableWrapper> vectorWrapper = new Inl
inedVectorObjectWithVtableWrapper(); |
| 4309 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4319 conservativelyCollectGarbage(); |
| 4310 EXPECT_EQ(3, InlinedVectorObjectWithVtable::s_destructorCalls); | 4320 EXPECT_EQ(3, InlinedVectorObjectWithVtable::s_destructorCalls); |
| 4311 } | 4321 } |
| 4312 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4322 preciselyCollectGarbage(); |
| 4313 EXPECT_EQ(9, InlinedVectorObjectWithVtable::s_destructorCalls); | 4323 EXPECT_EQ(9, InlinedVectorObjectWithVtable::s_destructorCalls); |
| 4314 } | 4324 } |
| 4315 #endif | 4325 #endif |
| 4316 | 4326 |
| 4317 template<typename Set> | 4327 template<typename Set> |
| 4318 void rawPtrInHashHelper() | 4328 void rawPtrInHashHelper() |
| 4319 { | 4329 { |
| 4320 Set set; | 4330 Set set; |
| 4321 set.add(new int(42)); | 4331 set.add(new int(42)); |
| 4322 set.add(new int(42)); | 4332 set.add(new int(42)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4345 const size_t suffixSize = 4; | 4355 const size_t suffixSize = 4; |
| 4346 | 4356 |
| 4347 { | 4357 { |
| 4348 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); | 4358 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); |
| 4349 builder.grow(prefixSize); | 4359 builder.grow(prefixSize); |
| 4350 for (size_t i = 0; i < prefixSize; i++) | 4360 for (size_t i = 0; i < prefixSize; i++) |
| 4351 builder.append(TerminatedArrayItem(IntWrapper::create(i))); | 4361 builder.append(TerminatedArrayItem(IntWrapper::create(i))); |
| 4352 arr = builder.release(); | 4362 arr = builder.release(); |
| 4353 } | 4363 } |
| 4354 | 4364 |
| 4355 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); | 4365 conservativelyCollectGarbage(); |
| 4356 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4366 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4357 EXPECT_EQ(prefixSize, arr->size()); | 4367 EXPECT_EQ(prefixSize, arr->size()); |
| 4358 for (size_t i = 0; i < prefixSize; i++) | 4368 for (size_t i = 0; i < prefixSize; i++) |
| 4359 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 4369 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
| 4360 | 4370 |
| 4361 { | 4371 { |
| 4362 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); | 4372 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); |
| 4363 builder.grow(suffixSize); | 4373 builder.grow(suffixSize); |
| 4364 for (size_t i = 0; i < suffixSize; i++) | 4374 for (size_t i = 0; i < suffixSize; i++) |
| 4365 builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i
))); | 4375 builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i
))); |
| 4366 arr = builder.release(); | 4376 arr = builder.release(); |
| 4367 } | 4377 } |
| 4368 | 4378 |
| 4369 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); | 4379 conservativelyCollectGarbage(); |
| 4370 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4380 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4371 EXPECT_EQ(prefixSize + suffixSize, arr->size()); | 4381 EXPECT_EQ(prefixSize + suffixSize, arr->size()); |
| 4372 for (size_t i = 0; i < prefixSize + suffixSize; i++) | 4382 for (size_t i = 0; i < prefixSize + suffixSize; i++) |
| 4373 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 4383 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
| 4374 | 4384 |
| 4375 { | 4385 { |
| 4376 Persistent<HeapTerminatedArray<TerminatedArrayItem>> persistentArr = arr
; | 4386 Persistent<HeapTerminatedArray<TerminatedArrayItem>> persistentArr = arr
; |
| 4377 arr = 0; | 4387 arr = 0; |
| 4378 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4388 preciselyCollectGarbage(); |
| 4379 arr = persistentArr.get(); | 4389 arr = persistentArr.get(); |
| 4380 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4390 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4381 EXPECT_EQ(prefixSize + suffixSize, arr->size()); | 4391 EXPECT_EQ(prefixSize + suffixSize, arr->size()); |
| 4382 for (size_t i = 0; i < prefixSize + suffixSize; i++) | 4392 for (size_t i = 0; i < prefixSize + suffixSize; i++) |
| 4383 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 4393 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
| 4384 } | 4394 } |
| 4385 | 4395 |
| 4386 arr = 0; | 4396 arr = 0; |
| 4387 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4397 preciselyCollectGarbage(); |
| 4388 EXPECT_EQ(8, IntWrapper::s_destructorCalls); | 4398 EXPECT_EQ(8, IntWrapper::s_destructorCalls); |
| 4389 } | 4399 } |
| 4390 | 4400 |
| 4391 TEST(HeapTest, HeapLinkedStack) | 4401 TEST(HeapTest, HeapLinkedStack) |
| 4392 { | 4402 { |
| 4393 clearOutOldGarbage(); | 4403 clearOutOldGarbage(); |
| 4394 IntWrapper::s_destructorCalls = 0; | 4404 IntWrapper::s_destructorCalls = 0; |
| 4395 | 4405 |
| 4396 HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<Terminated
ArrayItem>(); | 4406 HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<Terminated
ArrayItem>(); |
| 4397 | 4407 |
| 4398 const size_t stackSize = 10; | 4408 const size_t stackSize = 10; |
| 4399 | 4409 |
| 4400 for (size_t i = 0; i < stackSize; i++) | 4410 for (size_t i = 0; i < stackSize; i++) |
| 4401 stack->push(TerminatedArrayItem(IntWrapper::create(i))); | 4411 stack->push(TerminatedArrayItem(IntWrapper::create(i))); |
| 4402 | 4412 |
| 4403 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); | 4413 conservativelyCollectGarbage(); |
| 4404 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4414 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4405 EXPECT_EQ(stackSize, stack->size()); | 4415 EXPECT_EQ(stackSize, stack->size()); |
| 4406 while (!stack->isEmpty()) { | 4416 while (!stack->isEmpty()) { |
| 4407 EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()
->value())); | 4417 EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()
->value())); |
| 4408 stack->pop(); | 4418 stack->pop(); |
| 4409 } | 4419 } |
| 4410 | 4420 |
| 4411 Persistent<HeapLinkedStack<TerminatedArrayItem>> pStack = stack; | 4421 Persistent<HeapLinkedStack<TerminatedArrayItem>> pStack = stack; |
| 4412 | 4422 |
| 4413 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4423 preciselyCollectGarbage(); |
| 4414 EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls)); | 4424 EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls)); |
| 4415 EXPECT_EQ(0u, pStack->size()); | 4425 EXPECT_EQ(0u, pStack->size()); |
| 4416 } | 4426 } |
| 4417 | 4427 |
| 4418 TEST(HeapTest, AllocationDuringFinalization) | 4428 TEST(HeapTest, AllocationDuringFinalization) |
| 4419 { | 4429 { |
| 4420 clearOutOldGarbage(); | 4430 clearOutOldGarbage(); |
| 4421 IntWrapper::s_destructorCalls = 0; | 4431 IntWrapper::s_destructorCalls = 0; |
| 4422 OneKiloByteObject::s_destructorCalls = 0; | 4432 OneKiloByteObject::s_destructorCalls = 0; |
| 4423 LargeHeapObject::s_destructorCalls = 0; | 4433 LargeHeapObject::s_destructorCalls = 0; |
| 4424 | 4434 |
| 4425 Persistent<IntWrapper> wrapper; | 4435 Persistent<IntWrapper> wrapper; |
| 4426 new FinalizationAllocator(&wrapper); | 4436 new FinalizationAllocator(&wrapper); |
| 4427 | 4437 |
| 4428 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4438 preciselyCollectGarbage(); |
| 4429 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4439 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4430 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); | 4440 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); |
| 4431 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 4441 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 4432 // Check that the wrapper allocated during finalization is not | 4442 // Check that the wrapper allocated during finalization is not |
| 4433 // swept away and zapped later in the same sweeping phase. | 4443 // swept away and zapped later in the same sweeping phase. |
| 4434 EXPECT_EQ(42, wrapper->value()); | 4444 EXPECT_EQ(42, wrapper->value()); |
| 4435 | 4445 |
| 4436 wrapper.clear(); | 4446 wrapper.clear(); |
| 4437 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4447 preciselyCollectGarbage(); |
| 4438 // The 42 IntWrappers were the ones allocated in ~FinalizationAllocator | 4448 // The 42 IntWrappers were the ones allocated in ~FinalizationAllocator |
| 4439 // and the ones allocated in LargeHeapObject. | 4449 // and the ones allocated in LargeHeapObject. |
| 4440 EXPECT_EQ(42, IntWrapper::s_destructorCalls); | 4450 EXPECT_EQ(42, IntWrapper::s_destructorCalls); |
| 4441 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); | 4451 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); |
| 4442 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); | 4452 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); |
| 4443 } | 4453 } |
| 4444 | 4454 |
| 4445 TEST(HeapTest, AllocationDuringPrefinalizer) | 4455 TEST(HeapTest, AllocationDuringPrefinalizer) |
| 4446 { | 4456 { |
| 4447 clearOutOldGarbage(); | 4457 clearOutOldGarbage(); |
| 4448 IntWrapper::s_destructorCalls = 0; | 4458 IntWrapper::s_destructorCalls = 0; |
| 4449 OneKiloByteObject::s_destructorCalls = 0; | 4459 OneKiloByteObject::s_destructorCalls = 0; |
| 4450 LargeHeapObject::s_destructorCalls = 0; | 4460 LargeHeapObject::s_destructorCalls = 0; |
| 4451 | 4461 |
| 4452 Persistent<IntWrapper> wrapper; | 4462 Persistent<IntWrapper> wrapper; |
| 4453 new PreFinalizationAllocator(&wrapper); | 4463 new PreFinalizationAllocator(&wrapper); |
| 4454 | 4464 |
| 4455 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4465 preciselyCollectGarbage(); |
| 4456 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4466 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4457 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); | 4467 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); |
| 4458 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 4468 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 4459 // Check that the wrapper allocated during finalization is not | 4469 // Check that the wrapper allocated during finalization is not |
| 4460 // swept away and zapped later in the same sweeping phase. | 4470 // swept away and zapped later in the same sweeping phase. |
| 4461 EXPECT_EQ(42, wrapper->value()); | 4471 EXPECT_EQ(42, wrapper->value()); |
| 4462 | 4472 |
| 4463 wrapper.clear(); | 4473 wrapper.clear(); |
| 4464 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4474 preciselyCollectGarbage(); |
| 4465 // The 42 IntWrappers were the ones allocated in the pre-finalizer | 4475 // The 42 IntWrappers were the ones allocated in the pre-finalizer |
| 4466 // of PreFinalizationAllocator and the ones allocated in LargeHeapObject. | 4476 // of PreFinalizationAllocator and the ones allocated in LargeHeapObject. |
| 4467 EXPECT_EQ(42, IntWrapper::s_destructorCalls); | 4477 EXPECT_EQ(42, IntWrapper::s_destructorCalls); |
| 4468 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); | 4478 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); |
| 4469 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); | 4479 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); |
| 4470 } | 4480 } |
| 4471 | 4481 |
| 4472 class SimpleClassWithDestructor { | 4482 class SimpleClassWithDestructor { |
| 4473 public: | 4483 public: |
| 4474 SimpleClassWithDestructor() { } | 4484 SimpleClassWithDestructor() { } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4503 set.add(adoptRef(hasDestructor)); | 4513 set.add(adoptRef(hasDestructor)); |
| 4504 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4514 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
| 4505 | 4515 |
| 4506 if (addLots) { | 4516 if (addLots) { |
| 4507 for (int i = 0; i < 1000; i++) { | 4517 for (int i = 0; i < 1000; i++) { |
| 4508 set.add(adoptRef(new RefCountedWithDestructor())); | 4518 set.add(adoptRef(new RefCountedWithDestructor())); |
| 4509 } | 4519 } |
| 4510 } | 4520 } |
| 4511 | 4521 |
| 4512 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4522 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
| 4513 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4523 conservativelyCollectGarbage(); |
| 4514 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4524 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
| 4515 } | 4525 } |
| 4516 // The destructors of the sets don't call the destructors of the elements | 4526 // The destructors of the sets don't call the destructors of the elements |
| 4517 // in the heap sets. You have to actually remove the elments, call clear() | 4527 // in the heap sets. You have to actually remove the elments, call clear() |
| 4518 // or have a GC to get the destructors called. | 4528 // or have a GC to get the destructors called. |
| 4519 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4529 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
| 4520 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4530 preciselyCollectGarbage(); |
| 4521 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); | 4531 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); |
| 4522 } | 4532 } |
| 4523 | 4533 |
| 4524 template<typename Set> | 4534 template<typename Set> |
| 4525 void destructorsCalledOnClear(bool addLots) | 4535 void destructorsCalledOnClear(bool addLots) |
| 4526 { | 4536 { |
| 4527 RefCountedWithDestructor::s_wasDestructed = false; | 4537 RefCountedWithDestructor::s_wasDestructed = false; |
| 4528 Set set; | 4538 Set set; |
| 4529 RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor(); | 4539 RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor(); |
| 4530 set.add(adoptRef(hasDestructor)); | 4540 set.add(adoptRef(hasDestructor)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4604 TEST(HeapTest, MultipleMixins) | 4614 TEST(HeapTest, MultipleMixins) |
| 4605 { | 4615 { |
| 4606 EXPECT_TRUE(s_isMixinTrue); | 4616 EXPECT_TRUE(s_isMixinTrue); |
| 4607 EXPECT_FALSE(s_isMixinFalse); | 4617 EXPECT_FALSE(s_isMixinFalse); |
| 4608 | 4618 |
| 4609 clearOutOldGarbage(); | 4619 clearOutOldGarbage(); |
| 4610 IntWrapper::s_destructorCalls = 0; | 4620 IntWrapper::s_destructorCalls = 0; |
| 4611 MultipleMixins* obj = new MultipleMixins(); | 4621 MultipleMixins* obj = new MultipleMixins(); |
| 4612 { | 4622 { |
| 4613 Persistent<MixinA> a = obj; | 4623 Persistent<MixinA> a = obj; |
| 4614 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4624 preciselyCollectGarbage(); |
| 4615 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4625 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4616 } | 4626 } |
| 4617 { | 4627 { |
| 4618 Persistent<MixinB> b = obj; | 4628 Persistent<MixinB> b = obj; |
| 4619 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 4629 preciselyCollectGarbage(); |
| 4620 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4630 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 4621 } | 4631 } |
| 4622 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4632 preciselyCollectGarbage(); |
| 4623 EXPECT_EQ(3, IntWrapper::s_destructorCalls); | 4633 EXPECT_EQ(3, IntWrapper::s_destructorCalls); |
| 4624 } | 4634 } |
| 4625 | 4635 |
| 4626 class GCParkingThreadTester { | 4636 class GCParkingThreadTester { |
| 4627 public: | 4637 public: |
| 4628 static void test() | 4638 static void test() |
| 4629 { | 4639 { |
| 4630 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); | 4640 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); |
| 4631 sleepingThread->postTask(FROM_HERE, new Task(threadSafeBind(sleeperMainF
unc))); | 4641 sleepingThread->postTask(FROM_HERE, new Task(threadSafeBind(sleeperMainF
unc))); |
| 4632 | 4642 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4705 { | 4715 { |
| 4706 typedef typename Set::iterator Iterator; | 4716 typedef typename Set::iterator Iterator; |
| 4707 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4717 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
| 4708 Persistent<Set> set1(new Set()); | 4718 Persistent<Set> set1(new Set()); |
| 4709 { | 4719 { |
| 4710 Set set2; | 4720 Set set2; |
| 4711 Set* set3 = new Set(); | 4721 Set* set3 = new Set(); |
| 4712 set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1))); | 4722 set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1))); |
| 4713 set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3))); | 4723 set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3))); |
| 4714 set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5))); | 4724 set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5))); |
| 4715 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4725 conservativelyCollectGarbage(); |
| 4716 // The first set is pointed to from a persistent, so it's referenced, bu
t | 4726 // The first set is pointed to from a persistent, so it's referenced, bu
t |
| 4717 // the weak processing may have taken place. | 4727 // the weak processing may have taken place. |
| 4718 if (set1->size()) { | 4728 if (set1->size()) { |
| 4719 Iterator i1 = set1->begin(); | 4729 Iterator i1 = set1->begin(); |
| 4720 EXPECT_EQ(4, i1->first->value()); | 4730 EXPECT_EQ(4, i1->first->value()); |
| 4721 EXPECT_EQ(5, i1->second->value()); | 4731 EXPECT_EQ(5, i1->second->value()); |
| 4722 } | 4732 } |
| 4723 // The second set is on-stack, so its backing store must be referenced f
rom | 4733 // The second set is on-stack, so its backing store must be referenced f
rom |
| 4724 // the stack. That makes the weak references strong. | 4734 // the stack. That makes the weak references strong. |
| 4725 Iterator i2 = set2.begin(); | 4735 Iterator i2 = set2.begin(); |
| 4726 EXPECT_EQ(0, i2->first->value()); | 4736 EXPECT_EQ(0, i2->first->value()); |
| 4727 EXPECT_EQ(1, i2->second->value()); | 4737 EXPECT_EQ(1, i2->second->value()); |
| 4728 // The third set is pointed to from the stack, so it's referenced, but t
he | 4738 // The third set is pointed to from the stack, so it's referenced, but t
he |
| 4729 // weak processing may have taken place. | 4739 // weak processing may have taken place. |
| 4730 if (set3->size()) { | 4740 if (set3->size()) { |
| 4731 Iterator i3 = set3->begin(); | 4741 Iterator i3 = set3->begin(); |
| 4732 EXPECT_EQ(2, i3->first->value()); | 4742 EXPECT_EQ(2, i3->first->value()); |
| 4733 EXPECT_EQ(3, i3->second->value()); | 4743 EXPECT_EQ(3, i3->second->value()); |
| 4734 } | 4744 } |
| 4735 } | 4745 } |
| 4736 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4746 preciselyCollectGarbage(); |
| 4737 EXPECT_EQ(0u, set1->size()); | 4747 EXPECT_EQ(0u, set1->size()); |
| 4738 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); | 4748 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); |
| 4739 set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This
one gets zapped at GC time because nothing holds the 103 alive. | 4749 set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This
one gets zapped at GC time because nothing holds the 103 alive. |
| 4740 set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03))); // This one gets zapped too. | 4750 set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03))); // This one gets zapped too. |
| 4741 set1->add(PairWithWeakHandling(livingInt, livingInt)); | 4751 set1->add(PairWithWeakHandling(livingInt, livingInt)); |
| 4742 set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identi
cal to the previous and doesn't add anything. | 4752 set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identi
cal to the previous and doesn't add anything. |
| 4743 EXPECT_EQ(4u, set1->size()); | 4753 EXPECT_EQ(4u, set1->size()); |
| 4744 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4754 preciselyCollectGarbage(); |
| 4745 EXPECT_EQ(2u, set1->size()); | 4755 EXPECT_EQ(2u, set1->size()); |
| 4746 Iterator i1 = set1->begin(); | 4756 Iterator i1 = set1->begin(); |
| 4747 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4757 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
| 4748 EXPECT_EQ(livingInt, i1->second); | 4758 EXPECT_EQ(livingInt, i1->second); |
| 4749 ++i1; | 4759 ++i1; |
| 4750 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4760 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
| 4751 EXPECT_EQ(livingInt, i1->second); | 4761 EXPECT_EQ(livingInt, i1->second); |
| 4752 } | 4762 } |
| 4753 | 4763 |
| 4754 TEST(HeapTest, SetWithCustomWeaknessHandling) | 4764 TEST(HeapTest, SetWithCustomWeaknessHandling) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4767 Persistent<Map> map1(new Map()); | 4777 Persistent<Map> map1(new Map()); |
| 4768 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4778 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
| 4769 { | 4779 { |
| 4770 Map map2; | 4780 Map map2; |
| 4771 Map* map3 = new Map(); | 4781 Map* map3 = new Map(); |
| 4772 map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1)), OffHeapInt::create(1001)); | 4782 map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1)), OffHeapInt::create(1001)); |
| 4773 map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3)), OffHeapInt::create(1002)); | 4783 map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3)), OffHeapInt::create(1002)); |
| 4774 map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5)), OffHeapInt::create(1003)); | 4784 map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5)), OffHeapInt::create(1003)); |
| 4775 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4785 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
| 4776 | 4786 |
| 4777 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4787 conservativelyCollectGarbage(); |
| 4778 // The first map2 is pointed to from a persistent, so it's referenced, b
ut | 4788 // The first map2 is pointed to from a persistent, so it's referenced, b
ut |
| 4779 // the weak processing may have taken place. | 4789 // the weak processing may have taken place. |
| 4780 if (map1->size()) { | 4790 if (map1->size()) { |
| 4781 Iterator i1 = map1->begin(); | 4791 Iterator i1 = map1->begin(); |
| 4782 EXPECT_EQ(4, i1->key.first->value()); | 4792 EXPECT_EQ(4, i1->key.first->value()); |
| 4783 EXPECT_EQ(5, i1->key.second->value()); | 4793 EXPECT_EQ(5, i1->key.second->value()); |
| 4784 EXPECT_EQ(1003, i1->value->value()); | 4794 EXPECT_EQ(1003, i1->value->value()); |
| 4785 } | 4795 } |
| 4786 // The second map2 is on-stack, so its backing store must be referenced
from | 4796 // The second map2 is on-stack, so its backing store must be referenced
from |
| 4787 // the stack. That makes the weak references strong. | 4797 // the stack. That makes the weak references strong. |
| 4788 Iterator i2 = map2.begin(); | 4798 Iterator i2 = map2.begin(); |
| 4789 EXPECT_EQ(0, i2->key.first->value()); | 4799 EXPECT_EQ(0, i2->key.first->value()); |
| 4790 EXPECT_EQ(1, i2->key.second->value()); | 4800 EXPECT_EQ(1, i2->key.second->value()); |
| 4791 EXPECT_EQ(1001, i2->value->value()); | 4801 EXPECT_EQ(1001, i2->value->value()); |
| 4792 // The third map2 is pointed to from the stack, so it's referenced, but
the | 4802 // The third map2 is pointed to from the stack, so it's referenced, but
the |
| 4793 // weak processing may have taken place. | 4803 // weak processing may have taken place. |
| 4794 if (map3->size()) { | 4804 if (map3->size()) { |
| 4795 Iterator i3 = map3->begin(); | 4805 Iterator i3 = map3->begin(); |
| 4796 EXPECT_EQ(2, i3->key.first->value()); | 4806 EXPECT_EQ(2, i3->key.first->value()); |
| 4797 EXPECT_EQ(3, i3->key.second->value()); | 4807 EXPECT_EQ(3, i3->key.second->value()); |
| 4798 EXPECT_EQ(1002, i3->value->value()); | 4808 EXPECT_EQ(1002, i3->value->value()); |
| 4799 } | 4809 } |
| 4800 } | 4810 } |
| 4801 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4811 preciselyCollectGarbage(); |
| 4802 | 4812 |
| 4803 EXPECT_EQ(0u, map1->size()); | 4813 EXPECT_EQ(0u, map1->size()); |
| 4804 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 4814 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
| 4805 | 4815 |
| 4806 OffHeapInt::s_destructorCalls = 0; | 4816 OffHeapInt::s_destructorCalls = 0; |
| 4807 | 4817 |
| 4808 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapI
nt::create(2000)); | 4818 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapI
nt::create(2000)); |
| 4809 map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapI
nt::create(2001)); // This one gets zapped at GC time because nothing holds the
103 alive. | 4819 map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapI
nt::create(2001)); // This one gets zapped at GC time because nothing holds the
103 alive. |
| 4810 map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03)), OffHeapInt::create(2002)); // This one gets zapped too. | 4820 map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03)), OffHeapInt::create(2002)); // This one gets zapped too. |
| 4811 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 4821 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
| 4812 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); | 4822 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); |
| 4813 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one
is identical to the previous and doesn't add anything. | 4823 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one
is identical to the previous and doesn't add anything. |
| 4814 dupeInt.clear(); | 4824 dupeInt.clear(); |
| 4815 | 4825 |
| 4816 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4826 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
| 4817 EXPECT_EQ(4u, map1->size()); | 4827 EXPECT_EQ(4u, map1->size()); |
| 4818 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4828 preciselyCollectGarbage(); |
| 4819 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 4829 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
| 4820 EXPECT_EQ(2u, map1->size()); | 4830 EXPECT_EQ(2u, map1->size()); |
| 4821 Iterator i1 = map1->begin(); | 4831 Iterator i1 = map1->begin(); |
| 4822 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); | 4832 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); |
| 4823 EXPECT_EQ(livingInt, i1->key.second); | 4833 EXPECT_EQ(livingInt, i1->key.second); |
| 4824 ++i1; | 4834 ++i1; |
| 4825 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); | 4835 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); |
| 4826 EXPECT_EQ(livingInt, i1->key.second); | 4836 EXPECT_EQ(livingInt, i1->key.second); |
| 4827 } | 4837 } |
| 4828 | 4838 |
| 4829 TEST(HeapTest, MapWithCustomWeaknessHandling2) | 4839 TEST(HeapTest, MapWithCustomWeaknessHandling2) |
| 4830 { | 4840 { |
| 4831 typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map; | 4841 typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map; |
| 4832 typedef Map::iterator Iterator; | 4842 typedef Map::iterator Iterator; |
| 4833 clearOutOldGarbage(); | 4843 clearOutOldGarbage(); |
| 4834 OffHeapInt::s_destructorCalls = 0; | 4844 OffHeapInt::s_destructorCalls = 0; |
| 4835 | 4845 |
| 4836 Persistent<Map> map1(new Map()); | 4846 Persistent<Map> map1(new Map()); |
| 4837 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4847 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
| 4838 | 4848 |
| 4839 { | 4849 { |
| 4840 Map map2; | 4850 Map map2; |
| 4841 Map* map3 = new Map(); | 4851 Map* map3 = new Map(); |
| 4842 map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::crea
te(0), IntWrapper::create(1))); | 4852 map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::crea
te(0), IntWrapper::create(1))); |
| 4843 map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::cre
ate(2), IntWrapper::create(3))); | 4853 map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::cre
ate(2), IntWrapper::create(3))); |
| 4844 map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::cre
ate(4), IntWrapper::create(5))); | 4854 map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::cre
ate(4), IntWrapper::create(5))); |
| 4845 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4855 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
| 4846 | 4856 |
| 4847 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 4857 conservativelyCollectGarbage(); |
| 4848 // The first map2 is pointed to from a persistent, so it's referenced, b
ut | 4858 // The first map2 is pointed to from a persistent, so it's referenced, b
ut |
| 4849 // the weak processing may have taken place. | 4859 // the weak processing may have taken place. |
| 4850 if (map1->size()) { | 4860 if (map1->size()) { |
| 4851 Iterator i1 = map1->begin(); | 4861 Iterator i1 = map1->begin(); |
| 4852 EXPECT_EQ(4, i1->value.first->value()); | 4862 EXPECT_EQ(4, i1->value.first->value()); |
| 4853 EXPECT_EQ(5, i1->value.second->value()); | 4863 EXPECT_EQ(5, i1->value.second->value()); |
| 4854 EXPECT_EQ(1003, i1->key->value()); | 4864 EXPECT_EQ(1003, i1->key->value()); |
| 4855 } | 4865 } |
| 4856 // The second map2 is on-stack, so its backing store must be referenced
from | 4866 // The second map2 is on-stack, so its backing store must be referenced
from |
| 4857 // the stack. That makes the weak references strong. | 4867 // the stack. That makes the weak references strong. |
| 4858 Iterator i2 = map2.begin(); | 4868 Iterator i2 = map2.begin(); |
| 4859 EXPECT_EQ(0, i2->value.first->value()); | 4869 EXPECT_EQ(0, i2->value.first->value()); |
| 4860 EXPECT_EQ(1, i2->value.second->value()); | 4870 EXPECT_EQ(1, i2->value.second->value()); |
| 4861 EXPECT_EQ(1001, i2->key->value()); | 4871 EXPECT_EQ(1001, i2->key->value()); |
| 4862 // The third map2 is pointed to from the stack, so it's referenced, but
the | 4872 // The third map2 is pointed to from the stack, so it's referenced, but
the |
| 4863 // weak processing may have taken place. | 4873 // weak processing may have taken place. |
| 4864 if (map3->size()) { | 4874 if (map3->size()) { |
| 4865 Iterator i3 = map3->begin(); | 4875 Iterator i3 = map3->begin(); |
| 4866 EXPECT_EQ(2, i3->value.first->value()); | 4876 EXPECT_EQ(2, i3->value.first->value()); |
| 4867 EXPECT_EQ(3, i3->value.second->value()); | 4877 EXPECT_EQ(3, i3->value.second->value()); |
| 4868 EXPECT_EQ(1002, i3->key->value()); | 4878 EXPECT_EQ(1002, i3->key->value()); |
| 4869 } | 4879 } |
| 4870 } | 4880 } |
| 4871 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4881 preciselyCollectGarbage(); |
| 4872 | 4882 |
| 4873 EXPECT_EQ(0u, map1->size()); | 4883 EXPECT_EQ(0u, map1->size()); |
| 4874 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 4884 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
| 4875 | 4885 |
| 4876 OffHeapInt::s_destructorCalls = 0; | 4886 OffHeapInt::s_destructorCalls = 0; |
| 4877 | 4887 |
| 4878 map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(
103), livingInt)); | 4888 map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(
103), livingInt)); |
| 4879 map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapp
er::create(103))); // This one gets zapped at GC time because nothing holds the
103 alive. | 4889 map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapp
er::create(103))); // This one gets zapped at GC time because nothing holds the
103 alive. |
| 4880 map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(
103), IntWrapper::create(103))); // This one gets zapped too. | 4890 map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(
103), IntWrapper::create(103))); // This one gets zapped too. |
| 4881 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 4891 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
| 4882 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); | 4892 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); |
| 4883 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one
is identical to the previous and doesn't add anything. | 4893 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one
is identical to the previous and doesn't add anything. |
| 4884 dupeInt.clear(); | 4894 dupeInt.clear(); |
| 4885 | 4895 |
| 4886 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4896 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
| 4887 EXPECT_EQ(4u, map1->size()); | 4897 EXPECT_EQ(4u, map1->size()); |
| 4888 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4898 preciselyCollectGarbage(); |
| 4889 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 4899 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
| 4890 EXPECT_EQ(2u, map1->size()); | 4900 EXPECT_EQ(2u, map1->size()); |
| 4891 Iterator i1 = map1->begin(); | 4901 Iterator i1 = map1->begin(); |
| 4892 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; | 4902 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; |
| 4893 EXPECT_EQ(livingInt, i1->value.second); | 4903 EXPECT_EQ(livingInt, i1->value.second); |
| 4894 ++i1; | 4904 ++i1; |
| 4895 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; | 4905 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; |
| 4896 EXPECT_EQ(livingInt, i1->value.second); | 4906 EXPECT_EQ(livingInt, i1->value.second); |
| 4897 } | 4907 } |
| 4898 | 4908 |
| 4899 static void addElementsToWeakMap(HeapHashMap<int, WeakMember<IntWrapper>>* map) | 4909 static void addElementsToWeakMap(HeapHashMap<int, WeakMember<IntWrapper>>* map) |
| 4900 { | 4910 { |
| 4901 // Key cannot be zero in hashmap. | 4911 // Key cannot be zero in hashmap. |
| 4902 for (int i = 1; i < 11; i++) | 4912 for (int i = 1; i < 11; i++) |
| 4903 map->add(i, IntWrapper::create(i)); | 4913 map->add(i, IntWrapper::create(i)); |
| 4904 } | 4914 } |
| 4905 | 4915 |
| 4906 // crbug.com/402426 | 4916 // crbug.com/402426 |
| 4907 // If it doesn't assert a concurrent modification to the map, then it's passing. | 4917 // If it doesn't assert a concurrent modification to the map, then it's passing. |
| 4908 TEST(HeapTest, RegressNullIsStrongified) | 4918 TEST(HeapTest, RegressNullIsStrongified) |
| 4909 { | 4919 { |
| 4910 Persistent<HeapHashMap<int, WeakMember<IntWrapper>>> map = new HeapHashMap<i
nt, WeakMember<IntWrapper>>(); | 4920 Persistent<HeapHashMap<int, WeakMember<IntWrapper>>> map = new HeapHashMap<i
nt, WeakMember<IntWrapper>>(); |
| 4911 addElementsToWeakMap(map); | 4921 addElementsToWeakMap(map); |
| 4912 HeapHashMap<int, WeakMember<IntWrapper>>::AddResult result = map->add(800, n
ullptr); | 4922 HeapHashMap<int, WeakMember<IntWrapper>>::AddResult result = map->add(800, n
ullptr); |
| 4913 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); | 4923 conservativelyCollectGarbage(); |
| 4914 result.storedValue->value = IntWrapper::create(42); | 4924 result.storedValue->value = IntWrapper::create(42); |
| 4915 } | 4925 } |
| 4916 | 4926 |
| 4917 TEST(HeapTest, Bind) | 4927 TEST(HeapTest, Bind) |
| 4918 { | 4928 { |
| 4919 OwnPtr<Closure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::tr
ace), Bar::create(), static_cast<Visitor*>(0)); | 4929 OwnPtr<Closure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::tr
ace), Bar::create(), static_cast<Visitor*>(0)); |
| 4920 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4930 preciselyCollectGarbage(); |
| 4921 // The closure should have a persistent handle to the Bar. | 4931 // The closure should have a persistent handle to the Bar. |
| 4922 EXPECT_EQ(1u, Bar::s_live); | 4932 EXPECT_EQ(1u, Bar::s_live); |
| 4923 | 4933 |
| 4924 OwnPtr<Closure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::t
race), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0)); | 4934 OwnPtr<Closure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::t
race), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0)); |
| 4925 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4935 preciselyCollectGarbage(); |
| 4926 // The closure should have a persistent handle to the Bar. | 4936 // The closure should have a persistent handle to the Bar. |
| 4927 EXPECT_EQ(2u, Bar::s_live); | 4937 EXPECT_EQ(2u, Bar::s_live); |
| 4928 // RawPtr<OffHeapInt> should not make Persistent. | 4938 // RawPtr<OffHeapInt> should not make Persistent. |
| 4929 OwnPtr<Closure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt
>(OffHeapInt::create(1).get())); | 4939 OwnPtr<Closure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt
>(OffHeapInt::create(1).get())); |
| 4930 | 4940 |
| 4931 UseMixin::s_traceCount = 0; | 4941 UseMixin::s_traceCount = 0; |
| 4932 Mixin* mixin = UseMixin::create(); | 4942 Mixin* mixin = UseMixin::create(); |
| 4933 OwnPtr<Closure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&
Mixin::trace), mixin, static_cast<Visitor*>(0)); | 4943 OwnPtr<Closure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&
Mixin::trace), mixin, static_cast<Visitor*>(0)); |
| 4934 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 4944 preciselyCollectGarbage(); |
| 4935 // The closure should have a persistent handle to the mixin. | 4945 // The closure should have a persistent handle to the mixin. |
| 4936 EXPECT_EQ(1, UseMixin::s_traceCount); | 4946 EXPECT_EQ(1, UseMixin::s_traceCount); |
| 4937 } | 4947 } |
| 4938 | 4948 |
| 4939 typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet; | 4949 typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet; |
| 4940 | 4950 |
| 4941 // These special traits will remove a set from a map when the set is empty. | 4951 // These special traits will remove a set from a map when the set is empty. |
| 4942 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { | 4952 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { |
| 4943 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 4953 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 4944 template<typename VisitorDispatcher> | 4954 template<typename VisitorDispatcher> |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4989 set.add(IntWrapper::create(103)); // Weak set can't hold this long. | 4999 set.add(IntWrapper::create(103)); // Weak set can't hold this long. |
| 4990 set.add(livingInt); // This prevents the set from being emptied. | 5000 set.add(livingInt); // This prevents the set from being emptied. |
| 4991 EXPECT_EQ(2u, set.size()); | 5001 EXPECT_EQ(2u, set.size()); |
| 4992 } | 5002 } |
| 4993 | 5003 |
| 4994 // The set we add here is empty, so the entry will be removed from the map | 5004 // The set we add here is empty, so the entry will be removed from the map |
| 4995 // at the next GC. | 5005 // at the next GC. |
| 4996 map->add(OffHeapInt::create(2), WeakSet()); | 5006 map->add(OffHeapInt::create(2), WeakSet()); |
| 4997 EXPECT_EQ(2u, map->size()); | 5007 EXPECT_EQ(2u, map->size()); |
| 4998 | 5008 |
| 4999 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5009 preciselyCollectGarbage(); |
| 5000 EXPECT_EQ(1u, map->size()); // The one with key 2 was removed. | 5010 EXPECT_EQ(1u, map->size()); // The one with key 2 was removed. |
| 5001 EXPECT_EQ(1, OffHeapInt::s_destructorCalls); | 5011 EXPECT_EQ(1, OffHeapInt::s_destructorCalls); |
| 5002 { | 5012 { |
| 5003 WeakSet& set = map->begin()->value; | 5013 WeakSet& set = map->begin()->value; |
| 5004 EXPECT_EQ(1u, set.size()); | 5014 EXPECT_EQ(1u, set.size()); |
| 5005 } | 5015 } |
| 5006 | 5016 |
| 5007 livingInt.clear(); // The weak set can no longer keep the '42' alive now. | 5017 livingInt.clear(); // The weak set can no longer keep the '42' alive now. |
| 5008 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5018 preciselyCollectGarbage(); |
| 5009 EXPECT_EQ(0u, map->size()); | 5019 EXPECT_EQ(0u, map->size()); |
| 5010 } | 5020 } |
| 5011 | 5021 |
| 5012 TEST(HeapTest, EphemeronsInEphemerons) | 5022 TEST(HeapTest, EphemeronsInEphemerons) |
| 5013 { | 5023 { |
| 5014 typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap; | 5024 typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap; |
| 5015 typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap; | 5025 typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap; |
| 5016 | 5026 |
| 5017 for (int keepOuterAlive = 0; keepOuterAlive <= 1; keepOuterAlive++) { | 5027 for (int keepOuterAlive = 0; keepOuterAlive <= 1; keepOuterAlive++) { |
| 5018 for (int keepInnerAlive = 0; keepInnerAlive <=1; keepInnerAlive++) { | 5028 for (int keepInnerAlive = 0; keepInnerAlive <=1; keepInnerAlive++) { |
| 5019 Persistent<OuterMap> outer = new OuterMap(); | 5029 Persistent<OuterMap> outer = new OuterMap(); |
| 5020 Persistent<IntWrapper> one = IntWrapper::create(1); | 5030 Persistent<IntWrapper> one = IntWrapper::create(1); |
| 5021 Persistent<IntWrapper> two = IntWrapper::create(2); | 5031 Persistent<IntWrapper> two = IntWrapper::create(2); |
| 5022 outer->add(one, InnerMap()); | 5032 outer->add(one, InnerMap()); |
| 5023 outer->begin()->value.add(two, IntWrapper::create(3)); | 5033 outer->begin()->value.add(two, IntWrapper::create(3)); |
| 5024 EXPECT_EQ(1u, outer->get(one).size()); | 5034 EXPECT_EQ(1u, outer->get(one).size()); |
| 5025 if (!keepOuterAlive) | 5035 if (!keepOuterAlive) |
| 5026 one.clear(); | 5036 one.clear(); |
| 5027 if (!keepInnerAlive) | 5037 if (!keepInnerAlive) |
| 5028 two.clear(); | 5038 two.clear(); |
| 5029 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 5039 preciselyCollectGarbage(); |
| 5030 if (keepOuterAlive) { | 5040 if (keepOuterAlive) { |
| 5031 const InnerMap& inner = outer->get(one); | 5041 const InnerMap& inner = outer->get(one); |
| 5032 if (keepInnerAlive) { | 5042 if (keepInnerAlive) { |
| 5033 EXPECT_EQ(1u, inner.size()); | 5043 EXPECT_EQ(1u, inner.size()); |
| 5034 IntWrapper* three = inner.get(two); | 5044 IntWrapper* three = inner.get(two); |
| 5035 EXPECT_EQ(3, three->value()); | 5045 EXPECT_EQ(3, three->value()); |
| 5036 } else { | 5046 } else { |
| 5037 EXPECT_EQ(0u, inner.size()); | 5047 EXPECT_EQ(0u, inner.size()); |
| 5038 } | 5048 } |
| 5039 } else { | 5049 } else { |
| 5040 EXPECT_EQ(0u, outer->size()); | 5050 EXPECT_EQ(0u, outer->size()); |
| 5041 } | 5051 } |
| 5042 outer->clear(); | 5052 outer->clear(); |
| 5043 Persistent<IntWrapper> deep = IntWrapper::create(42); | 5053 Persistent<IntWrapper> deep = IntWrapper::create(42); |
| 5044 Persistent<IntWrapper> home = IntWrapper::create(103); | 5054 Persistent<IntWrapper> home = IntWrapper::create(103); |
| 5045 Persistent<IntWrapper> composite = IntWrapper::create(91); | 5055 Persistent<IntWrapper> composite = IntWrapper::create(91); |
| 5046 Persistent<HeapVector<Member<IntWrapper>>> keepAlive = new HeapVecto
r<Member<IntWrapper>>(); | 5056 Persistent<HeapVector<Member<IntWrapper>>> keepAlive = new HeapVecto
r<Member<IntWrapper>>(); |
| 5047 for (int i = 0; i < 10000; i++) { | 5057 for (int i = 0; i < 10000; i++) { |
| 5048 IntWrapper* value = IntWrapper::create(i); | 5058 IntWrapper* value = IntWrapper::create(i); |
| 5049 keepAlive->append(value); | 5059 keepAlive->append(value); |
| 5050 OuterMap::AddResult newEntry = outer->add(value, InnerMap()); | 5060 OuterMap::AddResult newEntry = outer->add(value, InnerMap()); |
| 5051 newEntry.storedValue->value.add(deep, home); | 5061 newEntry.storedValue->value.add(deep, home); |
| 5052 newEntry.storedValue->value.add(composite, home); | 5062 newEntry.storedValue->value.add(composite, home); |
| 5053 } | 5063 } |
| 5054 composite.clear(); | 5064 composite.clear(); |
| 5055 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 5065 preciselyCollectGarbage(); |
| 5056 EXPECT_EQ(10000u, outer->size()); | 5066 EXPECT_EQ(10000u, outer->size()); |
| 5057 for (int i = 0; i < 10000; i++) { | 5067 for (int i = 0; i < 10000; i++) { |
| 5058 IntWrapper* value = keepAlive->at(i); | 5068 IntWrapper* value = keepAlive->at(i); |
| 5059 EXPECT_EQ(1u, outer->get(value).size()); // Other one was delete
d by weak handling. | 5069 EXPECT_EQ(1u, outer->get(value).size()); // Other one was delete
d by weak handling. |
| 5060 if (i & 1) | 5070 if (i & 1) |
| 5061 keepAlive->at(i) = nullptr; | 5071 keepAlive->at(i) = nullptr; |
| 5062 } | 5072 } |
| 5063 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 5073 preciselyCollectGarbage(); |
| 5064 EXPECT_EQ(5000u, outer->size()); | 5074 EXPECT_EQ(5000u, outer->size()); |
| 5065 } | 5075 } |
| 5066 } | 5076 } |
| 5067 } | 5077 } |
| 5068 | 5078 |
| 5069 class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> { | 5079 class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> { |
| 5070 public: | 5080 public: |
| 5071 DEFINE_INLINE_TRACE() | 5081 DEFINE_INLINE_TRACE() |
| 5072 { | 5082 { |
| 5073 visitor->trace(m_map); | 5083 visitor->trace(m_map); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5089 for (int i = 0; i < 100; i++) { | 5099 for (int i = 0; i < 100; i++) { |
| 5090 EphemeronWrapper* oldHead = chain; | 5100 EphemeronWrapper* oldHead = chain; |
| 5091 chain = new EphemeronWrapper(); | 5101 chain = new EphemeronWrapper(); |
| 5092 if (i == 50) | 5102 if (i == 50) |
| 5093 chain->map().add(key2, oldHead); | 5103 chain->map().add(key2, oldHead); |
| 5094 else | 5104 else |
| 5095 chain->map().add(key, oldHead); | 5105 chain->map().add(key, oldHead); |
| 5096 chain->map().add(IntWrapper::create(103), new EphemeronWrapper()); | 5106 chain->map().add(IntWrapper::create(103), new EphemeronWrapper()); |
| 5097 } | 5107 } |
| 5098 | 5108 |
| 5099 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5109 preciselyCollectGarbage(); |
| 5100 | 5110 |
| 5101 EphemeronWrapper* wrapper = chain; | 5111 EphemeronWrapper* wrapper = chain; |
| 5102 for (int i = 0; i< 100; i++) { | 5112 for (int i = 0; i< 100; i++) { |
| 5103 EXPECT_EQ(1u, wrapper->map().size()); | 5113 EXPECT_EQ(1u, wrapper->map().size()); |
| 5104 if (i == 49) | 5114 if (i == 49) |
| 5105 wrapper = wrapper->map().get(key2); | 5115 wrapper = wrapper->map().get(key2); |
| 5106 else | 5116 else |
| 5107 wrapper = wrapper->map().get(key); | 5117 wrapper = wrapper->map().get(key); |
| 5108 } | 5118 } |
| 5109 EXPECT_EQ(nullptr, wrapper); | 5119 EXPECT_EQ(nullptr, wrapper); |
| 5110 | 5120 |
| 5111 key2.clear(); | 5121 key2.clear(); |
| 5112 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5122 preciselyCollectGarbage(); |
| 5113 | 5123 |
| 5114 wrapper = chain; | 5124 wrapper = chain; |
| 5115 for (int i = 0; i < 50; i++) { | 5125 for (int i = 0; i < 50; i++) { |
| 5116 EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size()); | 5126 EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size()); |
| 5117 wrapper = wrapper->map().get(key); | 5127 wrapper = wrapper->map().get(key); |
| 5118 } | 5128 } |
| 5119 EXPECT_EQ(nullptr, wrapper); | 5129 EXPECT_EQ(nullptr, wrapper); |
| 5120 | 5130 |
| 5121 key.clear(); | 5131 key.clear(); |
| 5122 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5132 preciselyCollectGarbage(); |
| 5123 EXPECT_EQ(0u, chain->map().size()); | 5133 EXPECT_EQ(0u, chain->map().size()); |
| 5124 } | 5134 } |
| 5125 | 5135 |
| 5126 TEST(HeapTest, Ephemeron) | 5136 TEST(HeapTest, Ephemeron) |
| 5127 { | 5137 { |
| 5128 typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling> WeakPairM
ap; | 5138 typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling> WeakPairM
ap; |
| 5129 typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper>> PairWeakM
ap; | 5139 typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper>> PairWeakM
ap; |
| 5130 typedef HeapHashSet<WeakMember<IntWrapper>> Set; | 5140 typedef HeapHashSet<WeakMember<IntWrapper>> Set; |
| 5131 | 5141 |
| 5132 Persistent<WeakPairMap> weakPairMap = new WeakPairMap(); | 5142 Persistent<WeakPairMap> weakPairMap = new WeakPairMap(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5161 pairWeakMap2->add(PairWithWeakHandling(pw1, pw2), pw2); | 5171 pairWeakMap2->add(PairWithWeakHandling(pw1, pw2), pw2); |
| 5162 pairWeakMap2->add(PairWithWeakHandling(pw2, pw1), pw2); | 5172 pairWeakMap2->add(PairWithWeakHandling(pw2, pw1), pw2); |
| 5163 pairWeakMap2->add(PairWithWeakHandling(pw2, pw2), pw2); | 5173 pairWeakMap2->add(PairWithWeakHandling(pw2, pw2), pw2); |
| 5164 | 5174 |
| 5165 | 5175 |
| 5166 set->add(wp1); | 5176 set->add(wp1); |
| 5167 set->add(wp2); | 5177 set->add(wp2); |
| 5168 set->add(pw1); | 5178 set->add(pw1); |
| 5169 set->add(pw2); | 5179 set->add(pw2); |
| 5170 | 5180 |
| 5171 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5181 preciselyCollectGarbage(); |
| 5172 | 5182 |
| 5173 EXPECT_EQ(2u, weakPairMap->size()); | 5183 EXPECT_EQ(2u, weakPairMap->size()); |
| 5174 EXPECT_EQ(2u, weakPairMap2->size()); | 5184 EXPECT_EQ(2u, weakPairMap2->size()); |
| 5175 EXPECT_EQ(1u, weakPairMap3->size()); | 5185 EXPECT_EQ(1u, weakPairMap3->size()); |
| 5176 EXPECT_EQ(2u, weakPairMap4->size()); | 5186 EXPECT_EQ(2u, weakPairMap4->size()); |
| 5177 | 5187 |
| 5178 EXPECT_EQ(3u, pairWeakMap->size()); | 5188 EXPECT_EQ(3u, pairWeakMap->size()); |
| 5179 EXPECT_EQ(4u, pairWeakMap2->size()); | 5189 EXPECT_EQ(4u, pairWeakMap2->size()); |
| 5180 | 5190 |
| 5181 EXPECT_EQ(4u, set->size()); | 5191 EXPECT_EQ(4u, set->size()); |
| 5182 | 5192 |
| 5183 wp2.clear(); // Kills all entries in the weakPairMaps except the first. | 5193 wp2.clear(); // Kills all entries in the weakPairMaps except the first. |
| 5184 pw2.clear(); // Kills all entries in the pairWeakMaps except the first. | 5194 pw2.clear(); // Kills all entries in the pairWeakMaps except the first. |
| 5185 | 5195 |
| 5186 for (int i = 0; i < 2; i++) { | 5196 for (int i = 0; i < 2; i++) { |
| 5187 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 5197 preciselyCollectGarbage(); |
| 5188 | 5198 |
| 5189 EXPECT_EQ(1u, weakPairMap->size()); | 5199 EXPECT_EQ(1u, weakPairMap->size()); |
| 5190 EXPECT_EQ(0u, weakPairMap2->size()); | 5200 EXPECT_EQ(0u, weakPairMap2->size()); |
| 5191 EXPECT_EQ(0u, weakPairMap3->size()); | 5201 EXPECT_EQ(0u, weakPairMap3->size()); |
| 5192 EXPECT_EQ(0u, weakPairMap4->size()); | 5202 EXPECT_EQ(0u, weakPairMap4->size()); |
| 5193 | 5203 |
| 5194 EXPECT_EQ(1u, pairWeakMap->size()); | 5204 EXPECT_EQ(1u, pairWeakMap->size()); |
| 5195 EXPECT_EQ(0u, pairWeakMap2->size()); | 5205 EXPECT_EQ(0u, pairWeakMap2->size()); |
| 5196 | 5206 |
| 5197 EXPECT_EQ(2u, set->size()); // wp1 and pw1. | 5207 EXPECT_EQ(2u, set->size()); // wp1 and pw1. |
| 5198 } | 5208 } |
| 5199 | 5209 |
| 5200 wp1.clear(); | 5210 wp1.clear(); |
| 5201 pw1.clear(); | 5211 pw1.clear(); |
| 5202 | 5212 |
| 5203 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5213 preciselyCollectGarbage(); |
| 5204 | 5214 |
| 5205 EXPECT_EQ(0u, weakPairMap->size()); | 5215 EXPECT_EQ(0u, weakPairMap->size()); |
| 5206 EXPECT_EQ(0u, pairWeakMap->size()); | 5216 EXPECT_EQ(0u, pairWeakMap->size()); |
| 5207 EXPECT_EQ(0u, set->size()); | 5217 EXPECT_EQ(0u, set->size()); |
| 5208 } | 5218 } |
| 5209 | 5219 |
| 5210 class Link1 : public GarbageCollected<Link1> { | 5220 class Link1 : public GarbageCollected<Link1> { |
| 5211 public: | 5221 public: |
| 5212 Link1(IntWrapper* link) : m_link(link) { } | 5222 Link1(IntWrapper* link) : m_link(link) { } |
| 5213 | 5223 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5224 | 5234 |
| 5225 TEST(HeapTest, IndirectStrongToWeak) | 5235 TEST(HeapTest, IndirectStrongToWeak) |
| 5226 { | 5236 { |
| 5227 typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1>> Map; | 5237 typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1>> Map; |
| 5228 Persistent<Map> map = new Map(); | 5238 Persistent<Map> map = new Map(); |
| 5229 Persistent<IntWrapper> deadObject = IntWrapper::create(100); // Named for "D
rowning by Numbers" (1988). | 5239 Persistent<IntWrapper> deadObject = IntWrapper::create(100); // Named for "D
rowning by Numbers" (1988). |
| 5230 Persistent<IntWrapper> lifeObject = IntWrapper::create(42); | 5240 Persistent<IntWrapper> lifeObject = IntWrapper::create(42); |
| 5231 map->add(deadObject, new Link1(deadObject)); | 5241 map->add(deadObject, new Link1(deadObject)); |
| 5232 map->add(lifeObject, new Link1(lifeObject)); | 5242 map->add(lifeObject, new Link1(lifeObject)); |
| 5233 EXPECT_EQ(2u, map->size()); | 5243 EXPECT_EQ(2u, map->size()); |
| 5234 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5244 preciselyCollectGarbage(); |
| 5235 EXPECT_EQ(2u, map->size()); | 5245 EXPECT_EQ(2u, map->size()); |
| 5236 EXPECT_EQ(deadObject, map->get(deadObject)->link()); | 5246 EXPECT_EQ(deadObject, map->get(deadObject)->link()); |
| 5237 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); | 5247 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); |
| 5238 deadObject.clear(); // Now it can live up to its name. | 5248 deadObject.clear(); // Now it can live up to its name. |
| 5239 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5249 preciselyCollectGarbage(); |
| 5240 EXPECT_EQ(1u, map->size()); | 5250 EXPECT_EQ(1u, map->size()); |
| 5241 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); | 5251 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); |
| 5242 lifeObject.clear(); // Despite its name. | 5252 lifeObject.clear(); // Despite its name. |
| 5243 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5253 preciselyCollectGarbage(); |
| 5244 EXPECT_EQ(0u, map->size()); | 5254 EXPECT_EQ(0u, map->size()); |
| 5245 } | 5255 } |
| 5246 | 5256 |
| 5247 static Mutex& mainThreadMutex() | 5257 static Mutex& mainThreadMutex() |
| 5248 { | 5258 { |
| 5249 AtomicallyInitializedStaticReference(Mutex, mainMutex, new Mutex); | 5259 AtomicallyInitializedStaticReference(Mutex, mainMutex, new Mutex); |
| 5250 return mainMutex; | 5260 return mainMutex; |
| 5251 } | 5261 } |
| 5252 | 5262 |
| 5253 static ThreadCondition& mainThreadCondition() | 5263 static ThreadCondition& mainThreadCondition() |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5303 // Wait for the worker thread to have done its initialization, | 5313 // Wait for the worker thread to have done its initialization, |
| 5304 // IE. the worker allocates an object and then throw aways any | 5314 // IE. the worker allocates an object and then throw aways any |
| 5305 // pointers to it. | 5315 // pointers to it. |
| 5306 parkMainThread(); | 5316 parkMainThread(); |
| 5307 | 5317 |
| 5308 // Now do a GC. This will not find the worker threads object since it | 5318 // Now do a GC. This will not find the worker threads object since it |
| 5309 // is not referred from any of the threads. Even a conservative | 5319 // is not referred from any of the threads. Even a conservative |
| 5310 // GC will not find it. | 5320 // GC will not find it. |
| 5311 // Also at this point the worker is waiting for the main thread | 5321 // Also at this point the worker is waiting for the main thread |
| 5312 // to be parked and will not do any sweep of its heap. | 5322 // to be parked and will not do any sweep of its heap. |
| 5313 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 5323 preciselyCollectGarbage(); |
| 5314 | 5324 |
| 5315 // Since the worker thread is not sweeping the worker object should | 5325 // Since the worker thread is not sweeping the worker object should |
| 5316 // not have been finalized. | 5326 // not have been finalized. |
| 5317 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 5327 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 5318 | 5328 |
| 5319 // Put the worker thread's object address on the stack and do a | 5329 // Put the worker thread's object address on the stack and do a |
| 5320 // conservative GC. This should find the worker object, but since | 5330 // conservative GC. This should find the worker object, but since |
| 5321 // it was dead in the previous GC it should not be traced in this | 5331 // it was dead in the previous GC it should not be traced in this |
| 5322 // GC. | 5332 // GC. |
| 5323 uintptr_t stackPtrValue = s_workerObjectPointer; | 5333 uintptr_t stackPtrValue = s_workerObjectPointer; |
| 5324 s_workerObjectPointer = 0; | 5334 s_workerObjectPointer = 0; |
| 5325 ASSERT_UNUSED(stackPtrValue, stackPtrValue); | 5335 ASSERT_UNUSED(stackPtrValue, stackPtrValue); |
| 5326 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 5336 conservativelyCollectGarbage(); |
| 5327 | 5337 |
| 5328 // Since the worker thread is not sweeping the worker object should | 5338 // Since the worker thread is not sweeping the worker object should |
| 5329 // not have been finalized. | 5339 // not have been finalized. |
| 5330 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 5340 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 5331 | 5341 |
| 5332 // Wake up the worker thread so it can continue with its sweeping. | 5342 // Wake up the worker thread so it can continue with its sweeping. |
| 5333 // This should finalized the worker object which we test below. | 5343 // This should finalized the worker object which we test below. |
| 5334 // The worker thread will go back to sleep once sweeping to ensure | 5344 // The worker thread will go back to sleep once sweeping to ensure |
| 5335 // we don't have thread local GCs until after validating the destructor | 5345 // we don't have thread local GCs until after validating the destructor |
| 5336 // was called. | 5346 // was called. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5406 // Wait for the worker thread initialization. The worker | 5416 // Wait for the worker thread initialization. The worker |
| 5407 // allocates a weak collection where both collection and | 5417 // allocates a weak collection where both collection and |
| 5408 // contents are kept alive via persistent pointers. | 5418 // contents are kept alive via persistent pointers. |
| 5409 parkMainThread(); | 5419 parkMainThread(); |
| 5410 | 5420 |
| 5411 // Perform two garbage collections where the worker thread does | 5421 // Perform two garbage collections where the worker thread does |
| 5412 // not wake up in between. This will cause us to remove marks | 5422 // not wake up in between. This will cause us to remove marks |
| 5413 // and mark unmarked objects dead. The collection on the worker | 5423 // and mark unmarked objects dead. The collection on the worker |
| 5414 // heap is found through the persistent and the backing should | 5424 // heap is found through the persistent and the backing should |
| 5415 // be marked. | 5425 // be marked. |
| 5416 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 5426 preciselyCollectGarbage(); |
| 5417 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); | 5427 preciselyCollectGarbage(); |
| 5418 | 5428 |
| 5419 // Wake up the worker thread so it can continue. It will sweep | 5429 // Wake up the worker thread so it can continue. It will sweep |
| 5420 // and perform another GC where the backing store of its | 5430 // and perform another GC where the backing store of its |
| 5421 // collection should be strongified. | 5431 // collection should be strongified. |
| 5422 wakeWorkerThread(); | 5432 wakeWorkerThread(); |
| 5423 | 5433 |
| 5424 // Wait for the worker thread to sweep its heaps before checking. | 5434 // Wait for the worker thread to sweep its heaps before checking. |
| 5425 { | 5435 { |
| 5426 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 5436 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
| 5427 parkMainThread(); | 5437 parkMainThread(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5472 { | 5482 { |
| 5473 MutexLocker locker(workerThreadMutex()); | 5483 MutexLocker locker(workerThreadMutex()); |
| 5474 | 5484 |
| 5475 ThreadState::attach(); | 5485 ThreadState::attach(); |
| 5476 | 5486 |
| 5477 { | 5487 { |
| 5478 Persistent<WeakCollectionType> collection = allocateCollection(); | 5488 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5479 { | 5489 { |
| 5480 // Prevent weak processing with an iterator and GC. | 5490 // Prevent weak processing with an iterator and GC. |
| 5481 WeakCollectionType::iterator it = collection->begin(); | 5491 WeakCollectionType::iterator it = collection->begin(); |
| 5482 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGC); | 5492 conservativelyCollectGarbage(); |
| 5483 | 5493 |
| 5484 // The backing should be strongified because of the iterator. | 5494 // The backing should be strongified because of the iterator. |
| 5485 EXPECT_EQ(6u, collection->size()); | 5495 EXPECT_EQ(6u, collection->size()); |
| 5486 EXPECT_EQ(32, it->value->value()); | 5496 EXPECT_EQ(32, it->value->value()); |
| 5487 } | 5497 } |
| 5488 | 5498 |
| 5489 // Disregarding the iterator but keeping the collection alive | 5499 // Disregarding the iterator but keeping the collection alive |
| 5490 // with a persistent should lead to weak processing. | 5500 // with a persistent should lead to weak processing. |
| 5491 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 5501 preciselyCollectGarbage(); |
| 5492 EXPECT_EQ(0u, collection->size()); | 5502 EXPECT_EQ(0u, collection->size()); |
| 5493 } | 5503 } |
| 5494 | 5504 |
| 5495 wakeMainThread(); | 5505 wakeMainThread(); |
| 5496 ThreadState::detach(); | 5506 ThreadState::detach(); |
| 5497 } | 5507 } |
| 5498 | 5508 |
| 5499 static volatile uintptr_t s_workerObjectPointer; | 5509 static volatile uintptr_t s_workerObjectPointer; |
| 5500 }; | 5510 }; |
| 5501 | 5511 |
| 5502 TEST(HeapTest, ThreadedStrongification) | 5512 TEST(HeapTest, ThreadedStrongification) |
| 5503 { | 5513 { |
| 5504 ThreadedStrongificationTester::test(); | 5514 ThreadedStrongificationTester::test(); |
| 5505 } | 5515 } |
| 5506 | 5516 |
| 5507 static bool allocateAndReturnBool() | 5517 static bool allocateAndReturnBool() |
| 5508 { | 5518 { |
| 5509 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); | 5519 conservativelyCollectGarbage(); |
| 5510 return true; | 5520 return true; |
| 5511 } | 5521 } |
| 5512 | 5522 |
| 5513 static bool checkGCForbidden() | 5523 static bool checkGCForbidden() |
| 5514 { | 5524 { |
| 5515 ASSERT(ThreadState::current()->isGCForbidden()); | 5525 ASSERT(ThreadState::current()->isGCForbidden()); |
| 5516 return true; | 5526 return true; |
| 5517 } | 5527 } |
| 5518 | 5528 |
| 5519 class MixinClass : public GarbageCollectedMixin { | 5529 class MixinClass : public GarbageCollectedMixin { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5609 // Park the main thread until the worker thread has initialized. | 5619 // Park the main thread until the worker thread has initialized. |
| 5610 parkMainThread(); | 5620 parkMainThread(); |
| 5611 | 5621 |
| 5612 { | 5622 { |
| 5613 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | 5623 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); |
| 5614 | 5624 |
| 5615 // Let the worker try to acquire the above mutex. It won't get it | 5625 // Let the worker try to acquire the above mutex. It won't get it |
| 5616 // until the main thread has done its GC. | 5626 // until the main thread has done its GC. |
| 5617 wakeWorkerThread(); | 5627 wakeWorkerThread(); |
| 5618 | 5628 |
| 5619 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); | 5629 preciselyCollectGarbage(); |
| 5620 | 5630 |
| 5621 // The worker thread should not have swept yet since it is waiting | 5631 // The worker thread should not have swept yet since it is waiting |
| 5622 // to get the global mutex. | 5632 // to get the global mutex. |
| 5623 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 5633 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |
| 5624 } | 5634 } |
| 5625 // At this point the main thread releases the global lock and the worker | 5635 // At this point the main thread releases the global lock and the worker |
| 5626 // can acquire it and do its sweep of its heaps. Just wait for the worke
r | 5636 // can acquire it and do its sweep of its heaps. Just wait for the worke
r |
| 5627 // to complete its sweep and check the result. | 5637 // to complete its sweep and check the result. |
| 5628 parkMainThread(); | 5638 parkMainThread(); |
| 5629 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5639 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5794 m_value = x.m_value; | 5804 m_value = x.m_value; |
| 5795 return *this; | 5805 return *this; |
| 5796 } | 5806 } |
| 5797 | 5807 |
| 5798 enum DeletedMarker { | 5808 enum DeletedMarker { |
| 5799 DeletedValue | 5809 DeletedValue |
| 5800 }; | 5810 }; |
| 5801 | 5811 |
| 5802 AllocatesOnAssignment(const AllocatesOnAssignment& other) | 5812 AllocatesOnAssignment(const AllocatesOnAssignment& other) |
| 5803 { | 5813 { |
| 5804 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 5814 conservativelyCollectGarbage(); |
| 5805 m_value = new IntWrapper(other.m_value->value()); | 5815 m_value = new IntWrapper(other.m_value->value()); |
| 5806 } | 5816 } |
| 5807 | 5817 |
| 5808 AllocatesOnAssignment(DeletedMarker) | 5818 AllocatesOnAssignment(DeletedMarker) |
| 5809 : m_value(reinterpret_cast<IntWrapper*>(-1)) { } | 5819 : m_value(reinterpret_cast<IntWrapper*>(-1)) { } |
| 5810 | 5820 |
| 5811 inline bool isDeleted() const { return m_value == reinterpret_cast<IntWrappe
r*>(-1); } | 5821 inline bool isDeleted() const { return m_value == reinterpret_cast<IntWrappe
r*>(-1); } |
| 5812 | 5822 |
| 5813 DEFINE_INLINE_TRACE() | 5823 DEFINE_INLINE_TRACE() |
| 5814 { | 5824 { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5934 DEFINE_INLINE_TRACE() { } | 5944 DEFINE_INLINE_TRACE() { } |
| 5935 | 5945 |
| 5936 static Persistent<IntNode>* s_node; | 5946 static Persistent<IntNode>* s_node; |
| 5937 }; | 5947 }; |
| 5938 | 5948 |
| 5939 Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::s_node = 0; | 5949 Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::s_node = 0; |
| 5940 | 5950 |
| 5941 TEST(HeapTest, NonNodeAllocatingNodeInDestructor) | 5951 TEST(HeapTest, NonNodeAllocatingNodeInDestructor) |
| 5942 { | 5952 { |
| 5943 new NonNodeAllocatingNodeInDestructor(); | 5953 new NonNodeAllocatingNodeInDestructor(); |
| 5944 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 5954 preciselyCollectGarbage(); |
| 5945 EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::s_node)->value()); | 5955 EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::s_node)->value()); |
| 5946 delete NonNodeAllocatingNodeInDestructor::s_node; | 5956 delete NonNodeAllocatingNodeInDestructor::s_node; |
| 5947 NonNodeAllocatingNodeInDestructor::s_node = 0; | 5957 NonNodeAllocatingNodeInDestructor::s_node = 0; |
| 5948 } | 5958 } |
| 5949 | 5959 |
| 5950 class TraceTypeEagerly1 : public GarbageCollected<TraceTypeEagerly1> { }; | 5960 class TraceTypeEagerly1 : public GarbageCollected<TraceTypeEagerly1> { }; |
| 5951 class TraceTypeEagerly2 : public TraceTypeEagerly1 { }; | 5961 class TraceTypeEagerly2 : public TraceTypeEagerly1 { }; |
| 5952 | 5962 |
| 5953 class TraceTypeNonEagerly1 { }; | 5963 class TraceTypeNonEagerly1 { }; |
| 5954 WILL_NOT_BE_EAGERLY_TRACED_CLASS(TraceTypeNonEagerly1); | 5964 WILL_NOT_BE_EAGERLY_TRACED_CLASS(TraceTypeNonEagerly1); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6002 int DeepEagerly::sTraceLazy = 0; | 6012 int DeepEagerly::sTraceLazy = 0; |
| 6003 | 6013 |
| 6004 TEST(HeapTest, TraceDeepEagerly) | 6014 TEST(HeapTest, TraceDeepEagerly) |
| 6005 { | 6015 { |
| 6006 #if !ENABLE(ASSERT) | 6016 #if !ENABLE(ASSERT) |
| 6007 DeepEagerly* obj = nullptr; | 6017 DeepEagerly* obj = nullptr; |
| 6008 for (int i = 0; i < 10000000; i++) | 6018 for (int i = 0; i < 10000000; i++) |
| 6009 obj = new DeepEagerly(obj); | 6019 obj = new DeepEagerly(obj); |
| 6010 | 6020 |
| 6011 Persistent<DeepEagerly> persistent(obj); | 6021 Persistent<DeepEagerly> persistent(obj); |
| 6012 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 6022 preciselyCollectGarbage(); |
| 6013 | 6023 |
| 6014 // Verify that the DeepEagerly chain isn't completely unravelled | 6024 // Verify that the DeepEagerly chain isn't completely unravelled |
| 6015 // by performing eager trace() calls, but the explicit mark | 6025 // by performing eager trace() calls, but the explicit mark |
| 6016 // stack is switched once some nesting limit is exceeded. | 6026 // stack is switched once some nesting limit is exceeded. |
| 6017 EXPECT_GT(DeepEagerly::sTraceLazy, 2); | 6027 EXPECT_GT(DeepEagerly::sTraceLazy, 2); |
| 6018 #endif | 6028 #endif |
| 6019 } | 6029 } |
| 6020 | 6030 |
| 6021 TEST(HeapTest, DequeExpand) | 6031 TEST(HeapTest, DequeExpand) |
| 6022 { | 6032 { |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6317 } | 6327 } |
| 6318 | 6328 |
| 6319 int traceCount() const { return m_traceCounter->traceCount(); } | 6329 int traceCount() const { return m_traceCounter->traceCount(); } |
| 6320 | 6330 |
| 6321 private: | 6331 private: |
| 6322 TestMixinAllocatingObject(ClassWithMember* member) | 6332 TestMixinAllocatingObject(ClassWithMember* member) |
| 6323 : ObjectWithLargeAmountsOfAllocationInConstructor(600, member) | 6333 : ObjectWithLargeAmountsOfAllocationInConstructor(600, member) |
| 6324 , m_traceCounter(TraceCounter::create()) | 6334 , m_traceCounter(TraceCounter::create()) |
| 6325 { | 6335 { |
| 6326 ASSERT(!ThreadState::current()->isGCForbidden()); | 6336 ASSERT(!ThreadState::current()->isGCForbidden()); |
| 6327 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); | 6337 conservativelyCollectGarbage(); |
| 6328 EXPECT_GT(member->traceCount(), 0); | 6338 EXPECT_GT(member->traceCount(), 0); |
| 6329 EXPECT_GT(traceCount(), 0); | 6339 EXPECT_GT(traceCount(), 0); |
| 6330 } | 6340 } |
| 6331 | 6341 |
| 6332 Member<TraceCounter> m_traceCounter; | 6342 Member<TraceCounter> m_traceCounter; |
| 6333 }; | 6343 }; |
| 6334 | 6344 |
| 6335 TEST(HeapTest, MixinConstructionNoGC) | 6345 TEST(HeapTest, MixinConstructionNoGC) |
| 6336 { | 6346 { |
| 6337 Persistent<ClassWithMember> object = ClassWithMember::create(); | 6347 Persistent<ClassWithMember> object = ClassWithMember::create(); |
| 6338 EXPECT_EQ(0, object->traceCount()); | 6348 EXPECT_EQ(0, object->traceCount()); |
| 6339 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); | 6349 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); |
| 6340 EXPECT_TRUE(mixin); | 6350 EXPECT_TRUE(mixin); |
| 6341 EXPECT_GT(object->traceCount(), 0); | 6351 EXPECT_GT(object->traceCount(), 0); |
| 6342 EXPECT_GT(mixin->traceCount(), 0); | 6352 EXPECT_GT(mixin->traceCount(), 0); |
| 6343 } | 6353 } |
| 6344 | 6354 |
| 6345 class WeakPersistentHolder final { | 6355 class WeakPersistentHolder final { |
| 6346 public: | 6356 public: |
| 6347 explicit WeakPersistentHolder(IntWrapper* object) : m_object(object) { } | 6357 explicit WeakPersistentHolder(IntWrapper* object) : m_object(object) { } |
| 6348 IntWrapper* object() const { return m_object; } | 6358 IntWrapper* object() const { return m_object; } |
| 6349 private: | 6359 private: |
| 6350 WeakPersistent<IntWrapper> m_object; | 6360 WeakPersistent<IntWrapper> m_object; |
| 6351 }; | 6361 }; |
| 6352 | 6362 |
| 6353 TEST(HeapTest, WeakPersistent) | 6363 TEST(HeapTest, WeakPersistent) |
| 6354 { | 6364 { |
| 6355 Persistent<IntWrapper> object = new IntWrapper(20); | 6365 Persistent<IntWrapper> object = new IntWrapper(20); |
| 6356 OwnPtr<WeakPersistentHolder> holder = adoptPtr(new WeakPersistentHolder(obje
ct)); | 6366 OwnPtr<WeakPersistentHolder> holder = adoptPtr(new WeakPersistentHolder(obje
ct)); |
| 6357 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 6367 preciselyCollectGarbage(); |
| 6358 EXPECT_TRUE(holder->object()); | 6368 EXPECT_TRUE(holder->object()); |
| 6359 object = nullptr; | 6369 object = nullptr; |
| 6360 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); | 6370 preciselyCollectGarbage(); |
| 6361 EXPECT_FALSE(holder->object()); | 6371 EXPECT_FALSE(holder->object()); |
| 6362 } | 6372 } |
| 6363 | 6373 |
| 6364 } // namespace blink | 6374 } // namespace blink |
| OLD | NEW |