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

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

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