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 |