Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: third_party/WebKit/Source/platform/heap/HeapTest.cpp

Issue 1892713003: Prepare for multiple ThreadHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 namespace blink { 237 namespace blink {
238 238
239 class TestGCScope { 239 class TestGCScope {
240 public: 240 public:
241 explicit TestGCScope(BlinkGC::StackState state) 241 explicit TestGCScope(BlinkGC::StackState state)
242 : m_state(ThreadState::current()) 242 : m_state(ThreadState::current())
243 , m_safePointScope(state) 243 , m_safePointScope(state)
244 , m_parkedAllThreads(false) 244 , m_parkedAllThreads(false)
245 { 245 {
246 ASSERT(m_state->checkThread()); 246 ASSERT(m_state->checkThread());
247 if (LIKELY(ThreadState::stopThreads())) { 247 if (LIKELY(m_state->heap().park())) {
248 ThreadHeap::preGC(); 248 m_state->heap().preGC();
249 m_parkedAllThreads = true; 249 m_parkedAllThreads = true;
250 } 250 }
251 } 251 }
252 252
253 bool allThreadsParked() { return m_parkedAllThreads; } 253 bool allThreadsParked() { return m_parkedAllThreads; }
254 254
255 ~TestGCScope() 255 ~TestGCScope()
256 { 256 {
257 // Only cleanup if we parked all threads in which case the GC happened 257 // Only cleanup if we parked all threads in which case the GC happened
258 // and we need to resume the other threads. 258 // and we need to resume the other threads.
259 if (LIKELY(m_parkedAllThreads)) { 259 if (LIKELY(m_parkedAllThreads)) {
260 ThreadHeap::postGC(BlinkGC::GCWithSweep); 260 m_state->heap().postGC(BlinkGC::GCWithSweep);
261 ThreadState::resumeThreads(); 261 m_state->heap().resume();
262 } 262 }
263 } 263 }
264 264
265 private: 265 private:
266 ThreadState* m_state; 266 ThreadState* m_state;
267 SafePointScope m_safePointScope; 267 SafePointScope m_safePointScope;
268 bool m_parkedAllThreads; // False if we fail to park all threads 268 bool m_parkedAllThreads; // False if we fail to park all threads
269 }; 269 };
270 270
271 #define DEFINE_VISITOR_METHODS(Type) \ 271 #define DEFINE_VISITOR_METHODS(Type) \
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 DEFINE_INLINE_TRACE() { } 407 DEFINE_INLINE_TRACE() { }
408 private: 408 private:
409 static const int s_arraySize = 1000; 409 static const int s_arraySize = 1000;
410 int8_t m_array[s_arraySize]; 410 int8_t m_array[s_arraySize];
411 }; 411 };
412 412
413 // Do several GCs to make sure that later GCs don't free up old memory from 413 // Do several GCs to make sure that later GCs don't free up old memory from
414 // previously run tests in this process. 414 // previously run tests in this process.
415 static void clearOutOldGarbage() 415 static void clearOutOldGarbage()
416 { 416 {
417 ThreadHeap& heap = ThreadState::current()->heap();
417 while (true) { 418 while (true) {
418 size_t used = ThreadHeap::objectPayloadSizeForTesting(); 419 size_t used = heap.objectPayloadSizeForTesting();
419 preciselyCollectGarbage(); 420 preciselyCollectGarbage();
420 if (ThreadHeap::objectPayloadSizeForTesting() >= used) 421 if (heap.objectPayloadSizeForTesting() >= used)
421 break; 422 break;
422 } 423 }
423 } 424 }
424 425
425 class OffHeapInt : public RefCounted<OffHeapInt> { 426 class OffHeapInt : public RefCounted<OffHeapInt> {
426 public: 427 public:
427 static RefPtr<OffHeapInt> create(int x) 428 static RefPtr<OffHeapInt> create(int x)
428 { 429 {
429 return adoptRef(new OffHeapInt(x)); 430 return adoptRef(new OffHeapInt(x));
430 } 431 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 557 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
557 testing::yieldCurrentThread(); 558 testing::yieldCurrentThread();
558 } 559 }
559 560
560 // Intentionally leak the cross-thread persistent so as to verify 561 // Intentionally leak the cross-thread persistent so as to verify
561 // that later GCs correctly handle cross-thread persistents that 562 // that later GCs correctly handle cross-thread persistents that
562 // refer to finalized objects after their heaps have been detached 563 // refer to finalized objects after their heaps have been detached
563 // and freed. 564 // and freed.
564 EXPECT_TRUE(longLivingPersistent.leakPtr()); 565 EXPECT_TRUE(longLivingPersistent.leakPtr());
565 566
566 ThreadState::detach(); 567 ThreadState::detachCurrentThread();
567 atomicDecrement(&m_threadsToFinish); 568 atomicDecrement(&m_threadsToFinish);
568 } 569 }
569 }; 570 };
570 571
571 class ThreadedWeaknessTester : public ThreadedTesterBase { 572 class ThreadedWeaknessTester : public ThreadedTesterBase {
572 public: 573 public:
573 static void test() 574 static void test()
574 { 575 {
575 ThreadedTesterBase::test(new ThreadedWeaknessTester); 576 ThreadedTesterBase::test(new ThreadedWeaknessTester);
576 } 577 }
(...skipping 27 matching lines...) Expand all
604 // TODO(haraken): This snapshot GC causes crashes, so disable 605 // TODO(haraken): This snapshot GC causes crashes, so disable
605 // it at the moment. Fix the crash and enable it. 606 // it at the moment. Fix the crash and enable it.
606 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl inkGC::TakeSnapshot, BlinkGC::ForcedGC); 607 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl inkGC::TakeSnapshot, BlinkGC::ForcedGC);
607 preciselyCollectGarbage(); 608 preciselyCollectGarbage();
608 EXPECT_TRUE(weakMap->isEmpty()); 609 EXPECT_TRUE(weakMap->isEmpty());
609 EXPECT_TRUE(weakMap2.isEmpty()); 610 EXPECT_TRUE(weakMap2.isEmpty());
610 } 611 }
611 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 612 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
612 testing::yieldCurrentThread(); 613 testing::yieldCurrentThread();
613 } 614 }
614 ThreadState::detach(); 615 ThreadState::detachCurrentThread();
615 atomicDecrement(&m_threadsToFinish); 616 atomicDecrement(&m_threadsToFinish);
616 } 617 }
617 }; 618 };
618 619
619 class ThreadPersistentHeapTester : public ThreadedTesterBase { 620 class ThreadPersistentHeapTester : public ThreadedTesterBase {
620 public: 621 public:
621 static void test() 622 static void test()
622 { 623 {
623 ThreadedTesterBase::test(new ThreadPersistentHeapTester); 624 ThreadedTesterBase::test(new ThreadPersistentHeapTester);
624 } 625 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 void runThread() override 674 void runThread() override
674 { 675 {
675 ThreadState::attach(); 676 ThreadState::attach();
676 677
677 PersistentChain::create(100); 678 PersistentChain::create(100);
678 679
679 // Upon thread detach, GCs will run until all persistents have been 680 // Upon thread detach, GCs will run until all persistents have been
680 // released. We verify that the draining of persistents proceeds 681 // released. We verify that the draining of persistents proceeds
681 // as expected by dropping one Persistent<> per GC until there 682 // as expected by dropping one Persistent<> per GC until there
682 // are none left. 683 // are none left.
683 ThreadState::detach(); 684 ThreadState::detachCurrentThread();
684 atomicDecrement(&m_threadsToFinish); 685 atomicDecrement(&m_threadsToFinish);
685 } 686 }
686 }; 687 };
687 688
688 // The accounting for memory includes the memory used by rounding up object 689 // The accounting for memory includes the memory used by rounding up object
689 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to 690 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
690 // have some slack in the tests. 691 // have some slack in the tests.
691 template<typename T> 692 template<typename T>
692 void CheckWithSlack(T expected, T actual, int slack) 693 void CheckWithSlack(T expected, T actual, int slack)
693 { 694 {
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 ThreadedWeaknessTester::test(); 1760 ThreadedWeaknessTester::test();
1760 } 1761 }
1761 1762
1762 TEST(HeapTest, ThreadPersistent) 1763 TEST(HeapTest, ThreadPersistent)
1763 { 1764 {
1764 ThreadPersistentHeapTester::test(); 1765 ThreadPersistentHeapTester::test();
1765 } 1766 }
1766 1767
1767 TEST(HeapTest, BasicFunctionality) 1768 TEST(HeapTest, BasicFunctionality)
1768 { 1769 {
1770 ThreadHeap& heap = ThreadState::current()->heap();
1769 clearOutOldGarbage(); 1771 clearOutOldGarbage();
1770 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 1772 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
1771 { 1773 {
1772 size_t slack = 0; 1774 size_t slack = 0;
1773 1775
1774 // When the test starts there may already have been leaked some memory 1776 // When the test starts there may already have been leaked some memory
1775 // on the heap, so we establish a base line. 1777 // on the heap, so we establish a base line.
1776 size_t baseLevel = initialObjectPayloadSize; 1778 size_t baseLevel = initialObjectPayloadSize;
1777 bool testPagesAllocated = !baseLevel; 1779 bool testPagesAllocated = !baseLevel;
1778 if (testPagesAllocated) 1780 if (testPagesAllocated)
1779 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); 1781 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1780 1782
1781 // This allocates objects on the general heap which should add a page of memory. 1783 // This allocates objects on the general heap which should add a page of memory.
1782 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); 1784 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32);
1783 slack += 4; 1785 slack += 4;
1784 memset(alloc32, 40, 32); 1786 memset(alloc32, 40, 32);
1785 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); 1787 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64);
1786 slack += 4; 1788 slack += 4;
1787 memset(alloc64, 27, 64); 1789 memset(alloc64, 27, 64);
1788 1790
1789 size_t total = 96; 1791 size_t total = 96;
1790 1792
1791 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1793 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1792 if (testPagesAllocated) 1794 if (testPagesAllocated)
1793 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), blinkPageSize * 2); 1795 EXPECT_EQ(heap.heapStats().allocatedSpace(), blinkPageSize * 2);
1794 1796
1795 EXPECT_EQ(alloc32->get(0), 40); 1797 EXPECT_EQ(alloc32->get(0), 40);
1796 EXPECT_EQ(alloc32->get(31), 40); 1798 EXPECT_EQ(alloc32->get(31), 40);
1797 EXPECT_EQ(alloc64->get(0), 27); 1799 EXPECT_EQ(alloc64->get(0), 27);
1798 EXPECT_EQ(alloc64->get(63), 27); 1800 EXPECT_EQ(alloc64->get(63), 27);
1799 1801
1800 conservativelyCollectGarbage(); 1802 conservativelyCollectGarbage();
1801 1803
1802 EXPECT_EQ(alloc32->get(0), 40); 1804 EXPECT_EQ(alloc32->get(0), 40);
1803 EXPECT_EQ(alloc32->get(31), 40); 1805 EXPECT_EQ(alloc32->get(31), 40);
1804 EXPECT_EQ(alloc64->get(0), 27); 1806 EXPECT_EQ(alloc64->get(0), 27);
1805 EXPECT_EQ(alloc64->get(63), 27); 1807 EXPECT_EQ(alloc64->get(63), 27);
1806 } 1808 }
1807 1809
1808 clearOutOldGarbage(); 1810 clearOutOldGarbage();
1809 size_t total = 0; 1811 size_t total = 0;
1810 size_t slack = 0; 1812 size_t slack = 0;
1811 size_t baseLevel = ThreadHeap::objectPayloadSizeForTesting(); 1813 size_t baseLevel = heap.objectPayloadSizeForTesting();
1812 bool testPagesAllocated = !baseLevel; 1814 bool testPagesAllocated = !baseLevel;
1813 if (testPagesAllocated) 1815 if (testPagesAllocated)
1814 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); 1816 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1815 1817
1816 size_t big = 1008; 1818 size_t big = 1008;
1817 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big); 1819 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big);
1818 total += big; 1820 total += big;
1819 slack += 4; 1821 slack += 4;
1820 1822
1821 size_t persistentCount = 0; 1823 size_t persistentCount = 0;
1822 const size_t numPersistents = 100000; 1824 const size_t numPersistents = 100000;
1823 Persistent<DynamicallySizedObject>* persistents[numPersistents]; 1825 Persistent<DynamicallySizedObject>* persistents[numPersistents];
1824 1826
1825 for (int i = 0; i < 1000; i++) { 1827 for (int i = 0; i < 1000; i++) {
1826 size_t size = 128 + i * 8; 1828 size_t size = 128 + i * 8;
1827 total += size; 1829 total += size;
1828 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size)); 1830 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size));
1829 slack += 4; 1831 slack += 4;
1830 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1832 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1831 if (testPagesAllocated) 1833 if (testPagesAllocated)
1832 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage Size - 1)); 1834 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1833 } 1835 }
1834 1836
1835 { 1837 {
1836 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); 1838 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32));
1837 slack += 4; 1839 slack += 4;
1838 memset(alloc32b, 40, 32); 1840 memset(alloc32b, 40, 32);
1839 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); 1841 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64));
1840 slack += 4; 1842 slack += 4;
1841 memset(alloc64b, 27, 64); 1843 memset(alloc64b, 27, 64);
1842 EXPECT_TRUE(alloc32b != alloc64b); 1844 EXPECT_TRUE(alloc32b != alloc64b);
1843 1845
1844 total += 96; 1846 total += 96;
1845 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1847 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1846 if (testPagesAllocated) 1848 if (testPagesAllocated)
1847 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage Size - 1)); 1849 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1848 } 1850 }
1849 1851
1850 clearOutOldGarbage(); 1852 clearOutOldGarbage();
1851 total -= 96; 1853 total -= 96;
1852 slack -= 8; 1854 slack -= 8;
1853 if (testPagesAllocated) 1855 if (testPagesAllocated)
1854 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1856 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1855 1857
1856 // Clear the persistent, so that the big area will be garbage collected. 1858 // Clear the persistent, so that the big area will be garbage collected.
1857 bigArea.release(); 1859 bigArea.release();
1858 clearOutOldGarbage(); 1860 clearOutOldGarbage();
1859 1861
1860 total -= big; 1862 total -= big;
1861 slack -= 4; 1863 slack -= 4;
1862 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(), slack); 1864 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1863 if (testPagesAllocated) 1865 if (testPagesAllocated)
1864 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1866 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1865 1867
1866 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(), slack); 1868 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1867 if (testPagesAllocated) 1869 if (testPagesAllocated)
1868 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1870 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1869 1871
1870 for (size_t i = 0; i < persistentCount; i++) { 1872 for (size_t i = 0; i < persistentCount; i++) {
1871 delete persistents[i]; 1873 delete persistents[i];
1872 persistents[i] = 0; 1874 persistents[i] = 0;
1873 } 1875 }
1874 1876
1875 uint8_t* address = reinterpret_cast<uint8_t*>(ThreadHeap::allocate<Dynamical lySizedObject>(100)); 1877 uint8_t* address = reinterpret_cast<uint8_t*>(ThreadHeap::allocate<Dynamical lySizedObject>(100));
1876 for (int i = 0; i < 100; i++) 1878 for (int i = 0; i < 100; i++)
1877 address[i] = i; 1879 address[i] = i;
1878 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 100000)); 1880 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 100000));
1879 for (int i = 0; i < 100; i++) 1881 for (int i = 0; i < 100; i++)
1880 EXPECT_EQ(address[i], i); 1882 EXPECT_EQ(address[i], i);
1881 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 50)); 1883 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 50));
1882 for (int i = 0; i < 50; i++) 1884 for (int i = 0; i < 50; i++)
1883 EXPECT_EQ(address[i], i); 1885 EXPECT_EQ(address[i], i);
1884 // This should be equivalent to free(address). 1886 // This should be equivalent to free(address).
1885 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(address, 0)), 0ul); 1887 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(address, 0)), 0ul);
1886 // This should be equivalent to malloc(0). 1888 // This should be equivalent to malloc(0).
1887 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(0, 0)), 0ul); 1889 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(0, 0)), 0ul);
1888 } 1890 }
1889 1891
1890 TEST(HeapTest, SimpleAllocation) 1892 TEST(HeapTest, SimpleAllocation)
1891 { 1893 {
1894 ThreadHeap& heap = ThreadState::current()->heap();
1892 clearOutOldGarbage(); 1895 clearOutOldGarbage();
1893 EXPECT_EQ(0ul, ThreadHeap::objectPayloadSizeForTesting()); 1896 EXPECT_EQ(0ul, heap.objectPayloadSizeForTesting());
1894 1897
1895 // Allocate an object in the heap. 1898 // Allocate an object in the heap.
1896 HeapAllocatedArray* array = new HeapAllocatedArray(); 1899 HeapAllocatedArray* array = new HeapAllocatedArray();
1897 EXPECT_TRUE(ThreadHeap::objectPayloadSizeForTesting() >= sizeof(HeapAllocate dArray)); 1900 EXPECT_TRUE(heap.objectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray) );
1898 1901
1899 // Sanity check of the contents in the heap. 1902 // Sanity check of the contents in the heap.
1900 EXPECT_EQ(0, array->at(0)); 1903 EXPECT_EQ(0, array->at(0));
1901 EXPECT_EQ(42, array->at(42)); 1904 EXPECT_EQ(42, array->at(42));
1902 EXPECT_EQ(0, array->at(128)); 1905 EXPECT_EQ(0, array->at(128));
1903 EXPECT_EQ(999 % 128, array->at(999)); 1906 EXPECT_EQ(999 % 128, array->at(999));
1904 } 1907 }
1905 1908
1906 TEST(HeapTest, SimplePersistent) 1909 TEST(HeapTest, SimplePersistent)
1907 { 1910 {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 // for the conservative stack scan to find. 2218 // for the conservative stack scan to find.
2216 EXPECT_EQ(width, bars->getWidth()); 2219 EXPECT_EQ(width, bars->getWidth());
2217 } 2220 }
2218 EXPECT_EQ(Bars::width + 1, Bar::s_live); 2221 EXPECT_EQ(Bars::width + 1, Bar::s_live);
2219 preciselyCollectGarbage(); 2222 preciselyCollectGarbage();
2220 EXPECT_EQ(0u, Bar::s_live); 2223 EXPECT_EQ(0u, Bar::s_live);
2221 } 2224 }
2222 2225
2223 TEST(HeapTest, HashMapOfMembers) 2226 TEST(HeapTest, HashMapOfMembers)
2224 { 2227 {
2228 ThreadHeap& heap = ThreadState::current()->heap();
2225 IntWrapper::s_destructorCalls = 0; 2229 IntWrapper::s_destructorCalls = 0;
2226 2230
2227 clearOutOldGarbage(); 2231 clearOutOldGarbage();
2228 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2232 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2229 { 2233 {
2230 typedef HeapHashMap< 2234 typedef HeapHashMap<
2231 Member<IntWrapper>, 2235 Member<IntWrapper>,
2232 Member<IntWrapper>, 2236 Member<IntWrapper>,
2233 DefaultHash<Member<IntWrapper>>::Hash, 2237 DefaultHash<Member<IntWrapper>>::Hash,
2234 HashTraits<Member<IntWrapper>>, 2238 HashTraits<Member<IntWrapper>>,
2235 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; 2239 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap;
2236 2240
2237 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); 2241 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap();
2238 2242
2239 map->clear(); 2243 map->clear();
2240 size_t afterSetWasCreated = ThreadHeap::objectPayloadSizeForTesting(); 2244 size_t afterSetWasCreated = heap.objectPayloadSizeForTesting();
2241 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); 2245 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize);
2242 2246
2243 preciselyCollectGarbage(); 2247 preciselyCollectGarbage();
2244 size_t afterGC = ThreadHeap::objectPayloadSizeForTesting(); 2248 size_t afterGC = heap.objectPayloadSizeForTesting();
2245 EXPECT_EQ(afterGC, afterSetWasCreated); 2249 EXPECT_EQ(afterGC, afterSetWasCreated);
2246 2250
2247 // If the additions below cause garbage collections, these 2251 // If the additions below cause garbage collections, these
2248 // pointers should be found by conservative stack scanning. 2252 // pointers should be found by conservative stack scanning.
2249 IntWrapper* one(IntWrapper::create(1)); 2253 IntWrapper* one(IntWrapper::create(1));
2250 IntWrapper* anotherOne(IntWrapper::create(1)); 2254 IntWrapper* anotherOne(IntWrapper::create(1));
2251 2255
2252 map->add(one, one); 2256 map->add(one, one);
2253 2257
2254 size_t afterOneAdd = ThreadHeap::objectPayloadSizeForTesting(); 2258 size_t afterOneAdd = heap.objectPayloadSizeForTesting();
2255 EXPECT_TRUE(afterOneAdd > afterGC); 2259 EXPECT_TRUE(afterOneAdd > afterGC);
2256 2260
2257 HeapObjectIdentityMap::iterator it(map->begin()); 2261 HeapObjectIdentityMap::iterator it(map->begin());
2258 HeapObjectIdentityMap::iterator it2(map->begin()); 2262 HeapObjectIdentityMap::iterator it2(map->begin());
2259 ++it; 2263 ++it;
2260 ++it2; 2264 ++it2;
2261 2265
2262 map->add(anotherOne, one); 2266 map->add(anotherOne, one);
2263 2267
2264 // The addition above can cause an allocation of a new 2268 // The addition above can cause an allocation of a new
2265 // backing store. We therefore garbage collect before 2269 // backing store. We therefore garbage collect before
2266 // taking the heap stats in order to get rid of the old 2270 // taking the heap stats in order to get rid of the old
2267 // backing store. We make sure to not use conservative 2271 // backing store. We make sure to not use conservative
2268 // stack scanning as that could find a pointer to the 2272 // stack scanning as that could find a pointer to the
2269 // old backing. 2273 // old backing.
2270 preciselyCollectGarbage(); 2274 preciselyCollectGarbage();
2271 size_t afterAddAndGC = ThreadHeap::objectPayloadSizeForTesting(); 2275 size_t afterAddAndGC = heap.objectPayloadSizeForTesting();
2272 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); 2276 EXPECT_TRUE(afterAddAndGC >= afterOneAdd);
2273 2277
2274 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct. 2278 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct.
2275 2279
2276 preciselyCollectGarbage(); 2280 preciselyCollectGarbage();
2277 EXPECT_TRUE(map->contains(one)); 2281 EXPECT_TRUE(map->contains(one));
2278 EXPECT_TRUE(map->contains(anotherOne)); 2282 EXPECT_TRUE(map->contains(anotherOne));
2279 2283
2280 IntWrapper* gotten(map->get(one)); 2284 IntWrapper* gotten(map->get(one));
2281 EXPECT_EQ(gotten->value(), one->value()); 2285 EXPECT_EQ(gotten->value(), one->value());
2282 EXPECT_EQ(gotten, one); 2286 EXPECT_EQ(gotten, one);
2283 2287
2284 size_t afterGC2 = ThreadHeap::objectPayloadSizeForTesting(); 2288 size_t afterGC2 = heap.objectPayloadSizeForTesting();
2285 EXPECT_EQ(afterGC2, afterAddAndGC); 2289 EXPECT_EQ(afterGC2, afterAddAndGC);
2286 2290
2287 IntWrapper* dozen = 0; 2291 IntWrapper* dozen = 0;
2288 2292
2289 for (int i = 1; i < 1000; i++) { // 999 iterations. 2293 for (int i = 1; i < 1000; i++) { // 999 iterations.
2290 IntWrapper* iWrapper(IntWrapper::create(i)); 2294 IntWrapper* iWrapper(IntWrapper::create(i));
2291 IntWrapper* iSquared(IntWrapper::create(i * i)); 2295 IntWrapper* iSquared(IntWrapper::create(i * i));
2292 map->add(iWrapper, iSquared); 2296 map->add(iWrapper, iSquared);
2293 if (i == 12) 2297 if (i == 12)
2294 dozen = iWrapper; 2298 dozen = iWrapper;
2295 } 2299 }
2296 size_t afterAdding1000 = ThreadHeap::objectPayloadSizeForTesting(); 2300 size_t afterAdding1000 = heap.objectPayloadSizeForTesting();
2297 EXPECT_TRUE(afterAdding1000 > afterGC2); 2301 EXPECT_TRUE(afterAdding1000 > afterGC2);
2298 2302
2299 IntWrapper* gross(map->get(dozen)); 2303 IntWrapper* gross(map->get(dozen));
2300 EXPECT_EQ(gross->value(), 144); 2304 EXPECT_EQ(gross->value(), 144);
2301 2305
2302 // This should clear out any junk backings created by all the adds. 2306 // This should clear out any junk backings created by all the adds.
2303 preciselyCollectGarbage(); 2307 preciselyCollectGarbage();
2304 size_t afterGC3 = ThreadHeap::objectPayloadSizeForTesting(); 2308 size_t afterGC3 = heap.objectPayloadSizeForTesting();
2305 EXPECT_TRUE(afterGC3 <= afterAdding1000); 2309 EXPECT_TRUE(afterGC3 <= afterAdding1000);
2306 } 2310 }
2307 2311
2308 preciselyCollectGarbage(); 2312 preciselyCollectGarbage();
2309 // The objects 'one', anotherOne, and the 999 other pairs. 2313 // The objects 'one', anotherOne, and the 999 other pairs.
2310 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); 2314 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
2311 size_t afterGC4 = ThreadHeap::objectPayloadSizeForTesting(); 2315 size_t afterGC4 = heap.objectPayloadSizeForTesting();
2312 EXPECT_EQ(afterGC4, initialObjectPayloadSize); 2316 EXPECT_EQ(afterGC4, initialObjectPayloadSize);
2313 } 2317 }
2314 2318
2315 TEST(HeapTest, NestedAllocation) 2319 TEST(HeapTest, NestedAllocation)
2316 { 2320 {
2321 ThreadHeap& heap = ThreadState::current()->heap();
2317 clearOutOldGarbage(); 2322 clearOutOldGarbage();
2318 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2323 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2319 { 2324 {
2320 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create(); 2325 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create();
2321 } 2326 }
2322 clearOutOldGarbage(); 2327 clearOutOldGarbage();
2323 size_t afterFree = ThreadHeap::objectPayloadSizeForTesting(); 2328 size_t afterFree = heap.objectPayloadSizeForTesting();
2324 EXPECT_TRUE(initialObjectPayloadSize == afterFree); 2329 EXPECT_TRUE(initialObjectPayloadSize == afterFree);
2325 } 2330 }
2326 2331
2327 TEST(HeapTest, LargeHeapObjects) 2332 TEST(HeapTest, LargeHeapObjects)
2328 { 2333 {
2334 ThreadHeap& heap = ThreadState::current()->heap();
2329 clearOutOldGarbage(); 2335 clearOutOldGarbage();
2330 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2336 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2331 size_t initialAllocatedSpace = ThreadHeap::heapStats().allocatedSpace(); 2337 size_t initialAllocatedSpace = heap.heapStats().allocatedSpace();
2332 IntWrapper::s_destructorCalls = 0; 2338 IntWrapper::s_destructorCalls = 0;
2333 LargeHeapObject::s_destructorCalls = 0; 2339 LargeHeapObject::s_destructorCalls = 0;
2334 { 2340 {
2335 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated. 2341 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated.
2336 Persistent<LargeHeapObject> object = LargeHeapObject::create(); 2342 Persistent<LargeHeapObject> object = LargeHeapObject::create();
2337 ASSERT(ThreadState::current()->findPageFromAddress(object)); 2343 ASSERT(ThreadState::current()->findPageFromAddress(object));
2338 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1)); 2344 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1));
2339 clearOutOldGarbage(); 2345 clearOutOldGarbage();
2340 size_t afterAllocation = ThreadHeap::heapStats().allocatedSpace(); 2346 size_t afterAllocation = heap.heapStats().allocatedSpace();
2341 { 2347 {
2342 object->set(0, 'a'); 2348 object->set(0, 'a');
2343 EXPECT_EQ('a', object->get(0)); 2349 EXPECT_EQ('a', object->get(0));
2344 object->set(object->length() - 1, 'b'); 2350 object->set(object->length() - 1, 'b');
2345 EXPECT_EQ('b', object->get(object->length() - 1)); 2351 EXPECT_EQ('b', object->get(object->length() - 1));
2346 size_t expectedLargeHeapObjectPayloadSize = ThreadHeap::allocationSi zeFromSize(sizeof(LargeHeapObject)); 2352 size_t expectedLargeHeapObjectPayloadSize = ThreadHeap::allocationSi zeFromSize(sizeof(LargeHeapObject));
2347 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper); 2353 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper);
2348 size_t actualObjectPayloadSize = ThreadHeap::objectPayloadSizeForTes ting() - initialObjectPayloadSize; 2354 size_t actualObjectPayloadSize = heap.objectPayloadSizeForTesting() - initialObjectPayloadSize;
2349 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack); 2355 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack);
2350 // There is probably space for the IntWrapper in a heap page without 2356 // There is probably space for the IntWrapper in a heap page without
2351 // allocating extra pages. However, the IntWrapper allocation might cause 2357 // allocating extra pages. However, the IntWrapper allocation might cause
2352 // the addition of a heap page. 2358 // the addition of a heap page.
2353 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize; 2359 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize;
2354 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize; 2360 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize;
2355 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize; 2361 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
2356 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); 2362 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation);
2357 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); 2363 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound);
2358 EXPECT_EQ(0, IntWrapper::s_destructorCalls); 2364 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
2359 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); 2365 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls);
2360 for (int i = 0; i < 10; i++) 2366 for (int i = 0; i < 10; i++)
2361 object = LargeHeapObject::create(); 2367 object = LargeHeapObject::create();
2362 } 2368 }
2363 clearOutOldGarbage(); 2369 clearOutOldGarbage();
2364 EXPECT_TRUE(ThreadHeap::heapStats().allocatedSpace() == afterAllocation) ; 2370 EXPECT_TRUE(heap.heapStats().allocatedSpace() == afterAllocation);
2365 EXPECT_EQ(10, IntWrapper::s_destructorCalls); 2371 EXPECT_EQ(10, IntWrapper::s_destructorCalls);
2366 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); 2372 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls);
2367 } 2373 }
2368 clearOutOldGarbage(); 2374 clearOutOldGarbage();
2369 EXPECT_TRUE(initialObjectPayloadSize == ThreadHeap::objectPayloadSizeForTest ing()); 2375 EXPECT_TRUE(initialObjectPayloadSize == heap.objectPayloadSizeForTesting());
2370 EXPECT_TRUE(initialAllocatedSpace == ThreadHeap::heapStats().allocatedSpace( )); 2376 EXPECT_TRUE(initialAllocatedSpace == heap.heapStats().allocatedSpace());
2371 EXPECT_EQ(11, IntWrapper::s_destructorCalls); 2377 EXPECT_EQ(11, IntWrapper::s_destructorCalls);
2372 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); 2378 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls);
2373 preciselyCollectGarbage(); 2379 preciselyCollectGarbage();
2374 } 2380 }
2375 2381
2376 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; 2382 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
2377 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; 2383 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped;
2378 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; 2384 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong;
2379 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; 2385 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak;
2380 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; 2386 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
3749 { 3755 {
3750 Persistent<Bar> barPersistent = Bar::create(); 3756 Persistent<Bar> barPersistent = Bar::create();
3751 Persistent<Foo> fooPersistent = Foo::create(barPersistent); 3757 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
3752 EXPECT_TRUE(barPersistent != fooPersistent); 3758 EXPECT_TRUE(barPersistent != fooPersistent);
3753 barPersistent = fooPersistent; 3759 barPersistent = fooPersistent;
3754 EXPECT_TRUE(barPersistent == fooPersistent); 3760 EXPECT_TRUE(barPersistent == fooPersistent);
3755 } 3761 }
3756 3762
3757 TEST(HeapTest, CheckAndMarkPointer) 3763 TEST(HeapTest, CheckAndMarkPointer)
3758 { 3764 {
3765 ThreadHeap& heap = ThreadState::current()->heap();
3759 clearOutOldGarbage(); 3766 clearOutOldGarbage();
3760 3767
3761 Vector<Address> objectAddresses; 3768 Vector<Address> objectAddresses;
3762 Vector<Address> endAddresses; 3769 Vector<Address> endAddresses;
3763 Address largeObjectAddress; 3770 Address largeObjectAddress;
3764 Address largeObjectEndAddress; 3771 Address largeObjectEndAddress;
3765 for (int i = 0; i < 10; i++) { 3772 for (int i = 0; i < 10; i++) {
3766 SimpleObject* object = SimpleObject::create(); 3773 SimpleObject* object = SimpleObject::create();
3767 Address objectAddress = reinterpret_cast<Address>(object); 3774 Address objectAddress = reinterpret_cast<Address>(object);
3768 objectAddresses.append(objectAddress); 3775 objectAddresses.append(objectAddress);
3769 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1); 3776 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
3770 } 3777 }
3771 LargeHeapObject* largeObject = LargeHeapObject::create(); 3778 LargeHeapObject* largeObject = LargeHeapObject::create();
3772 largeObjectAddress = reinterpret_cast<Address>(largeObject); 3779 largeObjectAddress = reinterpret_cast<Address>(largeObject);
3773 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; 3780 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1;
3774 3781
3775 // 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
3776 // 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
3777 // 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
3778 // into a free list header). However when we call makeConsistentForGC it 3785 // into a free list header). However when we call makeConsistentForGC it
3779 // 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
3780 // 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
3781 // checkAndMarkPointer tests. 3788 // checkAndMarkPointer tests.
3782 { 3789 {
3783 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3790 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3784 CountingVisitor visitor(ThreadState::current()); 3791 CountingVisitor visitor(ThreadState::current());
3785 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads. 3792 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
3786 ThreadHeap::flushHeapDoesNotContainCache(); 3793 heap.flushHeapDoesNotContainCache();
3787 for (size_t i = 0; i < objectAddresses.size(); i++) { 3794 for (size_t i = 0; i < objectAddresses.size(); i++) {
3788 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, objectAddresse s[i])); 3795 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i]));
3789 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i ])); 3796 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i]));
3790 } 3797 }
3791 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); 3798 EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
3792 visitor.reset(); 3799 visitor.reset();
3793 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress )); 3800 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress));
3794 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddr ess)); 3801 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress));
3795 EXPECT_EQ(2ul, visitor.count()); 3802 EXPECT_EQ(2ul, visitor.count());
3796 visitor.reset(); 3803 visitor.reset();
3797 } 3804 }
3798 // This forces a GC without stack scanning which results in the objects 3805 // This forces a GC without stack scanning which results in the objects
3799 // being collected. This will also rebuild the above mentioned freelists, 3806 // being collected. This will also rebuild the above mentioned freelists,
3800 // however we don't rely on that below since we don't have any allocations. 3807 // however we don't rely on that below since we don't have any allocations.
3801 clearOutOldGarbage(); 3808 clearOutOldGarbage();
3802 { 3809 {
3803 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3810 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3804 CountingVisitor visitor(ThreadState::current()); 3811 CountingVisitor visitor(ThreadState::current());
3805 EXPECT_TRUE(scope.allThreadsParked()); 3812 EXPECT_TRUE(scope.allThreadsParked());
3806 ThreadHeap::flushHeapDoesNotContainCache(); 3813 heap.flushHeapDoesNotContainCache();
3807 for (size_t i = 0; i < objectAddresses.size(); i++) { 3814 for (size_t i = 0; i < objectAddresses.size(); i++) {
3808 // We would like to assert that checkAndMarkPointer returned false 3815 // We would like to assert that checkAndMarkPointer returned false
3809 // here because the pointers no longer point into a valid object 3816 // here because the pointers no longer point into a valid object
3810 // (it's been freed by the GCs. But checkAndMarkPointer will return 3817 // (it's been freed by the GCs. But checkAndMarkPointer will return
3811 // true for any pointer that points into a heap page, regardless of 3818 // true for any pointer that points into a heap page, regardless of
3812 // whether it points at a valid object (this ensures the 3819 // whether it points at a valid object (this ensures the
3813 // correctness of the page-based on-heap address caches), so we 3820 // correctness of the page-based on-heap address caches), so we
3814 // can't make that assert. 3821 // can't make that assert.
3815 ThreadHeap::checkAndMarkPointer(&visitor, objectAddresses[i]); 3822 heap.checkAndMarkPointer(&visitor, objectAddresses[i]);
3816 ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i]); 3823 heap.checkAndMarkPointer(&visitor, endAddresses[i]);
3817 } 3824 }
3818 EXPECT_EQ(0ul, visitor.count()); 3825 EXPECT_EQ(0ul, visitor.count());
3819 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress); 3826 heap.checkAndMarkPointer(&visitor, largeObjectAddress);
3820 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddress); 3827 heap.checkAndMarkPointer(&visitor, largeObjectEndAddress);
3821 EXPECT_EQ(0ul, visitor.count()); 3828 EXPECT_EQ(0ul, visitor.count());
3822 } 3829 }
3823 // This round of GC is important to make sure that the object start 3830 // This round of GC is important to make sure that the object start
3824 // bitmap are cleared out and that the free lists are rebuild. 3831 // bitmap are cleared out and that the free lists are rebuild.
3825 clearOutOldGarbage(); 3832 clearOutOldGarbage();
3826 } 3833 }
3827 3834
3828 TEST(HeapTest, PersistentHeapCollectionTypes) 3835 TEST(HeapTest, PersistentHeapCollectionTypes)
3829 { 3836 {
3830 IntWrapper::s_destructorCalls = 0; 3837 IntWrapper::s_destructorCalls = 0;
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
4724 static void sleeperMainFunc() 4731 static void sleeperMainFunc()
4725 { 4732 {
4726 ThreadState::attach(); 4733 ThreadState::attach();
4727 s_sleeperRunning = true; 4734 s_sleeperRunning = true;
4728 4735
4729 // Simulate a long running op that is not entering a safepoint. 4736 // Simulate a long running op that is not entering a safepoint.
4730 while (!s_sleeperDone) { 4737 while (!s_sleeperDone) {
4731 testing::yieldCurrentThread(); 4738 testing::yieldCurrentThread();
4732 } 4739 }
4733 4740
4734 ThreadState::detach(); 4741 ThreadState::detachCurrentThread();
4735 s_sleeperRunning = false; 4742 s_sleeperRunning = false;
4736 } 4743 }
4737 4744
4738 static volatile bool s_sleeperRunning; 4745 static volatile bool s_sleeperRunning;
4739 static volatile bool s_sleeperDone; 4746 static volatile bool s_sleeperDone;
4740 }; 4747 };
4741 4748
4742 volatile bool GCParkingThreadTester::s_sleeperRunning = false; 4749 volatile bool GCParkingThreadTester::s_sleeperRunning = false;
4743 volatile bool GCParkingThreadTester::s_sleeperDone = false; 4750 volatile bool GCParkingThreadTester::s_sleeperDone = false;
4744 4751
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
5430 5437
5431 // Wake up the main thread when done sweeping. 5438 // Wake up the main thread when done sweeping.
5432 wakeMainThread(); 5439 wakeMainThread();
5433 5440
5434 // Wait with detach until the main thread says so. This is not strictly 5441 // Wait with detach until the main thread says so. This is not strictly
5435 // necessary, but it means the worker thread will not do its thread loca l 5442 // necessary, but it means the worker thread will not do its thread loca l
5436 // GCs just yet, making it easier to reason about that no new GC has occ urred 5443 // GCs just yet, making it easier to reason about that no new GC has occ urred
5437 // and the above sweep was the one finalizing the worker object. 5444 // and the above sweep was the one finalizing the worker object.
5438 parkWorkerThread(); 5445 parkWorkerThread();
5439 5446
5440 ThreadState::detach(); 5447 ThreadState::detachCurrentThread();
5441 } 5448 }
5442 5449
5443 static volatile uintptr_t s_workerObjectPointer; 5450 static volatile uintptr_t s_workerObjectPointer;
5444 }; 5451 };
5445 5452
5446 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; 5453 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0;
5447 5454
5448 TEST(HeapTest, ObjectDeadBit) 5455 TEST(HeapTest, ObjectDeadBit)
5449 { 5456 {
5450 DeadBitTester::test(); 5457 DeadBitTester::test();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5543 EXPECT_EQ(32, it->value->value()); 5550 EXPECT_EQ(32, it->value->value());
5544 } 5551 }
5545 5552
5546 // Disregarding the iterator but keeping the collection alive 5553 // Disregarding the iterator but keeping the collection alive
5547 // with a persistent should lead to weak processing. 5554 // with a persistent should lead to weak processing.
5548 preciselyCollectGarbage(); 5555 preciselyCollectGarbage();
5549 EXPECT_EQ(0u, collection->size()); 5556 EXPECT_EQ(0u, collection->size());
5550 } 5557 }
5551 5558
5552 wakeMainThread(); 5559 wakeMainThread();
5553 ThreadState::detach(); 5560 ThreadState::detachCurrentThread();
5554 } 5561 }
5555 5562
5556 static volatile uintptr_t s_workerObjectPointer; 5563 static volatile uintptr_t s_workerObjectPointer;
5557 }; 5564 };
5558 5565
5559 TEST(HeapTest, ThreadedStrongification) 5566 TEST(HeapTest, ThreadedStrongification)
5560 { 5567 {
5561 ThreadedStrongificationTester::test(); 5568 ThreadedStrongificationTester::test();
5562 } 5569 }
5563 5570
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5711 parkWorkerThread(); 5718 parkWorkerThread();
5712 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack); 5719 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack);
5713 5720
5714 // We won't get here unless the lock is recursive since the sweep done 5721 // We won't get here unless the lock is recursive since the sweep done
5715 // in the constructor of SafePointAwareMutexLocker after 5722 // in the constructor of SafePointAwareMutexLocker after
5716 // getting the lock will not complete given the "dlo" destructor is 5723 // getting the lock will not complete given the "dlo" destructor is
5717 // waiting to get the same lock. 5724 // waiting to get the same lock.
5718 // Tell the main thread the worker has done its sweep. 5725 // Tell the main thread the worker has done its sweep.
5719 wakeMainThread(); 5726 wakeMainThread();
5720 5727
5721 ThreadState::detach(); 5728 ThreadState::detachCurrentThread();
5722 } 5729 }
5723 5730
5724 static volatile IntWrapper* s_workerObjectPointer; 5731 static volatile IntWrapper* s_workerObjectPointer;
5725 }; 5732 };
5726 5733
5727 TEST(HeapTest, RecursiveMutex) 5734 TEST(HeapTest, RecursiveMutex)
5728 { 5735 {
5729 RecursiveLockingTester::test(); 5736 RecursiveLockingTester::test();
5730 } 5737 }
5731 5738
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
6381 *object = DestructorLockingObject::create(); 6388 *object = DestructorLockingObject::create();
6382 wakeMainThread(); 6389 wakeMainThread();
6383 parkWorkerThread(); 6390 parkWorkerThread();
6384 6391
6385 // Step 4: Run a GC. 6392 // Step 4: Run a GC.
6386 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw eep, BlinkGC::ForcedGC); 6393 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw eep, BlinkGC::ForcedGC);
6387 wakeMainThread(); 6394 wakeMainThread();
6388 parkWorkerThread(); 6395 parkWorkerThread();
6389 6396
6390 // Step 6: Finish. 6397 // Step 6: Finish.
6391 ThreadState::detach(); 6398 ThreadState::detachCurrentThread();
6392 wakeMainThread(); 6399 wakeMainThread();
6393 } 6400 }
6394 6401
6395 } // anonymous namespace 6402 } // anonymous namespace
6396 6403
6397 TEST(HeapTest, CrossThreadWeakPersistent) 6404 TEST(HeapTest, CrossThreadWeakPersistent)
6398 { 6405 {
6399 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread, 6406 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread,
6400 // clear the reference in the worker thread, run a GC in the worker thread, and see if the 6407 // clear the reference in the worker thread, run a GC in the worker thread, and see if the
6401 // CrossThreadWeakPersistent is cleared. 6408 // CrossThreadWeakPersistent is cleared.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
6496 IntWrapper::s_destructorCalls = 0; 6503 IntWrapper::s_destructorCalls = 0;
6497 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); 6504 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester);
6498 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); 6505 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls);
6499 } 6506 }
6500 6507
6501 private: 6508 private:
6502 void runThread() override 6509 void runThread() override
6503 { 6510 {
6504 ThreadState::attach(); 6511 ThreadState::attach();
6505 EXPECT_EQ(42, threadSpecificIntWrapper().value()); 6512 EXPECT_EQ(42, threadSpecificIntWrapper().value());
6506 ThreadState::detach(); 6513 ThreadState::detachCurrentThread();
6507 atomicDecrement(&m_threadsToFinish); 6514 atomicDecrement(&m_threadsToFinish);
6508 } 6515 }
6509 6516
6510 static IntWrapper& threadSpecificIntWrapper() 6517 static IntWrapper& threadSpecificIntWrapper()
6511 { 6518 {
6512 DEFINE_THREAD_SAFE_STATIC_LOCAL( 6519 DEFINE_THREAD_SAFE_STATIC_LOCAL(
6513 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, 6520 ThreadSpecific<Persistent<IntWrapper>>, intWrapper,
6514 new ThreadSpecific<Persistent<IntWrapper>>); 6521 new ThreadSpecific<Persistent<IntWrapper>>);
6515 Persistent<IntWrapper>& handle = *intWrapper; 6522 Persistent<IntWrapper>& handle = *intWrapper;
6516 if (!handle) { 6523 if (!handle) {
6517 handle = new IntWrapper(42); 6524 handle = new IntWrapper(42);
6518 handle.clearOnThreadShutdown(); 6525 handle.clearOnThreadShutdown();
6519 } 6526 }
6520 return *handle; 6527 return *handle;
6521 } 6528 }
6522 }; 6529 };
6523 6530
6524 } // namespace 6531 } // namespace
6525 6532
6526 TEST(HeapTest, TestClearOnShutdown) 6533 TEST(HeapTest, TestClearOnShutdown)
6527 { 6534 {
6528 ThreadedClearOnShutdownTester::test(); 6535 ThreadedClearOnShutdownTester::test();
6529 } 6536 }
6530 6537
6531 } // namespace blink 6538 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698