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

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: Rebase Created 4 years, 7 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 namespace blink { 242 namespace blink {
243 243
244 class TestGCScope { 244 class TestGCScope {
245 public: 245 public:
246 explicit TestGCScope(BlinkGC::StackState state) 246 explicit TestGCScope(BlinkGC::StackState state)
247 : m_state(ThreadState::current()) 247 : m_state(ThreadState::current())
248 , m_safePointScope(state) 248 , m_safePointScope(state)
249 , m_parkedAllThreads(false) 249 , m_parkedAllThreads(false)
250 { 250 {
251 ASSERT(m_state->checkThread()); 251 ASSERT(m_state->checkThread());
252 if (LIKELY(ThreadState::stopThreads())) { 252 if (LIKELY(m_state->heap().park())) {
253 ThreadHeap::preGC(); 253 m_state->heap().preGC();
254 m_parkedAllThreads = true; 254 m_parkedAllThreads = true;
255 } 255 }
256 } 256 }
257 257
258 bool allThreadsParked() { return m_parkedAllThreads; } 258 bool allThreadsParked() { return m_parkedAllThreads; }
259 259
260 ~TestGCScope() 260 ~TestGCScope()
261 { 261 {
262 // Only cleanup if we parked all threads in which case the GC happened 262 // Only cleanup if we parked all threads in which case the GC happened
263 // and we need to resume the other threads. 263 // and we need to resume the other threads.
264 if (LIKELY(m_parkedAllThreads)) { 264 if (LIKELY(m_parkedAllThreads)) {
265 ThreadHeap::postGC(BlinkGC::GCWithSweep); 265 m_state->heap().postGC(BlinkGC::GCWithSweep);
266 ThreadState::resumeThreads(); 266 m_state->heap().resume();
267 } 267 }
268 } 268 }
269 269
270 private: 270 private:
271 ThreadState* m_state; 271 ThreadState* m_state;
272 SafePointScope m_safePointScope; 272 SafePointScope m_safePointScope;
273 bool m_parkedAllThreads; // False if we fail to park all threads 273 bool m_parkedAllThreads; // False if we fail to park all threads
274 }; 274 };
275 275
276 #define DEFINE_VISITOR_METHODS(Type) \ 276 #define DEFINE_VISITOR_METHODS(Type) \
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 DEFINE_INLINE_TRACE() { } 412 DEFINE_INLINE_TRACE() { }
413 private: 413 private:
414 static const int s_arraySize = 1000; 414 static const int s_arraySize = 1000;
415 int8_t m_array[s_arraySize]; 415 int8_t m_array[s_arraySize];
416 }; 416 };
417 417
418 // Do several GCs to make sure that later GCs don't free up old memory from 418 // Do several GCs to make sure that later GCs don't free up old memory from
419 // previously run tests in this process. 419 // previously run tests in this process.
420 static void clearOutOldGarbage() 420 static void clearOutOldGarbage()
421 { 421 {
422 ThreadHeap& heap = ThreadState::current()->heap();
422 while (true) { 423 while (true) {
423 size_t used = ThreadHeap::objectPayloadSizeForTesting(); 424 size_t used = heap.objectPayloadSizeForTesting();
424 preciselyCollectGarbage(); 425 preciselyCollectGarbage();
425 if (ThreadHeap::objectPayloadSizeForTesting() >= used) 426 if (heap.objectPayloadSizeForTesting() >= used)
426 break; 427 break;
427 } 428 }
428 } 429 }
429 430
430 class OffHeapInt : public RefCounted<OffHeapInt> { 431 class OffHeapInt : public RefCounted<OffHeapInt> {
431 public: 432 public:
432 static RefPtr<OffHeapInt> create(int x) 433 static RefPtr<OffHeapInt> create(int x)
433 { 434 {
434 return adoptRef(new OffHeapInt(x)); 435 return adoptRef(new OffHeapInt(x));
435 } 436 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; 518 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>;
518 519
519 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) 520 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value)
520 { 521 {
521 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value) )); 522 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value) ));
522 } 523 }
523 524
524 void runThread() override 525 void runThread() override
525 { 526 {
526 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; 527 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent;
527 ThreadState::attach(); 528 ThreadState::attachCurrentThread();
528 529
529 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); 530 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a);
530 int gcCount = 0; 531 int gcCount = 0;
531 while (!done()) { 532 while (!done()) {
532 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); 533 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack);
533 { 534 {
534 Persistent<IntWrapper> wrapper; 535 Persistent<IntWrapper> wrapper;
535 536
536 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob alPersistent(0x0ed0cabb); 537 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob alPersistent(0x0ed0cabb);
537 538
(...skipping 23 matching lines...) Expand all
561 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 562 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
562 testing::yieldCurrentThread(); 563 testing::yieldCurrentThread();
563 } 564 }
564 565
565 // Intentionally leak the cross-thread persistent so as to verify 566 // Intentionally leak the cross-thread persistent so as to verify
566 // that later GCs correctly handle cross-thread persistents that 567 // that later GCs correctly handle cross-thread persistents that
567 // refer to finalized objects after their heaps have been detached 568 // refer to finalized objects after their heaps have been detached
568 // and freed. 569 // and freed.
569 EXPECT_TRUE(longLivingPersistent.leakPtr()); 570 EXPECT_TRUE(longLivingPersistent.leakPtr());
570 571
571 ThreadState::detach(); 572 ThreadState::detachCurrentThread();
572 atomicDecrement(&m_threadsToFinish); 573 atomicDecrement(&m_threadsToFinish);
573 } 574 }
574 }; 575 };
575 576
576 class ThreadedWeaknessTester : public ThreadedTesterBase { 577 class ThreadedWeaknessTester : public ThreadedTesterBase {
577 public: 578 public:
578 static void test() 579 static void test()
579 { 580 {
580 ThreadedTesterBase::test(new ThreadedWeaknessTester); 581 ThreadedTesterBase::test(new ThreadedWeaknessTester);
581 } 582 }
582 583
583 private: 584 private:
584 void runThread() override 585 void runThread() override
585 { 586 {
586 ThreadState::attach(); 587 ThreadState::attachCurrentThread();
587 588
588 int gcCount = 0; 589 int gcCount = 0;
589 while (!done()) { 590 while (!done()) {
590 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); 591 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack);
591 { 592 {
592 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; 593 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>;
593 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak Map2; 594 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak Map2;
594 595
595 for (int i = 0; i < numberOfAllocations; i++) { 596 for (int i = 0; i < numberOfAllocations; i++) {
596 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0) ); 597 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0) );
(...skipping 12 matching lines...) Expand all
609 // TODO(haraken): This snapshot GC causes crashes, so disable 610 // TODO(haraken): This snapshot GC causes crashes, so disable
610 // it at the moment. Fix the crash and enable it. 611 // it at the moment. Fix the crash and enable it.
611 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl inkGC::TakeSnapshot, BlinkGC::ForcedGC); 612 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl inkGC::TakeSnapshot, BlinkGC::ForcedGC);
612 preciselyCollectGarbage(); 613 preciselyCollectGarbage();
613 EXPECT_TRUE(weakMap->isEmpty()); 614 EXPECT_TRUE(weakMap->isEmpty());
614 EXPECT_TRUE(weakMap2.isEmpty()); 615 EXPECT_TRUE(weakMap2.isEmpty());
615 } 616 }
616 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 617 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
617 testing::yieldCurrentThread(); 618 testing::yieldCurrentThread();
618 } 619 }
619 ThreadState::detach(); 620 ThreadState::detachCurrentThread();
620 atomicDecrement(&m_threadsToFinish); 621 atomicDecrement(&m_threadsToFinish);
621 } 622 }
622 }; 623 };
623 624
624 class ThreadPersistentHeapTester : public ThreadedTesterBase { 625 class ThreadPersistentHeapTester : public ThreadedTesterBase {
625 public: 626 public:
626 static void test() 627 static void test()
627 { 628 {
628 ThreadedTesterBase::test(new ThreadPersistentHeapTester); 629 ThreadedTesterBase::test(new ThreadPersistentHeapTester);
629 } 630 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 explicit PersistentChain(int count) 671 explicit PersistentChain(int count)
671 { 672 {
672 m_refCountedChain = adoptRef(RefCountedChain::create(count)); 673 m_refCountedChain = adoptRef(RefCountedChain::create(count));
673 } 674 }
674 675
675 RefPtr<RefCountedChain> m_refCountedChain; 676 RefPtr<RefCountedChain> m_refCountedChain;
676 }; 677 };
677 678
678 void runThread() override 679 void runThread() override
679 { 680 {
680 ThreadState::attach(); 681 ThreadState::attachCurrentThread();
681 682
682 PersistentChain::create(100); 683 PersistentChain::create(100);
683 684
684 // Upon thread detach, GCs will run until all persistents have been 685 // Upon thread detach, GCs will run until all persistents have been
685 // released. We verify that the draining of persistents proceeds 686 // released. We verify that the draining of persistents proceeds
686 // as expected by dropping one Persistent<> per GC until there 687 // as expected by dropping one Persistent<> per GC until there
687 // are none left. 688 // are none left.
688 ThreadState::detach(); 689 ThreadState::detachCurrentThread();
689 atomicDecrement(&m_threadsToFinish); 690 atomicDecrement(&m_threadsToFinish);
690 } 691 }
691 }; 692 };
692 693
693 // The accounting for memory includes the memory used by rounding up object 694 // The accounting for memory includes the memory used by rounding up object
694 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to 695 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
695 // have some slack in the tests. 696 // have some slack in the tests.
696 template<typename T> 697 template<typename T>
697 void CheckWithSlack(T expected, T actual, int slack) 698 void CheckWithSlack(T expected, T actual, int slack)
698 { 699 {
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 ThreadedWeaknessTester::test(); 1787 ThreadedWeaknessTester::test();
1787 } 1788 }
1788 1789
1789 TEST(HeapTest, ThreadPersistent) 1790 TEST(HeapTest, ThreadPersistent)
1790 { 1791 {
1791 ThreadPersistentHeapTester::test(); 1792 ThreadPersistentHeapTester::test();
1792 } 1793 }
1793 1794
1794 TEST(HeapTest, BasicFunctionality) 1795 TEST(HeapTest, BasicFunctionality)
1795 { 1796 {
1797 ThreadHeap& heap = ThreadState::current()->heap();
1796 clearOutOldGarbage(); 1798 clearOutOldGarbage();
1797 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 1799 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
1798 { 1800 {
1799 size_t slack = 0; 1801 size_t slack = 0;
1800 1802
1801 // When the test starts there may already have been leaked some memory 1803 // When the test starts there may already have been leaked some memory
1802 // on the heap, so we establish a base line. 1804 // on the heap, so we establish a base line.
1803 size_t baseLevel = initialObjectPayloadSize; 1805 size_t baseLevel = initialObjectPayloadSize;
1804 bool testPagesAllocated = !baseLevel; 1806 bool testPagesAllocated = !baseLevel;
1805 if (testPagesAllocated) 1807 if (testPagesAllocated)
1806 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); 1808 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1807 1809
1808 // This allocates objects on the general heap which should add a page of memory. 1810 // This allocates objects on the general heap which should add a page of memory.
1809 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); 1811 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32);
1810 slack += 4; 1812 slack += 4;
1811 memset(alloc32, 40, 32); 1813 memset(alloc32, 40, 32);
1812 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); 1814 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64);
1813 slack += 4; 1815 slack += 4;
1814 memset(alloc64, 27, 64); 1816 memset(alloc64, 27, 64);
1815 1817
1816 size_t total = 96; 1818 size_t total = 96;
1817 1819
1818 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1820 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1819 if (testPagesAllocated) 1821 if (testPagesAllocated)
1820 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), blinkPageSize * 2); 1822 EXPECT_EQ(heap.heapStats().allocatedSpace(), blinkPageSize * 2);
1821 1823
1822 EXPECT_EQ(alloc32->get(0), 40); 1824 EXPECT_EQ(alloc32->get(0), 40);
1823 EXPECT_EQ(alloc32->get(31), 40); 1825 EXPECT_EQ(alloc32->get(31), 40);
1824 EXPECT_EQ(alloc64->get(0), 27); 1826 EXPECT_EQ(alloc64->get(0), 27);
1825 EXPECT_EQ(alloc64->get(63), 27); 1827 EXPECT_EQ(alloc64->get(63), 27);
1826 1828
1827 conservativelyCollectGarbage(); 1829 conservativelyCollectGarbage();
1828 1830
1829 EXPECT_EQ(alloc32->get(0), 40); 1831 EXPECT_EQ(alloc32->get(0), 40);
1830 EXPECT_EQ(alloc32->get(31), 40); 1832 EXPECT_EQ(alloc32->get(31), 40);
1831 EXPECT_EQ(alloc64->get(0), 27); 1833 EXPECT_EQ(alloc64->get(0), 27);
1832 EXPECT_EQ(alloc64->get(63), 27); 1834 EXPECT_EQ(alloc64->get(63), 27);
1833 } 1835 }
1834 1836
1835 clearOutOldGarbage(); 1837 clearOutOldGarbage();
1836 size_t total = 0; 1838 size_t total = 0;
1837 size_t slack = 0; 1839 size_t slack = 0;
1838 size_t baseLevel = ThreadHeap::objectPayloadSizeForTesting(); 1840 size_t baseLevel = heap.objectPayloadSizeForTesting();
1839 bool testPagesAllocated = !baseLevel; 1841 bool testPagesAllocated = !baseLevel;
1840 if (testPagesAllocated) 1842 if (testPagesAllocated)
1841 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); 1843 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1842 1844
1843 size_t big = 1008; 1845 size_t big = 1008;
1844 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big); 1846 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big);
1845 total += big; 1847 total += big;
1846 slack += 4; 1848 slack += 4;
1847 1849
1848 size_t persistentCount = 0; 1850 size_t persistentCount = 0;
1849 const size_t numPersistents = 100000; 1851 const size_t numPersistents = 100000;
1850 Persistent<DynamicallySizedObject>* persistents[numPersistents]; 1852 Persistent<DynamicallySizedObject>* persistents[numPersistents];
1851 1853
1852 for (int i = 0; i < 1000; i++) { 1854 for (int i = 0; i < 1000; i++) {
1853 size_t size = 128 + i * 8; 1855 size_t size = 128 + i * 8;
1854 total += size; 1856 total += size;
1855 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size)); 1857 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size));
1856 slack += 4; 1858 slack += 4;
1857 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1859 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1858 if (testPagesAllocated) 1860 if (testPagesAllocated)
1859 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage Size - 1)); 1861 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1860 } 1862 }
1861 1863
1862 { 1864 {
1863 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); 1865 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32));
1864 slack += 4; 1866 slack += 4;
1865 memset(alloc32b, 40, 32); 1867 memset(alloc32b, 40, 32);
1866 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); 1868 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64));
1867 slack += 4; 1869 slack += 4;
1868 memset(alloc64b, 27, 64); 1870 memset(alloc64b, 27, 64);
1869 EXPECT_TRUE(alloc32b != alloc64b); 1871 EXPECT_TRUE(alloc32b != alloc64b);
1870 1872
1871 total += 96; 1873 total += 96;
1872 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin g(), slack); 1874 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1873 if (testPagesAllocated) 1875 if (testPagesAllocated)
1874 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage Size - 1)); 1876 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1875 } 1877 }
1876 1878
1877 clearOutOldGarbage(); 1879 clearOutOldGarbage();
1878 total -= 96; 1880 total -= 96;
1879 slack -= 8; 1881 slack -= 8;
1880 if (testPagesAllocated) 1882 if (testPagesAllocated)
1881 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1883 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1882 1884
1883 // Clear the persistent, so that the big area will be garbage collected. 1885 // Clear the persistent, so that the big area will be garbage collected.
1884 bigArea.release(); 1886 bigArea.release();
1885 clearOutOldGarbage(); 1887 clearOutOldGarbage();
1886 1888
1887 total -= big; 1889 total -= big;
1888 slack -= 4; 1890 slack -= 4;
1889 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(), slack); 1891 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1890 if (testPagesAllocated) 1892 if (testPagesAllocated)
1891 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1893 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1892 1894
1893 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(), slack); 1895 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1894 if (testPagesAllocated) 1896 if (testPagesAllocated)
1895 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize - 1)); 1897 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1896 1898
1897 for (size_t i = 0; i < persistentCount; i++) { 1899 for (size_t i = 0; i < persistentCount; i++) {
1898 delete persistents[i]; 1900 delete persistents[i];
1899 persistents[i] = 0; 1901 persistents[i] = 0;
1900 } 1902 }
1901 1903
1902 uint8_t* address = reinterpret_cast<uint8_t*>(ThreadHeap::allocate<Dynamical lySizedObject>(100)); 1904 uint8_t* address = reinterpret_cast<uint8_t*>(ThreadHeap::allocate<Dynamical lySizedObject>(100));
1903 for (int i = 0; i < 100; i++) 1905 for (int i = 0; i < 100; i++)
1904 address[i] = i; 1906 address[i] = i;
1905 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 100000)); 1907 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 100000));
1906 for (int i = 0; i < 100; i++) 1908 for (int i = 0; i < 100; i++)
1907 EXPECT_EQ(address[i], i); 1909 EXPECT_EQ(address[i], i);
1908 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 50)); 1910 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized Object>(address, 50));
1909 for (int i = 0; i < 50; i++) 1911 for (int i = 0; i < 50; i++)
1910 EXPECT_EQ(address[i], i); 1912 EXPECT_EQ(address[i], i);
1911 // This should be equivalent to free(address). 1913 // This should be equivalent to free(address).
1912 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(address, 0)), 0ul); 1914 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(address, 0)), 0ul);
1913 // This should be equivalent to malloc(0). 1915 // This should be equivalent to malloc(0).
1914 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(0, 0)), 0ul); 1916 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize dObject>(0, 0)), 0ul);
1915 } 1917 }
1916 1918
1917 TEST(HeapTest, SimpleAllocation) 1919 TEST(HeapTest, SimpleAllocation)
1918 { 1920 {
1921 ThreadHeap& heap = ThreadState::current()->heap();
1919 clearOutOldGarbage(); 1922 clearOutOldGarbage();
1920 EXPECT_EQ(0ul, ThreadHeap::objectPayloadSizeForTesting()); 1923 EXPECT_EQ(0ul, heap.objectPayloadSizeForTesting());
1921 1924
1922 // Allocate an object in the heap. 1925 // Allocate an object in the heap.
1923 HeapAllocatedArray* array = new HeapAllocatedArray(); 1926 HeapAllocatedArray* array = new HeapAllocatedArray();
1924 EXPECT_TRUE(ThreadHeap::objectPayloadSizeForTesting() >= sizeof(HeapAllocate dArray)); 1927 EXPECT_TRUE(heap.objectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray) );
1925 1928
1926 // Sanity check of the contents in the heap. 1929 // Sanity check of the contents in the heap.
1927 EXPECT_EQ(0, array->at(0)); 1930 EXPECT_EQ(0, array->at(0));
1928 EXPECT_EQ(42, array->at(42)); 1931 EXPECT_EQ(42, array->at(42));
1929 EXPECT_EQ(0, array->at(128)); 1932 EXPECT_EQ(0, array->at(128));
1930 EXPECT_EQ(999 % 128, array->at(999)); 1933 EXPECT_EQ(999 % 128, array->at(999));
1931 } 1934 }
1932 1935
1933 TEST(HeapTest, SimplePersistent) 1936 TEST(HeapTest, SimplePersistent)
1934 { 1937 {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 // for the conservative stack scan to find. 2245 // for the conservative stack scan to find.
2243 EXPECT_EQ(width, bars->getWidth()); 2246 EXPECT_EQ(width, bars->getWidth());
2244 } 2247 }
2245 EXPECT_EQ(Bars::width + 1, Bar::s_live); 2248 EXPECT_EQ(Bars::width + 1, Bar::s_live);
2246 preciselyCollectGarbage(); 2249 preciselyCollectGarbage();
2247 EXPECT_EQ(0u, Bar::s_live); 2250 EXPECT_EQ(0u, Bar::s_live);
2248 } 2251 }
2249 2252
2250 TEST(HeapTest, HashMapOfMembers) 2253 TEST(HeapTest, HashMapOfMembers)
2251 { 2254 {
2255 ThreadHeap& heap = ThreadState::current()->heap();
2252 IntWrapper::s_destructorCalls = 0; 2256 IntWrapper::s_destructorCalls = 0;
2253 2257
2254 clearOutOldGarbage(); 2258 clearOutOldGarbage();
2255 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2259 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2256 { 2260 {
2257 typedef HeapHashMap< 2261 typedef HeapHashMap<
2258 Member<IntWrapper>, 2262 Member<IntWrapper>,
2259 Member<IntWrapper>, 2263 Member<IntWrapper>,
2260 DefaultHash<Member<IntWrapper>>::Hash, 2264 DefaultHash<Member<IntWrapper>>::Hash,
2261 HashTraits<Member<IntWrapper>>, 2265 HashTraits<Member<IntWrapper>>,
2262 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; 2266 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap;
2263 2267
2264 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); 2268 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap();
2265 2269
2266 map->clear(); 2270 map->clear();
2267 size_t afterSetWasCreated = ThreadHeap::objectPayloadSizeForTesting(); 2271 size_t afterSetWasCreated = heap.objectPayloadSizeForTesting();
2268 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); 2272 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize);
2269 2273
2270 preciselyCollectGarbage(); 2274 preciselyCollectGarbage();
2271 size_t afterGC = ThreadHeap::objectPayloadSizeForTesting(); 2275 size_t afterGC = heap.objectPayloadSizeForTesting();
2272 EXPECT_EQ(afterGC, afterSetWasCreated); 2276 EXPECT_EQ(afterGC, afterSetWasCreated);
2273 2277
2274 // If the additions below cause garbage collections, these 2278 // If the additions below cause garbage collections, these
2275 // pointers should be found by conservative stack scanning. 2279 // pointers should be found by conservative stack scanning.
2276 IntWrapper* one(IntWrapper::create(1)); 2280 IntWrapper* one(IntWrapper::create(1));
2277 IntWrapper* anotherOne(IntWrapper::create(1)); 2281 IntWrapper* anotherOne(IntWrapper::create(1));
2278 2282
2279 map->add(one, one); 2283 map->add(one, one);
2280 2284
2281 size_t afterOneAdd = ThreadHeap::objectPayloadSizeForTesting(); 2285 size_t afterOneAdd = heap.objectPayloadSizeForTesting();
2282 EXPECT_TRUE(afterOneAdd > afterGC); 2286 EXPECT_TRUE(afterOneAdd > afterGC);
2283 2287
2284 HeapObjectIdentityMap::iterator it(map->begin()); 2288 HeapObjectIdentityMap::iterator it(map->begin());
2285 HeapObjectIdentityMap::iterator it2(map->begin()); 2289 HeapObjectIdentityMap::iterator it2(map->begin());
2286 ++it; 2290 ++it;
2287 ++it2; 2291 ++it2;
2288 2292
2289 map->add(anotherOne, one); 2293 map->add(anotherOne, one);
2290 2294
2291 // The addition above can cause an allocation of a new 2295 // The addition above can cause an allocation of a new
2292 // backing store. We therefore garbage collect before 2296 // backing store. We therefore garbage collect before
2293 // taking the heap stats in order to get rid of the old 2297 // taking the heap stats in order to get rid of the old
2294 // backing store. We make sure to not use conservative 2298 // backing store. We make sure to not use conservative
2295 // stack scanning as that could find a pointer to the 2299 // stack scanning as that could find a pointer to the
2296 // old backing. 2300 // old backing.
2297 preciselyCollectGarbage(); 2301 preciselyCollectGarbage();
2298 size_t afterAddAndGC = ThreadHeap::objectPayloadSizeForTesting(); 2302 size_t afterAddAndGC = heap.objectPayloadSizeForTesting();
2299 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); 2303 EXPECT_TRUE(afterAddAndGC >= afterOneAdd);
2300 2304
2301 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct. 2305 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct.
2302 2306
2303 preciselyCollectGarbage(); 2307 preciselyCollectGarbage();
2304 EXPECT_TRUE(map->contains(one)); 2308 EXPECT_TRUE(map->contains(one));
2305 EXPECT_TRUE(map->contains(anotherOne)); 2309 EXPECT_TRUE(map->contains(anotherOne));
2306 2310
2307 IntWrapper* gotten(map->get(one)); 2311 IntWrapper* gotten(map->get(one));
2308 EXPECT_EQ(gotten->value(), one->value()); 2312 EXPECT_EQ(gotten->value(), one->value());
2309 EXPECT_EQ(gotten, one); 2313 EXPECT_EQ(gotten, one);
2310 2314
2311 size_t afterGC2 = ThreadHeap::objectPayloadSizeForTesting(); 2315 size_t afterGC2 = heap.objectPayloadSizeForTesting();
2312 EXPECT_EQ(afterGC2, afterAddAndGC); 2316 EXPECT_EQ(afterGC2, afterAddAndGC);
2313 2317
2314 IntWrapper* dozen = 0; 2318 IntWrapper* dozen = 0;
2315 2319
2316 for (int i = 1; i < 1000; i++) { // 999 iterations. 2320 for (int i = 1; i < 1000; i++) { // 999 iterations.
2317 IntWrapper* iWrapper(IntWrapper::create(i)); 2321 IntWrapper* iWrapper(IntWrapper::create(i));
2318 IntWrapper* iSquared(IntWrapper::create(i * i)); 2322 IntWrapper* iSquared(IntWrapper::create(i * i));
2319 map->add(iWrapper, iSquared); 2323 map->add(iWrapper, iSquared);
2320 if (i == 12) 2324 if (i == 12)
2321 dozen = iWrapper; 2325 dozen = iWrapper;
2322 } 2326 }
2323 size_t afterAdding1000 = ThreadHeap::objectPayloadSizeForTesting(); 2327 size_t afterAdding1000 = heap.objectPayloadSizeForTesting();
2324 EXPECT_TRUE(afterAdding1000 > afterGC2); 2328 EXPECT_TRUE(afterAdding1000 > afterGC2);
2325 2329
2326 IntWrapper* gross(map->get(dozen)); 2330 IntWrapper* gross(map->get(dozen));
2327 EXPECT_EQ(gross->value(), 144); 2331 EXPECT_EQ(gross->value(), 144);
2328 2332
2329 // This should clear out any junk backings created by all the adds. 2333 // This should clear out any junk backings created by all the adds.
2330 preciselyCollectGarbage(); 2334 preciselyCollectGarbage();
2331 size_t afterGC3 = ThreadHeap::objectPayloadSizeForTesting(); 2335 size_t afterGC3 = heap.objectPayloadSizeForTesting();
2332 EXPECT_TRUE(afterGC3 <= afterAdding1000); 2336 EXPECT_TRUE(afterGC3 <= afterAdding1000);
2333 } 2337 }
2334 2338
2335 preciselyCollectGarbage(); 2339 preciselyCollectGarbage();
2336 // The objects 'one', anotherOne, and the 999 other pairs. 2340 // The objects 'one', anotherOne, and the 999 other pairs.
2337 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); 2341 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
2338 size_t afterGC4 = ThreadHeap::objectPayloadSizeForTesting(); 2342 size_t afterGC4 = heap.objectPayloadSizeForTesting();
2339 EXPECT_EQ(afterGC4, initialObjectPayloadSize); 2343 EXPECT_EQ(afterGC4, initialObjectPayloadSize);
2340 } 2344 }
2341 2345
2342 TEST(HeapTest, NestedAllocation) 2346 TEST(HeapTest, NestedAllocation)
2343 { 2347 {
2348 ThreadHeap& heap = ThreadState::current()->heap();
2344 clearOutOldGarbage(); 2349 clearOutOldGarbage();
2345 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2350 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2346 { 2351 {
2347 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create(); 2352 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create();
2348 } 2353 }
2349 clearOutOldGarbage(); 2354 clearOutOldGarbage();
2350 size_t afterFree = ThreadHeap::objectPayloadSizeForTesting(); 2355 size_t afterFree = heap.objectPayloadSizeForTesting();
2351 EXPECT_TRUE(initialObjectPayloadSize == afterFree); 2356 EXPECT_TRUE(initialObjectPayloadSize == afterFree);
2352 } 2357 }
2353 2358
2354 TEST(HeapTest, LargeHeapObjects) 2359 TEST(HeapTest, LargeHeapObjects)
2355 { 2360 {
2361 ThreadHeap& heap = ThreadState::current()->heap();
2356 clearOutOldGarbage(); 2362 clearOutOldGarbage();
2357 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); 2363 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2358 size_t initialAllocatedSpace = ThreadHeap::heapStats().allocatedSpace(); 2364 size_t initialAllocatedSpace = heap.heapStats().allocatedSpace();
2359 IntWrapper::s_destructorCalls = 0; 2365 IntWrapper::s_destructorCalls = 0;
2360 LargeHeapObject::s_destructorCalls = 0; 2366 LargeHeapObject::s_destructorCalls = 0;
2361 { 2367 {
2362 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated. 2368 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated.
2363 Persistent<LargeHeapObject> object = LargeHeapObject::create(); 2369 Persistent<LargeHeapObject> object = LargeHeapObject::create();
2364 ASSERT(ThreadState::current()->findPageFromAddress(object)); 2370 ASSERT(ThreadState::current()->findPageFromAddress(object));
2365 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1)); 2371 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1));
2366 clearOutOldGarbage(); 2372 clearOutOldGarbage();
2367 size_t afterAllocation = ThreadHeap::heapStats().allocatedSpace(); 2373 size_t afterAllocation = heap.heapStats().allocatedSpace();
2368 { 2374 {
2369 object->set(0, 'a'); 2375 object->set(0, 'a');
2370 EXPECT_EQ('a', object->get(0)); 2376 EXPECT_EQ('a', object->get(0));
2371 object->set(object->length() - 1, 'b'); 2377 object->set(object->length() - 1, 'b');
2372 EXPECT_EQ('b', object->get(object->length() - 1)); 2378 EXPECT_EQ('b', object->get(object->length() - 1));
2373 size_t expectedLargeHeapObjectPayloadSize = ThreadHeap::allocationSi zeFromSize(sizeof(LargeHeapObject)); 2379 size_t expectedLargeHeapObjectPayloadSize = ThreadHeap::allocationSi zeFromSize(sizeof(LargeHeapObject));
2374 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper); 2380 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper);
2375 size_t actualObjectPayloadSize = ThreadHeap::objectPayloadSizeForTes ting() - initialObjectPayloadSize; 2381 size_t actualObjectPayloadSize = heap.objectPayloadSizeForTesting() - initialObjectPayloadSize;
2376 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack); 2382 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack);
2377 // There is probably space for the IntWrapper in a heap page without 2383 // There is probably space for the IntWrapper in a heap page without
2378 // allocating extra pages. However, the IntWrapper allocation might cause 2384 // allocating extra pages. However, the IntWrapper allocation might cause
2379 // the addition of a heap page. 2385 // the addition of a heap page.
2380 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize; 2386 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize;
2381 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize; 2387 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize;
2382 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize; 2388 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
2383 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); 2389 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation);
2384 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); 2390 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound);
2385 EXPECT_EQ(0, IntWrapper::s_destructorCalls); 2391 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
2386 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); 2392 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls);
2387 for (int i = 0; i < 10; i++) 2393 for (int i = 0; i < 10; i++)
2388 object = LargeHeapObject::create(); 2394 object = LargeHeapObject::create();
2389 } 2395 }
2390 clearOutOldGarbage(); 2396 clearOutOldGarbage();
2391 EXPECT_TRUE(ThreadHeap::heapStats().allocatedSpace() == afterAllocation) ; 2397 EXPECT_TRUE(heap.heapStats().allocatedSpace() == afterAllocation);
2392 EXPECT_EQ(10, IntWrapper::s_destructorCalls); 2398 EXPECT_EQ(10, IntWrapper::s_destructorCalls);
2393 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); 2399 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls);
2394 } 2400 }
2395 clearOutOldGarbage(); 2401 clearOutOldGarbage();
2396 EXPECT_TRUE(initialObjectPayloadSize == ThreadHeap::objectPayloadSizeForTest ing()); 2402 EXPECT_TRUE(initialObjectPayloadSize == heap.objectPayloadSizeForTesting());
2397 EXPECT_TRUE(initialAllocatedSpace == ThreadHeap::heapStats().allocatedSpace( )); 2403 EXPECT_TRUE(initialAllocatedSpace == heap.heapStats().allocatedSpace());
2398 EXPECT_EQ(11, IntWrapper::s_destructorCalls); 2404 EXPECT_EQ(11, IntWrapper::s_destructorCalls);
2399 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); 2405 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls);
2400 preciselyCollectGarbage(); 2406 preciselyCollectGarbage();
2401 } 2407 }
2402 2408
2403 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; 2409 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
2404 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; 2410 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped;
2405 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; 2411 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong;
2406 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; 2412 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak;
2407 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; 2413 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
3776 { 3782 {
3777 Persistent<Bar> barPersistent = Bar::create(); 3783 Persistent<Bar> barPersistent = Bar::create();
3778 Persistent<Foo> fooPersistent = Foo::create(barPersistent); 3784 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
3779 EXPECT_TRUE(barPersistent != fooPersistent); 3785 EXPECT_TRUE(barPersistent != fooPersistent);
3780 barPersistent = fooPersistent; 3786 barPersistent = fooPersistent;
3781 EXPECT_TRUE(barPersistent == fooPersistent); 3787 EXPECT_TRUE(barPersistent == fooPersistent);
3782 } 3788 }
3783 3789
3784 TEST(HeapTest, CheckAndMarkPointer) 3790 TEST(HeapTest, CheckAndMarkPointer)
3785 { 3791 {
3792 ThreadHeap& heap = ThreadState::current()->heap();
3786 clearOutOldGarbage(); 3793 clearOutOldGarbage();
3787 3794
3788 Vector<Address> objectAddresses; 3795 Vector<Address> objectAddresses;
3789 Vector<Address> endAddresses; 3796 Vector<Address> endAddresses;
3790 Address largeObjectAddress; 3797 Address largeObjectAddress;
3791 Address largeObjectEndAddress; 3798 Address largeObjectEndAddress;
3792 for (int i = 0; i < 10; i++) { 3799 for (int i = 0; i < 10; i++) {
3793 SimpleObject* object = SimpleObject::create(); 3800 SimpleObject* object = SimpleObject::create();
3794 Address objectAddress = reinterpret_cast<Address>(object); 3801 Address objectAddress = reinterpret_cast<Address>(object);
3795 objectAddresses.append(objectAddress); 3802 objectAddresses.append(objectAddress);
3796 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1); 3803 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
3797 } 3804 }
3798 LargeHeapObject* largeObject = LargeHeapObject::create(); 3805 LargeHeapObject* largeObject = LargeHeapObject::create();
3799 largeObjectAddress = reinterpret_cast<Address>(largeObject); 3806 largeObjectAddress = reinterpret_cast<Address>(largeObject);
3800 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; 3807 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1;
3801 3808
3802 // This is a low-level test where we call checkAndMarkPointer. This method 3809 // This is a low-level test where we call checkAndMarkPointer. This method
3803 // causes the object start bitmap to be computed which requires the heap 3810 // causes the object start bitmap to be computed which requires the heap
3804 // to be in a consistent state (e.g. the free allocation area must be put 3811 // to be in a consistent state (e.g. the free allocation area must be put
3805 // into a free list header). However when we call makeConsistentForGC it 3812 // into a free list header). However when we call makeConsistentForGC it
3806 // also clears out the freelists so we have to rebuild those before trying 3813 // also clears out the freelists so we have to rebuild those before trying
3807 // to allocate anything again. We do this by forcing a GC after doing the 3814 // to allocate anything again. We do this by forcing a GC after doing the
3808 // checkAndMarkPointer tests. 3815 // checkAndMarkPointer tests.
3809 { 3816 {
3810 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3817 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3811 CountingVisitor visitor(ThreadState::current()); 3818 CountingVisitor visitor(ThreadState::current());
3812 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads. 3819 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
3813 ThreadHeap::flushHeapDoesNotContainCache(); 3820 heap.flushHeapDoesNotContainCache();
3814 for (size_t i = 0; i < objectAddresses.size(); i++) { 3821 for (size_t i = 0; i < objectAddresses.size(); i++) {
3815 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, objectAddresse s[i])); 3822 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i]));
3816 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i ])); 3823 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i]));
3817 } 3824 }
3818 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); 3825 EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
3819 visitor.reset(); 3826 visitor.reset();
3820 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress )); 3827 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress));
3821 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddr ess)); 3828 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress));
3822 EXPECT_EQ(2ul, visitor.count()); 3829 EXPECT_EQ(2ul, visitor.count());
3823 visitor.reset(); 3830 visitor.reset();
3824 } 3831 }
3825 // This forces a GC without stack scanning which results in the objects 3832 // This forces a GC without stack scanning which results in the objects
3826 // being collected. This will also rebuild the above mentioned freelists, 3833 // being collected. This will also rebuild the above mentioned freelists,
3827 // however we don't rely on that below since we don't have any allocations. 3834 // however we don't rely on that below since we don't have any allocations.
3828 clearOutOldGarbage(); 3835 clearOutOldGarbage();
3829 { 3836 {
3830 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3837 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3831 CountingVisitor visitor(ThreadState::current()); 3838 CountingVisitor visitor(ThreadState::current());
3832 EXPECT_TRUE(scope.allThreadsParked()); 3839 EXPECT_TRUE(scope.allThreadsParked());
3833 ThreadHeap::flushHeapDoesNotContainCache(); 3840 heap.flushHeapDoesNotContainCache();
3834 for (size_t i = 0; i < objectAddresses.size(); i++) { 3841 for (size_t i = 0; i < objectAddresses.size(); i++) {
3835 // We would like to assert that checkAndMarkPointer returned false 3842 // We would like to assert that checkAndMarkPointer returned false
3836 // here because the pointers no longer point into a valid object 3843 // here because the pointers no longer point into a valid object
3837 // (it's been freed by the GCs. But checkAndMarkPointer will return 3844 // (it's been freed by the GCs. But checkAndMarkPointer will return
3838 // true for any pointer that points into a heap page, regardless of 3845 // true for any pointer that points into a heap page, regardless of
3839 // whether it points at a valid object (this ensures the 3846 // whether it points at a valid object (this ensures the
3840 // correctness of the page-based on-heap address caches), so we 3847 // correctness of the page-based on-heap address caches), so we
3841 // can't make that assert. 3848 // can't make that assert.
3842 ThreadHeap::checkAndMarkPointer(&visitor, objectAddresses[i]); 3849 heap.checkAndMarkPointer(&visitor, objectAddresses[i]);
3843 ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i]); 3850 heap.checkAndMarkPointer(&visitor, endAddresses[i]);
3844 } 3851 }
3845 EXPECT_EQ(0ul, visitor.count()); 3852 EXPECT_EQ(0ul, visitor.count());
3846 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress); 3853 heap.checkAndMarkPointer(&visitor, largeObjectAddress);
3847 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddress); 3854 heap.checkAndMarkPointer(&visitor, largeObjectEndAddress);
3848 EXPECT_EQ(0ul, visitor.count()); 3855 EXPECT_EQ(0ul, visitor.count());
3849 } 3856 }
3850 // This round of GC is important to make sure that the object start 3857 // This round of GC is important to make sure that the object start
3851 // bitmap are cleared out and that the free lists are rebuild. 3858 // bitmap are cleared out and that the free lists are rebuild.
3852 clearOutOldGarbage(); 3859 clearOutOldGarbage();
3853 } 3860 }
3854 3861
3855 TEST(HeapTest, PersistentHeapCollectionTypes) 3862 TEST(HeapTest, PersistentHeapCollectionTypes)
3856 { 3863 {
3857 IntWrapper::s_destructorCalls = 0; 3864 IntWrapper::s_destructorCalls = 0;
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
4706 { 4713 {
4707 // Since the sleeper thread has detached this is the only thread. 4714 // Since the sleeper thread has detached this is the only thread.
4708 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); 4715 TestGCScope scope(BlinkGC::NoHeapPointersOnStack);
4709 EXPECT_TRUE(scope.allThreadsParked()); 4716 EXPECT_TRUE(scope.allThreadsParked());
4710 } 4717 }
4711 } 4718 }
4712 4719
4713 private: 4720 private:
4714 static void sleeperMainFunc() 4721 static void sleeperMainFunc()
4715 { 4722 {
4716 ThreadState::attach(); 4723 ThreadState::attachCurrentThread();
4717 s_sleeperRunning = true; 4724 s_sleeperRunning = true;
4718 4725
4719 // Simulate a long running op that is not entering a safepoint. 4726 // Simulate a long running op that is not entering a safepoint.
4720 while (!s_sleeperDone) { 4727 while (!s_sleeperDone) {
4721 testing::yieldCurrentThread(); 4728 testing::yieldCurrentThread();
4722 } 4729 }
4723 4730
4724 ThreadState::detach(); 4731 ThreadState::detachCurrentThread();
4725 s_sleeperRunning = false; 4732 s_sleeperRunning = false;
4726 } 4733 }
4727 4734
4728 static volatile bool s_sleeperRunning; 4735 static volatile bool s_sleeperRunning;
4729 static volatile bool s_sleeperDone; 4736 static volatile bool s_sleeperDone;
4730 }; 4737 };
4731 4738
4732 volatile bool GCParkingThreadTester::s_sleeperRunning = false; 4739 volatile bool GCParkingThreadTester::s_sleeperRunning = false;
4733 volatile bool GCParkingThreadTester::s_sleeperDone = false; 4740 volatile bool GCParkingThreadTester::s_sleeperDone = false;
4734 4741
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 // shutdown. 5398 // shutdown.
5392 wakeWorkerThread(); 5399 wakeWorkerThread();
5393 } 5400 }
5394 5401
5395 private: 5402 private:
5396 5403
5397 static void workerThreadMain() 5404 static void workerThreadMain()
5398 { 5405 {
5399 MutexLocker locker(workerThreadMutex()); 5406 MutexLocker locker(workerThreadMutex());
5400 5407
5401 ThreadState::attach(); 5408 ThreadState::attachCurrentThread();
5402 5409
5403 { 5410 {
5404 // Create a worker object that is not kept alive except the 5411 // Create a worker object that is not kept alive except the
5405 // main thread will keep it as an integer value on its stack. 5412 // main thread will keep it as an integer value on its stack.
5406 IntWrapper* workerObject = IntWrapper::create(42); 5413 IntWrapper* workerObject = IntWrapper::create(42);
5407 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); 5414 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject);
5408 } 5415 }
5409 5416
5410 // Signal the main thread that the worker is done with its allocation. 5417 // Signal the main thread that the worker is done with its allocation.
5411 wakeMainThread(); 5418 wakeMainThread();
5412 5419
5413 { 5420 {
5414 // Wait for the main thread to do two GCs without sweeping this thre ad 5421 // Wait for the main thread to do two GCs without sweeping this thre ad
5415 // heap. The worker waits within a safepoint, but there is no sweepi ng 5422 // heap. The worker waits within a safepoint, but there is no sweepi ng
5416 // until leaving the safepoint scope. 5423 // until leaving the safepoint scope.
5417 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 5424 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
5418 parkWorkerThread(); 5425 parkWorkerThread();
5419 } 5426 }
5420 5427
5421 // Wake up the main thread when done sweeping. 5428 // Wake up the main thread when done sweeping.
5422 wakeMainThread(); 5429 wakeMainThread();
5423 5430
5424 // Wait with detach until the main thread says so. This is not strictly 5431 // Wait with detach until the main thread says so. This is not strictly
5425 // necessary, but it means the worker thread will not do its thread loca l 5432 // necessary, but it means the worker thread will not do its thread loca l
5426 // GCs just yet, making it easier to reason about that no new GC has occ urred 5433 // GCs just yet, making it easier to reason about that no new GC has occ urred
5427 // and the above sweep was the one finalizing the worker object. 5434 // and the above sweep was the one finalizing the worker object.
5428 parkWorkerThread(); 5435 parkWorkerThread();
5429 5436
5430 ThreadState::detach(); 5437 ThreadState::detachCurrentThread();
5431 } 5438 }
5432 5439
5433 static volatile uintptr_t s_workerObjectPointer; 5440 static volatile uintptr_t s_workerObjectPointer;
5434 }; 5441 };
5435 5442
5436 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; 5443 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0;
5437 5444
5438 TEST(HeapTest, ObjectDeadBit) 5445 TEST(HeapTest, ObjectDeadBit)
5439 { 5446 {
5440 DeadBitTester::test(); 5447 DeadBitTester::test();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 parkWorkerThread(); 5519 parkWorkerThread();
5513 } 5520 }
5514 5521
5515 return weakCollection; 5522 return weakCollection;
5516 } 5523 }
5517 5524
5518 static void workerThreadMain() 5525 static void workerThreadMain()
5519 { 5526 {
5520 MutexLocker locker(workerThreadMutex()); 5527 MutexLocker locker(workerThreadMutex());
5521 5528
5522 ThreadState::attach(); 5529 ThreadState::attachCurrentThread();
5523 5530
5524 { 5531 {
5525 Persistent<WeakCollectionType> collection = allocateCollection(); 5532 Persistent<WeakCollectionType> collection = allocateCollection();
5526 { 5533 {
5527 // Prevent weak processing with an iterator and GC. 5534 // Prevent weak processing with an iterator and GC.
5528 WeakCollectionType::iterator it = collection->begin(); 5535 WeakCollectionType::iterator it = collection->begin();
5529 conservativelyCollectGarbage(); 5536 conservativelyCollectGarbage();
5530 5537
5531 // The backing should be strongified because of the iterator. 5538 // The backing should be strongified because of the iterator.
5532 EXPECT_EQ(6u, collection->size()); 5539 EXPECT_EQ(6u, collection->size());
5533 EXPECT_EQ(32, it->value->value()); 5540 EXPECT_EQ(32, it->value->value());
5534 } 5541 }
5535 5542
5536 // Disregarding the iterator but keeping the collection alive 5543 // Disregarding the iterator but keeping the collection alive
5537 // with a persistent should lead to weak processing. 5544 // with a persistent should lead to weak processing.
5538 preciselyCollectGarbage(); 5545 preciselyCollectGarbage();
5539 EXPECT_EQ(0u, collection->size()); 5546 EXPECT_EQ(0u, collection->size());
5540 } 5547 }
5541 5548
5542 wakeMainThread(); 5549 wakeMainThread();
5543 ThreadState::detach(); 5550 ThreadState::detachCurrentThread();
5544 } 5551 }
5545 5552
5546 static volatile uintptr_t s_workerObjectPointer; 5553 static volatile uintptr_t s_workerObjectPointer;
5547 }; 5554 };
5548 5555
5549 TEST(HeapTest, ThreadedStrongification) 5556 TEST(HeapTest, ThreadedStrongification)
5550 { 5557 {
5551 ThreadedStrongificationTester::test(); 5558 ThreadedStrongificationTester::test();
5552 } 5559 }
5553 5560
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
5673 // can acquire it and do its sweep of its arenas. Just wait for the work er 5680 // can acquire it and do its sweep of its arenas. Just wait for the work er
5674 // to complete its sweep and check the result. 5681 // to complete its sweep and check the result.
5675 parkMainThread(); 5682 parkMainThread();
5676 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); 5683 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls);
5677 } 5684 }
5678 5685
5679 private: 5686 private:
5680 static void workerThreadMain() 5687 static void workerThreadMain()
5681 { 5688 {
5682 MutexLocker locker(workerThreadMutex()); 5689 MutexLocker locker(workerThreadMutex());
5683 ThreadState::attach(); 5690 ThreadState::attachCurrentThread();
5684 5691
5685 DestructorLockingObject* dlo = DestructorLockingObject::create(); 5692 DestructorLockingObject* dlo = DestructorLockingObject::create();
5686 ASSERT_UNUSED(dlo, dlo); 5693 ASSERT_UNUSED(dlo, dlo);
5687 5694
5688 // Wake up the main thread which is waiting for the worker to do its 5695 // Wake up the main thread which is waiting for the worker to do its
5689 // allocation. 5696 // allocation.
5690 wakeMainThread(); 5697 wakeMainThread();
5691 5698
5692 // Wait for the main thread to get the global lock to ensure it has 5699 // Wait for the main thread to get the global lock to ensure it has
5693 // it before the worker tries to acquire it. We want the worker to 5700 // it before the worker tries to acquire it. We want the worker to
5694 // block in the SafePointAwareMutexLocker until the main thread 5701 // block in the SafePointAwareMutexLocker until the main thread
5695 // has done a GC. The GC will not mark the "dlo" object since the worker 5702 // has done a GC. The GC will not mark the "dlo" object since the worker
5696 // is entering the safepoint with NoHeapPointersOnStack. When the worker 5703 // is entering the safepoint with NoHeapPointersOnStack. When the worker
5697 // subsequently gets the global lock and leaves the safepoint it will 5704 // subsequently gets the global lock and leaves the safepoint it will
5698 // sweep its heap and finalize "dlo". The destructor of "dlo" will try 5705 // sweep its heap and finalize "dlo". The destructor of "dlo" will try
5699 // to acquire the same global lock that the thread just got and deadlock 5706 // to acquire the same global lock that the thread just got and deadlock
5700 // unless the global lock is recursive. 5707 // unless the global lock is recursive.
5701 parkWorkerThread(); 5708 parkWorkerThread();
5702 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack); 5709 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack);
5703 5710
5704 // We won't get here unless the lock is recursive since the sweep done 5711 // We won't get here unless the lock is recursive since the sweep done
5705 // in the constructor of SafePointAwareMutexLocker after 5712 // in the constructor of SafePointAwareMutexLocker after
5706 // getting the lock will not complete given the "dlo" destructor is 5713 // getting the lock will not complete given the "dlo" destructor is
5707 // waiting to get the same lock. 5714 // waiting to get the same lock.
5708 // Tell the main thread the worker has done its sweep. 5715 // Tell the main thread the worker has done its sweep.
5709 wakeMainThread(); 5716 wakeMainThread();
5710 5717
5711 ThreadState::detach(); 5718 ThreadState::detachCurrentThread();
5712 } 5719 }
5713 5720
5714 static volatile IntWrapper* s_workerObjectPointer; 5721 static volatile IntWrapper* s_workerObjectPointer;
5715 }; 5722 };
5716 5723
5717 TEST(HeapTest, RecursiveMutex) 5724 TEST(HeapTest, RecursiveMutex)
5718 { 5725 {
5719 RecursiveLockingTester::test(); 5726 RecursiveLockingTester::test();
5720 } 5727 }
5721 5728
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
6362 preciselyCollectGarbage(); 6369 preciselyCollectGarbage();
6363 EXPECT_FALSE(holder->object()); 6370 EXPECT_FALSE(holder->object());
6364 } 6371 }
6365 6372
6366 namespace { 6373 namespace {
6367 6374
6368 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject** object) 6375 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject** object)
6369 { 6376 {
6370 // Step 2: Create an object and store the pointer. 6377 // Step 2: Create an object and store the pointer.
6371 MutexLocker locker(workerThreadMutex()); 6378 MutexLocker locker(workerThreadMutex());
6372 ThreadState::attach(); 6379 ThreadState::attachCurrentThread();
6373 *object = DestructorLockingObject::create(); 6380 *object = DestructorLockingObject::create();
6374 wakeMainThread(); 6381 wakeMainThread();
6375 parkWorkerThread(); 6382 parkWorkerThread();
6376 6383
6377 // Step 4: Run a GC. 6384 // Step 4: Run a GC.
6378 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw eep, BlinkGC::ForcedGC); 6385 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw eep, BlinkGC::ForcedGC);
6379 wakeMainThread(); 6386 wakeMainThread();
6380 parkWorkerThread(); 6387 parkWorkerThread();
6381 6388
6382 // Step 6: Finish. 6389 // Step 6: Finish.
6383 ThreadState::detach(); 6390 ThreadState::detachCurrentThread();
6384 wakeMainThread(); 6391 wakeMainThread();
6385 } 6392 }
6386 6393
6387 } // anonymous namespace 6394 } // anonymous namespace
6388 6395
6389 TEST(HeapTest, CrossThreadWeakPersistent) 6396 TEST(HeapTest, CrossThreadWeakPersistent)
6390 { 6397 {
6391 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread, 6398 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread,
6392 // clear the reference in the worker thread, run a GC in the worker thread, and see if the 6399 // clear the reference in the worker thread, run a GC in the worker thread, and see if the
6393 // CrossThreadWeakPersistent is cleared. 6400 // CrossThreadWeakPersistent is cleared.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
6486 static void test() 6493 static void test()
6487 { 6494 {
6488 IntWrapper::s_destructorCalls = 0; 6495 IntWrapper::s_destructorCalls = 0;
6489 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); 6496 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester);
6490 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); 6497 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls);
6491 } 6498 }
6492 6499
6493 private: 6500 private:
6494 void runThread() override 6501 void runThread() override
6495 { 6502 {
6496 ThreadState::attach(); 6503 ThreadState::attachCurrentThread();
6497 EXPECT_EQ(42, threadSpecificIntWrapper().value()); 6504 EXPECT_EQ(42, threadSpecificIntWrapper().value());
6498 ThreadState::detach(); 6505 ThreadState::detachCurrentThread();
6499 atomicDecrement(&m_threadsToFinish); 6506 atomicDecrement(&m_threadsToFinish);
6500 } 6507 }
6501 6508
6502 static IntWrapper& threadSpecificIntWrapper() 6509 static IntWrapper& threadSpecificIntWrapper()
6503 { 6510 {
6504 DEFINE_THREAD_SAFE_STATIC_LOCAL( 6511 DEFINE_THREAD_SAFE_STATIC_LOCAL(
6505 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, 6512 ThreadSpecific<Persistent<IntWrapper>>, intWrapper,
6506 new ThreadSpecific<Persistent<IntWrapper>>); 6513 new ThreadSpecific<Persistent<IntWrapper>>);
6507 Persistent<IntWrapper>& handle = *intWrapper; 6514 Persistent<IntWrapper>& handle = *intWrapper;
6508 if (!handle) { 6515 if (!handle) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6553 conservativelyCollectGarbage(); 6560 conservativelyCollectGarbage();
6554 EXPECT_EQ(wrapper, weakWrapper->value()); 6561 EXPECT_EQ(wrapper, weakWrapper->value());
6555 // Stub out any stack reference. 6562 // Stub out any stack reference.
6556 wrapper = nullptr; 6563 wrapper = nullptr;
6557 } 6564 }
6558 preciselyCollectGarbage(); 6565 preciselyCollectGarbage();
6559 EXPECT_EQ(nullptr, weakWrapper->value()); 6566 EXPECT_EQ(nullptr, weakWrapper->value());
6560 } 6567 }
6561 6568
6562 } // namespace blink 6569 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/HeapPage.cpp ('k') | third_party/WebKit/Source/platform/heap/MarkingVisitorImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698