| 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 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; | 507 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; |
| 508 | 508 |
| 509 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) | 509 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) |
| 510 { | 510 { |
| 511 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); | 511 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); |
| 512 } | 512 } |
| 513 | 513 |
| 514 void runThread() override | 514 void runThread() override |
| 515 { | 515 { |
| 516 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; | 516 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; |
| 517 ThreadState::attach(); | 517 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 518 | 518 |
| 519 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); | 519 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); |
| 520 int gcCount = 0; | 520 int gcCount = 0; |
| 521 while (!done()) { | 521 while (!done()) { |
| 522 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 522 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 523 { | 523 { |
| 524 Persistent<IntWrapper> wrapper; | 524 Persistent<IntWrapper> wrapper; |
| 525 | 525 |
| 526 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); | 526 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); |
| 527 | 527 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 class ThreadedWeaknessTester : public ThreadedTesterBase { | 566 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 567 public: | 567 public: |
| 568 static void test() | 568 static void test() |
| 569 { | 569 { |
| 570 ThreadedTesterBase::test(new ThreadedWeaknessTester); | 570 ThreadedTesterBase::test(new ThreadedWeaknessTester); |
| 571 } | 571 } |
| 572 | 572 |
| 573 private: | 573 private: |
| 574 void runThread() override | 574 void runThread() override |
| 575 { | 575 { |
| 576 ThreadState::attach(); | 576 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 577 | 577 |
| 578 int gcCount = 0; | 578 int gcCount = 0; |
| 579 while (!done()) { | 579 while (!done()) { |
| 580 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 580 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 581 { | 581 { |
| 582 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 582 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 583 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 583 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
| 584 | 584 |
| 585 for (int i = 0; i < numberOfAllocations; i++) { | 585 for (int i = 0; i < numberOfAllocations; i++) { |
| 586 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 586 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 explicit PersistentChain(int count) | 660 explicit PersistentChain(int count) |
| 661 { | 661 { |
| 662 m_refCountedChain = adoptRef(RefCountedChain::create(count)); | 662 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 663 } | 663 } |
| 664 | 664 |
| 665 RefPtr<RefCountedChain> m_refCountedChain; | 665 RefPtr<RefCountedChain> m_refCountedChain; |
| 666 }; | 666 }; |
| 667 | 667 |
| 668 void runThread() override | 668 void runThread() override |
| 669 { | 669 { |
| 670 ThreadState::attach(); | 670 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 671 | 671 |
| 672 PersistentChain::create(100); | 672 PersistentChain::create(100); |
| 673 | 673 |
| 674 // Upon thread detach, GCs will run until all persistents have been | 674 // Upon thread detach, GCs will run until all persistents have been |
| 675 // released. We verify that the draining of persistents proceeds | 675 // released. We verify that the draining of persistents proceeds |
| 676 // as expected by dropping one Persistent<> per GC until there | 676 // as expected by dropping one Persistent<> per GC until there |
| 677 // are none left. | 677 // are none left. |
| 678 ThreadState::detach(); | 678 ThreadState::detach(); |
| 679 atomicDecrement(&m_threadsToFinish); | 679 atomicDecrement(&m_threadsToFinish); |
| 680 } | 680 } |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 clearOutOldGarbage(); | 1764 clearOutOldGarbage(); |
| 1765 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 1765 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
| 1766 { | 1766 { |
| 1767 size_t slack = 0; | 1767 size_t slack = 0; |
| 1768 | 1768 |
| 1769 // When the test starts there may already have been leaked some memory | 1769 // When the test starts there may already have been leaked some memory |
| 1770 // on the heap, so we establish a base line. | 1770 // on the heap, so we establish a base line. |
| 1771 size_t baseLevel = initialObjectPayloadSize; | 1771 size_t baseLevel = initialObjectPayloadSize; |
| 1772 bool testPagesAllocated = !baseLevel; | 1772 bool testPagesAllocated = !baseLevel; |
| 1773 if (testPagesAllocated) | 1773 if (testPagesAllocated) |
| 1774 EXPECT_EQ(Heap::allocatedSpace(), 0ul); | 1774 EXPECT_EQ(ThreadState::current()->allocatedSpace(), 0ul); |
| 1775 | 1775 |
| 1776 // This allocates objects on the general heap which should add a page of
memory. | 1776 // This allocates objects on the general heap which should add a page of
memory. |
| 1777 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); | 1777 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); |
| 1778 slack += 4; | 1778 slack += 4; |
| 1779 memset(alloc32, 40, 32); | 1779 memset(alloc32, 40, 32); |
| 1780 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); | 1780 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); |
| 1781 slack += 4; | 1781 slack += 4; |
| 1782 memset(alloc64, 27, 64); | 1782 memset(alloc64, 27, 64); |
| 1783 | 1783 |
| 1784 size_t total = 96; | 1784 size_t total = 96; |
| 1785 | 1785 |
| 1786 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1786 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); |
| 1787 if (testPagesAllocated) | 1787 if (testPagesAllocated) |
| 1788 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); | 1788 EXPECT_EQ(ThreadState::current()->allocatedSpace(), blinkPageSize *
2); |
| 1789 | 1789 |
| 1790 EXPECT_EQ(alloc32->get(0), 40); | 1790 EXPECT_EQ(alloc32->get(0), 40); |
| 1791 EXPECT_EQ(alloc32->get(31), 40); | 1791 EXPECT_EQ(alloc32->get(31), 40); |
| 1792 EXPECT_EQ(alloc64->get(0), 27); | 1792 EXPECT_EQ(alloc64->get(0), 27); |
| 1793 EXPECT_EQ(alloc64->get(63), 27); | 1793 EXPECT_EQ(alloc64->get(63), 27); |
| 1794 | 1794 |
| 1795 conservativelyCollectGarbage(); | 1795 conservativelyCollectGarbage(); |
| 1796 | 1796 |
| 1797 EXPECT_EQ(alloc32->get(0), 40); | 1797 EXPECT_EQ(alloc32->get(0), 40); |
| 1798 EXPECT_EQ(alloc32->get(31), 40); | 1798 EXPECT_EQ(alloc32->get(31), 40); |
| 1799 EXPECT_EQ(alloc64->get(0), 27); | 1799 EXPECT_EQ(alloc64->get(0), 27); |
| 1800 EXPECT_EQ(alloc64->get(63), 27); | 1800 EXPECT_EQ(alloc64->get(63), 27); |
| 1801 } | 1801 } |
| 1802 | 1802 |
| 1803 clearOutOldGarbage(); | 1803 clearOutOldGarbage(); |
| 1804 size_t total = 0; | 1804 size_t total = 0; |
| 1805 size_t slack = 0; | 1805 size_t slack = 0; |
| 1806 size_t baseLevel = Heap::objectPayloadSizeForTesting(); | 1806 size_t baseLevel = Heap::objectPayloadSizeForTesting(); |
| 1807 bool testPagesAllocated = !baseLevel; | 1807 bool testPagesAllocated = !baseLevel; |
| 1808 if (testPagesAllocated) | 1808 if (testPagesAllocated) |
| 1809 EXPECT_EQ(Heap::allocatedSpace(), 0ul); | 1809 EXPECT_EQ(ThreadState::current()->allocatedSpace(), 0ul); |
| 1810 | 1810 |
| 1811 size_t big = 1008; | 1811 size_t big = 1008; |
| 1812 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(
big); | 1812 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(
big); |
| 1813 total += big; | 1813 total += big; |
| 1814 slack += 4; | 1814 slack += 4; |
| 1815 | 1815 |
| 1816 size_t persistentCount = 0; | 1816 size_t persistentCount = 0; |
| 1817 const size_t numPersistents = 100000; | 1817 const size_t numPersistents = 100000; |
| 1818 Persistent<DynamicallySizedObject>* persistents[numPersistents]; | 1818 Persistent<DynamicallySizedObject>* persistents[numPersistents]; |
| 1819 | 1819 |
| 1820 for (int i = 0; i < 1000; i++) { | 1820 for (int i = 0; i < 1000; i++) { |
| 1821 size_t size = 128 + i * 8; | 1821 size_t size = 128 + i * 8; |
| 1822 total += size; | 1822 total += size; |
| 1823 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(
DynamicallySizedObject::create(size)); | 1823 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(
DynamicallySizedObject::create(size)); |
| 1824 slack += 4; | 1824 slack += 4; |
| 1825 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1825 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); |
| 1826 if (testPagesAllocated) | 1826 if (testPagesAllocated) |
| 1827 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); | 1827 EXPECT_EQ(0ul, ThreadState::current()->allocatedSpace() & (blinkPage
Size - 1)); |
| 1828 } | 1828 } |
| 1829 | 1829 |
| 1830 { | 1830 { |
| 1831 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); | 1831 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); |
| 1832 slack += 4; | 1832 slack += 4; |
| 1833 memset(alloc32b, 40, 32); | 1833 memset(alloc32b, 40, 32); |
| 1834 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); | 1834 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); |
| 1835 slack += 4; | 1835 slack += 4; |
| 1836 memset(alloc64b, 27, 64); | 1836 memset(alloc64b, 27, 64); |
| 1837 EXPECT_TRUE(alloc32b != alloc64b); | 1837 EXPECT_TRUE(alloc32b != alloc64b); |
| 1838 | 1838 |
| 1839 total += 96; | 1839 total += 96; |
| 1840 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1840 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); |
| 1841 if (testPagesAllocated) | 1841 if (testPagesAllocated) |
| 1842 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); | 1842 EXPECT_EQ(0ul, ThreadState::current()->allocatedSpace() & (blinkPage
Size - 1)); |
| 1843 } | 1843 } |
| 1844 | 1844 |
| 1845 clearOutOldGarbage(); | 1845 clearOutOldGarbage(); |
| 1846 total -= 96; | 1846 total -= 96; |
| 1847 slack -= 8; | 1847 slack -= 8; |
| 1848 if (testPagesAllocated) | 1848 if (testPagesAllocated) |
| 1849 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); | 1849 EXPECT_EQ(0ul, ThreadState::current()->allocatedSpace() & (blinkPageSize
- 1)); |
| 1850 | 1850 |
| 1851 // Clear the persistent, so that the big area will be garbage collected. | 1851 // Clear the persistent, so that the big area will be garbage collected. |
| 1852 bigArea.release(); | 1852 bigArea.release(); |
| 1853 clearOutOldGarbage(); | 1853 clearOutOldGarbage(); |
| 1854 | 1854 |
| 1855 total -= big; | 1855 total -= big; |
| 1856 slack -= 4; | 1856 slack -= 4; |
| 1857 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); | 1857 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); |
| 1858 if (testPagesAllocated) | 1858 if (testPagesAllocated) |
| 1859 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); | 1859 EXPECT_EQ(0ul, ThreadState::current()->allocatedSpace() & (blinkPageSize
- 1)); |
| 1860 | 1860 |
| 1861 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); | 1861 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); |
| 1862 if (testPagesAllocated) | 1862 if (testPagesAllocated) |
| 1863 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); | 1863 EXPECT_EQ(0ul, ThreadState::current()->allocatedSpace() & (blinkPageSize
- 1)); |
| 1864 | 1864 |
| 1865 for (size_t i = 0; i < persistentCount; i++) { | 1865 for (size_t i = 0; i < persistentCount; i++) { |
| 1866 delete persistents[i]; | 1866 delete persistents[i]; |
| 1867 persistents[i] = 0; | 1867 persistents[i] = 0; |
| 1868 } | 1868 } |
| 1869 | 1869 |
| 1870 uint8_t* address = reinterpret_cast<uint8_t*>(Heap::allocate<DynamicallySize
dObject>(100)); | 1870 uint8_t* address = reinterpret_cast<uint8_t*>(Heap::allocate<DynamicallySize
dObject>(100)); |
| 1871 for (int i = 0; i < 100; i++) | 1871 for (int i = 0; i < 100; i++) |
| 1872 address[i] = i; | 1872 address[i] = i; |
| 1873 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject
>(address, 100000)); | 1873 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject
>(address, 100000)); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2316 } | 2316 } |
| 2317 clearOutOldGarbage(); | 2317 clearOutOldGarbage(); |
| 2318 size_t afterFree = Heap::objectPayloadSizeForTesting(); | 2318 size_t afterFree = Heap::objectPayloadSizeForTesting(); |
| 2319 EXPECT_TRUE(initialObjectPayloadSize == afterFree); | 2319 EXPECT_TRUE(initialObjectPayloadSize == afterFree); |
| 2320 } | 2320 } |
| 2321 | 2321 |
| 2322 TEST(HeapTest, LargeHeapObjects) | 2322 TEST(HeapTest, LargeHeapObjects) |
| 2323 { | 2323 { |
| 2324 clearOutOldGarbage(); | 2324 clearOutOldGarbage(); |
| 2325 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2325 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
| 2326 size_t initialAllocatedSpace = Heap::allocatedSpace(); | 2326 size_t initialAllocatedSpace = ThreadState::current()->allocatedSpace(); |
| 2327 IntWrapper::s_destructorCalls = 0; | 2327 IntWrapper::s_destructorCalls = 0; |
| 2328 LargeHeapObject::s_destructorCalls = 0; | 2328 LargeHeapObject::s_destructorCalls = 0; |
| 2329 { | 2329 { |
| 2330 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a
llocated. | 2330 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a
llocated. |
| 2331 Persistent<LargeHeapObject> object = LargeHeapObject::create(); | 2331 Persistent<LargeHeapObject> object = LargeHeapObject::create(); |
| 2332 ASSERT(ThreadState::current()->findPageFromAddress(object)); | 2332 ASSERT(ThreadState::current()->findPageFromAddress(object)); |
| 2333 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char
*>(object.get()) + sizeof(LargeHeapObject) - 1)); | 2333 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char
*>(object.get()) + sizeof(LargeHeapObject) - 1)); |
| 2334 clearOutOldGarbage(); | 2334 clearOutOldGarbage(); |
| 2335 size_t afterAllocation = Heap::allocatedSpace(); | 2335 size_t afterAllocation = ThreadState::current()->allocatedSpace(); |
| 2336 { | 2336 { |
| 2337 object->set(0, 'a'); | 2337 object->set(0, 'a'); |
| 2338 EXPECT_EQ('a', object->get(0)); | 2338 EXPECT_EQ('a', object->get(0)); |
| 2339 object->set(object->length() - 1, 'b'); | 2339 object->set(object->length() - 1, 'b'); |
| 2340 EXPECT_EQ('b', object->get(object->length() - 1)); | 2340 EXPECT_EQ('b', object->get(object->length() - 1)); |
| 2341 size_t expectedLargeHeapObjectPayloadSize = Heap::allocationSizeFrom
Size(sizeof(LargeHeapObject)); | 2341 size_t expectedLargeHeapObjectPayloadSize = Heap::allocationSizeFrom
Size(sizeof(LargeHeapObject)); |
| 2342 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz
e + sizeof(IntWrapper); | 2342 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz
e + sizeof(IntWrapper); |
| 2343 size_t actualObjectPayloadSize = Heap::objectPayloadSizeForTesting()
- initialObjectPayloadSize; | 2343 size_t actualObjectPayloadSize = Heap::objectPayloadSizeForTesting()
- initialObjectPayloadSize; |
| 2344 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s
lack); | 2344 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s
lack); |
| 2345 // There is probably space for the IntWrapper in a heap page without | 2345 // There is probably space for the IntWrapper in a heap page without |
| 2346 // allocating extra pages. However, the IntWrapper allocation might
cause | 2346 // allocating extra pages. However, the IntWrapper allocation might
cause |
| 2347 // the addition of a heap page. | 2347 // the addition of a heap page. |
| 2348 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte
dLargeHeapObjectPayloadSize; | 2348 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte
dLargeHeapObjectPayloadSize; |
| 2349 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec
tAllocationSize; | 2349 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec
tAllocationSize; |
| 2350 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack +
blinkPageSize; | 2350 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack +
blinkPageSize; |
| 2351 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); | 2351 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); |
| 2352 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); | 2352 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); |
| 2353 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 2353 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 2354 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 2354 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 2355 for (int i = 0; i < 10; i++) | 2355 for (int i = 0; i < 10; i++) |
| 2356 object = LargeHeapObject::create(); | 2356 object = LargeHeapObject::create(); |
| 2357 } | 2357 } |
| 2358 clearOutOldGarbage(); | 2358 clearOutOldGarbage(); |
| 2359 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); | 2359 EXPECT_TRUE(ThreadState::current()->allocatedSpace() == afterAllocation)
; |
| 2360 EXPECT_EQ(10, IntWrapper::s_destructorCalls); | 2360 EXPECT_EQ(10, IntWrapper::s_destructorCalls); |
| 2361 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2361 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2362 } | 2362 } |
| 2363 clearOutOldGarbage(); | 2363 clearOutOldGarbage(); |
| 2364 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; | 2364 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; |
| 2365 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); | 2365 EXPECT_TRUE(initialAllocatedSpace == ThreadState::current()->allocatedSpace(
)); |
| 2366 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 2366 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
| 2367 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); | 2367 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); |
| 2368 preciselyCollectGarbage(); | 2368 preciselyCollectGarbage(); |
| 2369 } | 2369 } |
| 2370 | 2370 |
| 2371 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; | 2371 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; |
| 2372 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; | 2372 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; |
| 2373 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; | 2373 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; |
| 2374 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; | 2374 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; |
| 2375 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; | 2375 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3782 // This is a low-level test where we call checkAndMarkPointer. This method | 3782 // This is a low-level test where we call checkAndMarkPointer. This method |
| 3783 // causes the object start bitmap to be computed which requires the heap | 3783 // causes the object start bitmap to be computed which requires the heap |
| 3784 // to be in a consistent state (e.g. the free allocation area must be put | 3784 // to be in a consistent state (e.g. the free allocation area must be put |
| 3785 // into a free list header). However when we call makeConsistentForGC it | 3785 // into a free list header). However when we call makeConsistentForGC it |
| 3786 // also clears out the freelists so we have to rebuild those before trying | 3786 // also clears out the freelists so we have to rebuild those before trying |
| 3787 // to allocate anything again. We do this by forcing a GC after doing the | 3787 // to allocate anything again. We do this by forcing a GC after doing the |
| 3788 // checkAndMarkPointer tests. | 3788 // checkAndMarkPointer tests. |
| 3789 { | 3789 { |
| 3790 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3790 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3791 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. | 3791 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. |
| 3792 Heap::flushHeapDoesNotContainCache(); | 3792 ThreadState::current()->flushHeapDoesNotContainCache(); |
| 3793 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3793 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3794 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
; | 3794 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
; |
| 3795 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); | 3795 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); |
| 3796 } | 3796 } |
| 3797 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 3797 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
| 3798 visitor.reset(); | 3798 visitor.reset(); |
| 3799 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); | 3799 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); |
| 3800 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 3800 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); |
| 3801 EXPECT_EQ(2ul, visitor.count()); | 3801 EXPECT_EQ(2ul, visitor.count()); |
| 3802 visitor.reset(); | 3802 visitor.reset(); |
| 3803 } | 3803 } |
| 3804 // This forces a GC without stack scanning which results in the objects | 3804 // This forces a GC without stack scanning which results in the objects |
| 3805 // being collected. This will also rebuild the above mentioned freelists, | 3805 // being collected. This will also rebuild the above mentioned freelists, |
| 3806 // however we don't rely on that below since we don't have any allocations. | 3806 // however we don't rely on that below since we don't have any allocations. |
| 3807 clearOutOldGarbage(); | 3807 clearOutOldGarbage(); |
| 3808 { | 3808 { |
| 3809 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3809 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3810 EXPECT_TRUE(scope.allThreadsParked()); | 3810 EXPECT_TRUE(scope.allThreadsParked()); |
| 3811 Heap::flushHeapDoesNotContainCache(); | 3811 ThreadState::current()->flushHeapDoesNotContainCache(); |
| 3812 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3812 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3813 // We would like to assert that checkAndMarkPointer returned false | 3813 // We would like to assert that checkAndMarkPointer returned false |
| 3814 // here because the pointers no longer point into a valid object | 3814 // here because the pointers no longer point into a valid object |
| 3815 // (it's been freed by the GCs. But checkAndMarkPointer will return | 3815 // (it's been freed by the GCs. But checkAndMarkPointer will return |
| 3816 // true for any pointer that points into a heap page, regardless of | 3816 // true for any pointer that points into a heap page, regardless of |
| 3817 // whether it points at a valid object (this ensures the | 3817 // whether it points at a valid object (this ensures the |
| 3818 // correctness of the page-based on-heap address caches), so we | 3818 // correctness of the page-based on-heap address caches), so we |
| 3819 // can't make that assert. | 3819 // can't make that assert. |
| 3820 Heap::checkAndMarkPointer(&visitor, objectAddresses[i]); | 3820 Heap::checkAndMarkPointer(&visitor, objectAddresses[i]); |
| 3821 Heap::checkAndMarkPointer(&visitor, endAddresses[i]); | 3821 Heap::checkAndMarkPointer(&visitor, endAddresses[i]); |
| (...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4727 { | 4727 { |
| 4728 // Since the sleeper thread has detached this is the only thread. | 4728 // Since the sleeper thread has detached this is the only thread. |
| 4729 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 4729 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); |
| 4730 EXPECT_TRUE(scope.allThreadsParked()); | 4730 EXPECT_TRUE(scope.allThreadsParked()); |
| 4731 } | 4731 } |
| 4732 } | 4732 } |
| 4733 | 4733 |
| 4734 private: | 4734 private: |
| 4735 static void sleeperMainFunc() | 4735 static void sleeperMainFunc() |
| 4736 { | 4736 { |
| 4737 ThreadState::attach(); | 4737 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 4738 s_sleeperRunning = true; | 4738 s_sleeperRunning = true; |
| 4739 | 4739 |
| 4740 // Simulate a long running op that is not entering a safepoint. | 4740 // Simulate a long running op that is not entering a safepoint. |
| 4741 while (!s_sleeperDone) { | 4741 while (!s_sleeperDone) { |
| 4742 Platform::current()->yieldCurrentThread(); | 4742 Platform::current()->yieldCurrentThread(); |
| 4743 } | 4743 } |
| 4744 | 4744 |
| 4745 ThreadState::detach(); | 4745 ThreadState::detach(); |
| 4746 s_sleeperRunning = false; | 4746 s_sleeperRunning = false; |
| 4747 } | 4747 } |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5417 // shutdown. | 5417 // shutdown. |
| 5418 wakeWorkerThread(); | 5418 wakeWorkerThread(); |
| 5419 } | 5419 } |
| 5420 | 5420 |
| 5421 private: | 5421 private: |
| 5422 | 5422 |
| 5423 static void workerThreadMain() | 5423 static void workerThreadMain() |
| 5424 { | 5424 { |
| 5425 MutexLocker locker(workerThreadMutex()); | 5425 MutexLocker locker(workerThreadMutex()); |
| 5426 | 5426 |
| 5427 ThreadState::attach(); | 5427 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 5428 | 5428 |
| 5429 { | 5429 { |
| 5430 // Create a worker object that is not kept alive except the | 5430 // Create a worker object that is not kept alive except the |
| 5431 // main thread will keep it as an integer value on its stack. | 5431 // main thread will keep it as an integer value on its stack. |
| 5432 IntWrapper* workerObject = IntWrapper::create(42); | 5432 IntWrapper* workerObject = IntWrapper::create(42); |
| 5433 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | 5433 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); |
| 5434 } | 5434 } |
| 5435 | 5435 |
| 5436 // Signal the main thread that the worker is done with its allocation. | 5436 // Signal the main thread that the worker is done with its allocation. |
| 5437 wakeMainThread(); | 5437 wakeMainThread(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5538 parkWorkerThread(); | 5538 parkWorkerThread(); |
| 5539 } | 5539 } |
| 5540 | 5540 |
| 5541 return weakCollection; | 5541 return weakCollection; |
| 5542 } | 5542 } |
| 5543 | 5543 |
| 5544 static void workerThreadMain() | 5544 static void workerThreadMain() |
| 5545 { | 5545 { |
| 5546 MutexLocker locker(workerThreadMutex()); | 5546 MutexLocker locker(workerThreadMutex()); |
| 5547 | 5547 |
| 5548 ThreadState::attach(); | 5548 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 5549 | 5549 |
| 5550 { | 5550 { |
| 5551 Persistent<WeakCollectionType> collection = allocateCollection(); | 5551 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5552 { | 5552 { |
| 5553 // Prevent weak processing with an iterator and GC. | 5553 // Prevent weak processing with an iterator and GC. |
| 5554 WeakCollectionType::iterator it = collection->begin(); | 5554 WeakCollectionType::iterator it = collection->begin(); |
| 5555 conservativelyCollectGarbage(); | 5555 conservativelyCollectGarbage(); |
| 5556 | 5556 |
| 5557 // The backing should be strongified because of the iterator. | 5557 // The backing should be strongified because of the iterator. |
| 5558 EXPECT_EQ(6u, collection->size()); | 5558 EXPECT_EQ(6u, collection->size()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5699 // can acquire it and do its sweep of its heaps. Just wait for the worke
r | 5699 // can acquire it and do its sweep of its heaps. Just wait for the worke
r |
| 5700 // to complete its sweep and check the result. | 5700 // to complete its sweep and check the result. |
| 5701 parkMainThread(); | 5701 parkMainThread(); |
| 5702 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5702 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| 5703 } | 5703 } |
| 5704 | 5704 |
| 5705 private: | 5705 private: |
| 5706 static void workerThreadMain() | 5706 static void workerThreadMain() |
| 5707 { | 5707 { |
| 5708 MutexLocker locker(workerThreadMutex()); | 5708 MutexLocker locker(workerThreadMutex()); |
| 5709 ThreadState::attach(); | 5709 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 5710 | 5710 |
| 5711 DestructorLockingObject* dlo = DestructorLockingObject::create(); | 5711 DestructorLockingObject* dlo = DestructorLockingObject::create(); |
| 5712 ASSERT_UNUSED(dlo, dlo); | 5712 ASSERT_UNUSED(dlo, dlo); |
| 5713 | 5713 |
| 5714 // Wake up the main thread which is waiting for the worker to do its | 5714 // Wake up the main thread which is waiting for the worker to do its |
| 5715 // allocation. | 5715 // allocation. |
| 5716 wakeMainThread(); | 5716 wakeMainThread(); |
| 5717 | 5717 |
| 5718 // Wait for the main thread to get the global lock to ensure it has | 5718 // Wait for the main thread to get the global lock to ensure it has |
| 5719 // it before the worker tries to acquire it. We want the worker to | 5719 // it before the worker tries to acquire it. We want the worker to |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5767 private: | 5767 private: |
| 5768 | 5768 |
| 5769 static void workerThreadMain() | 5769 static void workerThreadMain() |
| 5770 { | 5770 { |
| 5771 MutexLocker locker(workerThreadMutex()); | 5771 MutexLocker locker(workerThreadMutex()); |
| 5772 | 5772 |
| 5773 // Start up a worker thread and have it detach after the main thread has
. | 5773 // Start up a worker thread and have it detach after the main thread has
. |
| 5774 // Do this to verify that CrossThreadPersistent<>s referring to objects | 5774 // Do this to verify that CrossThreadPersistent<>s referring to objects |
| 5775 // on one of the main thread's heaps does not upset the CTP invalidation | 5775 // on one of the main thread's heaps does not upset the CTP invalidation |
| 5776 // pass that ThreadState::detach() performs. | 5776 // pass that ThreadState::detach() performs. |
| 5777 ThreadState::attach(); | 5777 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 5778 | 5778 |
| 5779 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(43)); | 5779 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(43)); |
| 5780 | 5780 |
| 5781 // Wait for the main thread to detach. | 5781 // Wait for the main thread to detach. |
| 5782 wakeMainThread(); | 5782 wakeMainThread(); |
| 5783 parkWorkerThread(); | 5783 parkWorkerThread(); |
| 5784 | 5784 |
| 5785 ThreadState::detach(); | 5785 ThreadState::detach(); |
| 5786 wakeMainThread(); | 5786 wakeMainThread(); |
| 5787 } | 5787 } |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6433 preciselyCollectGarbage(); | 6433 preciselyCollectGarbage(); |
| 6434 EXPECT_FALSE(holder->object()); | 6434 EXPECT_FALSE(holder->object()); |
| 6435 } | 6435 } |
| 6436 | 6436 |
| 6437 namespace { | 6437 namespace { |
| 6438 | 6438 |
| 6439 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) | 6439 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) |
| 6440 { | 6440 { |
| 6441 // Step 2: Create an object and store the pointer. | 6441 // Step 2: Create an object and store the pointer. |
| 6442 MutexLocker locker(workerThreadMutex()); | 6442 MutexLocker locker(workerThreadMutex()); |
| 6443 ThreadState::attach(); | 6443 ThreadState::attach(ThreadState::PerThreadHeapDisabled); |
| 6444 *object = DestructorLockingObject::create(); | 6444 *object = DestructorLockingObject::create(); |
| 6445 wakeMainThread(); | 6445 wakeMainThread(); |
| 6446 parkWorkerThread(); | 6446 parkWorkerThread(); |
| 6447 | 6447 |
| 6448 // Step 4: Run a GC. | 6448 // Step 4: Run a GC. |
| 6449 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B
linkGC::ForcedGC); | 6449 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B
linkGC::ForcedGC); |
| 6450 wakeMainThread(); | 6450 wakeMainThread(); |
| 6451 parkWorkerThread(); | 6451 parkWorkerThread(); |
| 6452 | 6452 |
| 6453 // Step 6: Finish. | 6453 // Step 6: Finish. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6523 EXPECT_EQ(1u, vector2.size()); | 6523 EXPECT_EQ(1u, vector2.size()); |
| 6524 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables | 6524 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables |
| 6525 // Vector<>s with inline capacity, remove. | 6525 // Vector<>s with inline capacity, remove. |
| 6526 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) | 6526 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) |
| 6527 EXPECT_EQ(16u, vector1.capacity()); | 6527 EXPECT_EQ(16u, vector1.capacity()); |
| 6528 EXPECT_EQ(16u, vector2.capacity()); | 6528 EXPECT_EQ(16u, vector2.capacity()); |
| 6529 #endif | 6529 #endif |
| 6530 } | 6530 } |
| 6531 | 6531 |
| 6532 } // namespace blink | 6532 } // namespace blink |
| OLD | NEW |