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

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

Issue 1477023003: Refactor the Heap into ThreadHeap to prepare for per thread heaps Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 namespace blink { 237 namespace blink {
238 238
239 class TestGCScope { 239 class TestGCScope {
240 public: 240 public:
241 explicit TestGCScope(BlinkGC::StackState state) 241 explicit TestGCScope(BlinkGC::StackState state)
242 : m_state(ThreadState::current()) 242 : m_state(ThreadState::current())
243 , m_safePointScope(state) 243 , m_safePointScope(state)
244 , m_parkedAllThreads(false) 244 , m_parkedAllThreads(false)
245 { 245 {
246 ASSERT(m_state->checkThread()); 246 ASSERT(m_state->checkThread());
247 if (LIKELY(ThreadState::stopThreads())) { 247 if (LIKELY(m_state->heap().park())) {
248 Heap::preGC(); 248 m_state->heap().preGC();
249 m_parkedAllThreads = true; 249 m_parkedAllThreads = true;
250 } 250 }
251 } 251 }
252 252
253 bool allThreadsParked() { return m_parkedAllThreads; } 253 bool allThreadsParked() { return m_parkedAllThreads; }
254 254
255 ~TestGCScope() 255 ~TestGCScope()
256 { 256 {
257 // Only cleanup if we parked all threads in which case the GC happened 257 // Only cleanup if we parked all threads in which case the GC happened
258 // and we need to resume the other threads. 258 // and we need to resume the other threads.
259 if (LIKELY(m_parkedAllThreads)) { 259 if (LIKELY(m_parkedAllThreads)) {
260 Heap::postGC(BlinkGC::GCWithSweep); 260 m_state->heap().postGC(BlinkGC::GCWithSweep);
261 ThreadState::resumeThreads(); 261 m_state->heap().resume();
262 } 262 }
263 } 263 }
264 264
265 private: 265 private:
266 ThreadState* m_state; 266 ThreadState* m_state;
267 SafePointScope m_safePointScope; 267 SafePointScope m_safePointScope;
268 bool m_parkedAllThreads; // False if we fail to park all threads 268 bool m_parkedAllThreads; // False if we fail to park all threads
269 }; 269 };
270 270
271 #define DEFINE_VISITOR_METHODS(Type) \ 271 #define DEFINE_VISITOR_METHODS(Type) \
272 void mark(const Type* object, TraceCallback callback) override \ 272 void mark(const Type* object, TraceCallback callback) override \
273 { \ 273 { \
274 if (object) \ 274 if (object) \
275 m_count++; \ 275 m_count++; \
276 } \ 276 } \
277 bool isMarked(const Type*) override { return false; } \ 277 bool isMarked(const Type*) override { return false; } \
278 bool ensureMarked(const Type* objectPointer) override \ 278 bool ensureMarked(const Type* objectPointer) override \
279 { \ 279 { \
280 return ensureMarked(objectPointer); \ 280 return ensureMarked(objectPointer); \
281 } 281 }
282 282
283 class CountingVisitor : public Visitor { 283 class CountingVisitor : public Visitor {
284 public: 284 public:
285 CountingVisitor() 285 explicit CountingVisitor(VisitorScope* visitorScope)
286 : Visitor(Visitor::ThreadLocalMarking) 286 : Visitor(Visitor::ThreadLocalMarking, visitorScope)
287 , m_count(0) 287 , m_count(0)
288 { 288 {
289 } 289 }
290 290
291 void mark(const void* object, TraceCallback) override 291 void mark(const void* object, TraceCallback) override
292 { 292 {
293 if (object) 293 if (object)
294 m_count++; 294 m_count++;
295 } 295 }
296 296
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 DEFINE_INLINE_TRACE() { } 407 DEFINE_INLINE_TRACE() { }
408 private: 408 private:
409 static const int s_arraySize = 1000; 409 static const int s_arraySize = 1000;
410 int8_t m_array[s_arraySize]; 410 int8_t m_array[s_arraySize];
411 }; 411 };
412 412
413 // Do several GCs to make sure that later GCs don't free up old memory from 413 // Do several GCs to make sure that later GCs don't free up old memory from
414 // previously run tests in this process. 414 // previously run tests in this process.
415 static void clearOutOldGarbage() 415 static void clearOutOldGarbage()
416 { 416 {
417 Heap& heap = ThreadState::current()->heap();
417 while (true) { 418 while (true) {
418 size_t used = Heap::objectPayloadSizeForTesting(); 419 size_t used = heap.objectPayloadSizeForTesting();
419 preciselyCollectGarbage(); 420 preciselyCollectGarbage();
420 if (Heap::objectPayloadSizeForTesting() >= used) 421 if (heap.objectPayloadSizeForTesting() >= used)
421 break; 422 break;
422 } 423 }
423 } 424 }
424 425
425 class OffHeapInt : public RefCounted<OffHeapInt> { 426 class OffHeapInt : public RefCounted<OffHeapInt> {
426 public: 427 public:
427 static RefPtr<OffHeapInt> create(int x) 428 static RefPtr<OffHeapInt> create(int x)
428 { 429 {
429 return adoptRef(new OffHeapInt(x)); 430 return adoptRef(new OffHeapInt(x));
430 } 431 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 553 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
553 testing::yieldCurrentThread(); 554 testing::yieldCurrentThread();
554 } 555 }
555 556
556 // Intentionally leak the cross-thread persistent so as to verify 557 // Intentionally leak the cross-thread persistent so as to verify
557 // that later GCs correctly handle cross-thread persistents that 558 // that later GCs correctly handle cross-thread persistents that
558 // refer to finalized objects after their heaps have been detached 559 // refer to finalized objects after their heaps have been detached
559 // and freed. 560 // and freed.
560 EXPECT_TRUE(longLivingPersistent.leakPtr()); 561 EXPECT_TRUE(longLivingPersistent.leakPtr());
561 562
562 ThreadState::detach(); 563 ThreadState::detachCurrentThread();
563 atomicDecrement(&m_threadsToFinish); 564 atomicDecrement(&m_threadsToFinish);
564 } 565 }
565 }; 566 };
566 567
567 class ThreadedWeaknessTester : public ThreadedTesterBase { 568 class ThreadedWeaknessTester : public ThreadedTesterBase {
568 public: 569 public:
569 static void test() 570 static void test()
570 { 571 {
571 ThreadedTesterBase::test(new ThreadedWeaknessTester); 572 ThreadedTesterBase::test(new ThreadedWeaknessTester);
572 } 573 }
(...skipping 27 matching lines...) Expand all
600 // TODO(haraken): This snapshot GC causes crashes, so disable 601 // TODO(haraken): This snapshot GC causes crashes, so disable
601 // it at the moment. Fix the crash and enable it. 602 // it at the moment. Fix the crash and enable it.
602 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC: :TakeSnapshot, BlinkGC::ForcedGC); 603 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC: :TakeSnapshot, BlinkGC::ForcedGC);
603 preciselyCollectGarbage(); 604 preciselyCollectGarbage();
604 EXPECT_TRUE(weakMap->isEmpty()); 605 EXPECT_TRUE(weakMap->isEmpty());
605 EXPECT_TRUE(weakMap2.isEmpty()); 606 EXPECT_TRUE(weakMap2.isEmpty());
606 } 607 }
607 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); 608 SafePointScope scope(BlinkGC::NoHeapPointersOnStack);
608 testing::yieldCurrentThread(); 609 testing::yieldCurrentThread();
609 } 610 }
610 ThreadState::detach(); 611 ThreadState::detachCurrentThread();
611 atomicDecrement(&m_threadsToFinish); 612 atomicDecrement(&m_threadsToFinish);
612 } 613 }
613 }; 614 };
614 615
615 class ThreadPersistentHeapTester : public ThreadedTesterBase { 616 class ThreadPersistentHeapTester : public ThreadedTesterBase {
616 public: 617 public:
617 static void test() 618 static void test()
618 { 619 {
619 ThreadedTesterBase::test(new ThreadPersistentHeapTester); 620 ThreadedTesterBase::test(new ThreadPersistentHeapTester);
620 } 621 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 void runThread() override 670 void runThread() override
670 { 671 {
671 ThreadState::attach(); 672 ThreadState::attach();
672 673
673 PersistentChain::create(100); 674 PersistentChain::create(100);
674 675
675 // Upon thread detach, GCs will run until all persistents have been 676 // Upon thread detach, GCs will run until all persistents have been
676 // released. We verify that the draining of persistents proceeds 677 // released. We verify that the draining of persistents proceeds
677 // as expected by dropping one Persistent<> per GC until there 678 // as expected by dropping one Persistent<> per GC until there
678 // are none left. 679 // are none left.
679 ThreadState::detach(); 680 ThreadState::detachCurrentThread();
680 atomicDecrement(&m_threadsToFinish); 681 atomicDecrement(&m_threadsToFinish);
681 } 682 }
682 }; 683 };
683 684
684 // The accounting for memory includes the memory used by rounding up object 685 // The accounting for memory includes the memory used by rounding up object
685 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to 686 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to
686 // have some slack in the tests. 687 // have some slack in the tests.
687 template<typename T> 688 template<typename T>
688 void CheckWithSlack(T expected, T actual, int slack) 689 void CheckWithSlack(T expected, T actual, int slack)
689 { 690 {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 // so as to avoid possible warnings about linker duplicates. 769 // so as to avoid possible warnings about linker duplicates.
769 // Override operator new to allocate IntNode subtype objects onto 770 // Override operator new to allocate IntNode subtype objects onto
770 // the dedicated heap for blink::Node. 771 // the dedicated heap for blink::Node.
771 // 772 //
772 // TODO(haraken): untangling the heap unit tests from Blink would 773 // TODO(haraken): untangling the heap unit tests from Blink would
773 // simplify and avoid running into this problem - http://crbug.com/425381 774 // simplify and avoid running into this problem - http://crbug.com/425381
774 GC_PLUGIN_IGNORE("crbug.com/443854") 775 GC_PLUGIN_IGNORE("crbug.com/443854")
775 void* operator new(size_t size) 776 void* operator new(size_t size)
776 { 777 {
777 ThreadState* state = ThreadState::current(); 778 ThreadState* state = ThreadState::current();
778 return Heap::allocateOnHeapIndex(state, size, BlinkGC::NodeHeapIndex, GC InfoTrait<IntNode>::index()); 779 return Heap::allocateOnArenaIndex(state, size, BlinkGC::NodeArenaIndex, GCInfoTrait<IntNode>::index());
779 } 780 }
780 781
781 static IntNode* create(int i) 782 static IntNode* create(int i)
782 { 783 {
783 return new IntNode(i); 784 return new IntNode(i);
784 } 785 }
785 786
786 DEFINE_INLINE_TRACE() { } 787 DEFINE_INLINE_TRACE() { }
787 788
788 int value() { return m_value; } 789 int value() { return m_value; }
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 int RefCountedAndGarbageCollected2::s_destructorCalls = 0; 1027 int RefCountedAndGarbageCollected2::s_destructorCalls = 0;
1027 1028
1028 #define DEFINE_VISITOR_METHODS(Type) \ 1029 #define DEFINE_VISITOR_METHODS(Type) \
1029 void mark(const Type* object, TraceCallback callback) override \ 1030 void mark(const Type* object, TraceCallback callback) override \
1030 { \ 1031 { \
1031 mark(object); \ 1032 mark(object); \
1032 } \ 1033 } \
1033 1034
1034 class RefCountedGarbageCollectedVisitor : public CountingVisitor { 1035 class RefCountedGarbageCollectedVisitor : public CountingVisitor {
1035 public: 1036 public:
1036 RefCountedGarbageCollectedVisitor(int expected, void** objects) 1037 RefCountedGarbageCollectedVisitor(int expected, void** objects, VisitorScope * visitorScope)
1037 : m_count(0) 1038 : CountingVisitor(visitorScope)
1039 , m_count(0)
1038 , m_expectedCount(expected) 1040 , m_expectedCount(expected)
1039 , m_expectedObjects(objects) 1041 , m_expectedObjects(objects)
1040 { 1042 {
1041 } 1043 }
1042 1044
1043 void mark(const void* ptr) { markNoTrace(ptr); } 1045 void mark(const void* ptr) { markNoTrace(ptr); }
1044 1046
1045 virtual void markNoTrace(const void* ptr) 1047 virtual void markNoTrace(const void* ptr)
1046 { 1048 {
1047 if (!ptr) 1049 if (!ptr)
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 ThreadedWeaknessTester::test(); 1757 ThreadedWeaknessTester::test();
1756 } 1758 }
1757 1759
1758 TEST(HeapTest, ThreadPersistent) 1760 TEST(HeapTest, ThreadPersistent)
1759 { 1761 {
1760 ThreadPersistentHeapTester::test(); 1762 ThreadPersistentHeapTester::test();
1761 } 1763 }
1762 1764
1763 TEST(HeapTest, BasicFunctionality) 1765 TEST(HeapTest, BasicFunctionality)
1764 { 1766 {
1767 Heap& heap = ThreadState::current()->heap();
1765 clearOutOldGarbage(); 1768 clearOutOldGarbage();
1766 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); 1769 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
1767 { 1770 {
1768 size_t slack = 0; 1771 size_t slack = 0;
1769 1772
1770 // When the test starts there may already have been leaked some memory 1773 // When the test starts there may already have been leaked some memory
1771 // on the heap, so we establish a base line. 1774 // on the heap, so we establish a base line.
1772 size_t baseLevel = initialObjectPayloadSize; 1775 size_t baseLevel = initialObjectPayloadSize;
1773 bool testPagesAllocated = !baseLevel; 1776 bool testPagesAllocated = !baseLevel;
1774 if (testPagesAllocated) 1777 if (testPagesAllocated)
1775 EXPECT_EQ(Heap::allocatedSpace(), 0ul); 1778 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1776 1779
1777 // This allocates objects on the general heap which should add a page of memory. 1780 // This allocates objects on the general heap which should add a page of memory.
1778 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); 1781 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32);
1779 slack += 4; 1782 slack += 4;
1780 memset(alloc32, 40, 32); 1783 memset(alloc32, 40, 32);
1781 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); 1784 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64);
1782 slack += 4; 1785 slack += 4;
1783 memset(alloc64, 27, 64); 1786 memset(alloc64, 27, 64);
1784 1787
1785 size_t total = 96; 1788 size_t total = 96;
1786 1789
1787 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s lack); 1790 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1788 if (testPagesAllocated) 1791 if (testPagesAllocated)
1789 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); 1792 EXPECT_EQ(heap.heapStats().allocatedSpace(), blinkPageSize * 2);
1790 1793
1791 EXPECT_EQ(alloc32->get(0), 40); 1794 EXPECT_EQ(alloc32->get(0), 40);
1792 EXPECT_EQ(alloc32->get(31), 40); 1795 EXPECT_EQ(alloc32->get(31), 40);
1793 EXPECT_EQ(alloc64->get(0), 27); 1796 EXPECT_EQ(alloc64->get(0), 27);
1794 EXPECT_EQ(alloc64->get(63), 27); 1797 EXPECT_EQ(alloc64->get(63), 27);
1795 1798
1796 conservativelyCollectGarbage(); 1799 conservativelyCollectGarbage();
1797 1800
1798 EXPECT_EQ(alloc32->get(0), 40); 1801 EXPECT_EQ(alloc32->get(0), 40);
1799 EXPECT_EQ(alloc32->get(31), 40); 1802 EXPECT_EQ(alloc32->get(31), 40);
1800 EXPECT_EQ(alloc64->get(0), 27); 1803 EXPECT_EQ(alloc64->get(0), 27);
1801 EXPECT_EQ(alloc64->get(63), 27); 1804 EXPECT_EQ(alloc64->get(63), 27);
1802 } 1805 }
1803 1806
1804 clearOutOldGarbage(); 1807 clearOutOldGarbage();
1805 size_t total = 0; 1808 size_t total = 0;
1806 size_t slack = 0; 1809 size_t slack = 0;
1807 size_t baseLevel = Heap::objectPayloadSizeForTesting(); 1810 size_t baseLevel = heap.objectPayloadSizeForTesting();
1808 bool testPagesAllocated = !baseLevel; 1811 bool testPagesAllocated = !baseLevel;
1809 if (testPagesAllocated) 1812 if (testPagesAllocated)
1810 EXPECT_EQ(Heap::allocatedSpace(), 0ul); 1813 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul);
1811 1814
1812 size_t big = 1008; 1815 size_t big = 1008;
1813 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big); 1816 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create( big);
1814 total += big; 1817 total += big;
1815 slack += 4; 1818 slack += 4;
1816 1819
1817 size_t persistentCount = 0; 1820 size_t persistentCount = 0;
1818 const size_t numPersistents = 100000; 1821 const size_t numPersistents = 100000;
1819 Persistent<DynamicallySizedObject>* persistents[numPersistents]; 1822 Persistent<DynamicallySizedObject>* persistents[numPersistents];
1820 1823
1821 for (int i = 0; i < 1000; i++) { 1824 for (int i = 0; i < 1000; i++) {
1822 size_t size = 128 + i * 8; 1825 size_t size = 128 + i * 8;
1823 total += size; 1826 total += size;
1824 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size)); 1827 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>( DynamicallySizedObject::create(size));
1825 slack += 4; 1828 slack += 4;
1826 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s lack); 1829 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1827 if (testPagesAllocated) 1830 if (testPagesAllocated)
1828 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); 1831 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1829 } 1832 }
1830 1833
1831 { 1834 {
1832 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); 1835 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32));
1833 slack += 4; 1836 slack += 4;
1834 memset(alloc32b, 40, 32); 1837 memset(alloc32b, 40, 32);
1835 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); 1838 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64));
1836 slack += 4; 1839 slack += 4;
1837 memset(alloc64b, 27, 64); 1840 memset(alloc64b, 27, 64);
1838 EXPECT_TRUE(alloc32b != alloc64b); 1841 EXPECT_TRUE(alloc32b != alloc64b);
1839 1842
1840 total += 96; 1843 total += 96;
1841 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s lack); 1844 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), sl ack);
1842 if (testPagesAllocated) 1845 if (testPagesAllocated)
1843 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); 1846 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1844 } 1847 }
1845 1848
1846 clearOutOldGarbage(); 1849 clearOutOldGarbage();
1847 total -= 96; 1850 total -= 96;
1848 slack -= 8; 1851 slack -= 8;
1849 if (testPagesAllocated) 1852 if (testPagesAllocated)
1850 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); 1853 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1851 1854
1852 // Clear the persistent, so that the big area will be garbage collected. 1855 // Clear the persistent, so that the big area will be garbage collected.
1853 bigArea.release(); 1856 bigArea.release();
1854 clearOutOldGarbage(); 1857 clearOutOldGarbage();
1855 1858
1856 total -= big; 1859 total -= big;
1857 slack -= 4; 1860 slack -= 4;
1858 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack ); 1861 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1859 if (testPagesAllocated) 1862 if (testPagesAllocated)
1860 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); 1863 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1861 1864
1862 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack ); 1865 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), slack) ;
1863 if (testPagesAllocated) 1866 if (testPagesAllocated)
1864 EXPECT_EQ(0ul, Heap::allocatedSpace() & (blinkPageSize - 1)); 1867 EXPECT_EQ(0ul, heap.heapStats().allocatedSpace() & (blinkPageSize - 1));
1865 1868
1866 for (size_t i = 0; i < persistentCount; i++) { 1869 for (size_t i = 0; i < persistentCount; i++) {
1867 delete persistents[i]; 1870 delete persistents[i];
1868 persistents[i] = 0; 1871 persistents[i] = 0;
1869 } 1872 }
1870 1873
1871 uint8_t* address = reinterpret_cast<uint8_t*>(Heap::allocate<DynamicallySize dObject>(100)); 1874 uint8_t* address = reinterpret_cast<uint8_t*>(Heap::allocate<DynamicallySize dObject>(100));
1872 for (int i = 0; i < 100; i++) 1875 for (int i = 0; i < 100; i++)
1873 address[i] = i; 1876 address[i] = i;
1874 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject >(address, 100000)); 1877 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject >(address, 100000));
1875 for (int i = 0; i < 100; i++) 1878 for (int i = 0; i < 100; i++)
1876 EXPECT_EQ(address[i], i); 1879 EXPECT_EQ(address[i], i);
1877 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject >(address, 50)); 1880 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject >(address, 50));
1878 for (int i = 0; i < 50; i++) 1881 for (int i = 0; i < 50; i++)
1879 EXPECT_EQ(address[i], i); 1882 EXPECT_EQ(address[i], i);
1880 // This should be equivalent to free(address). 1883 // This should be equivalent to free(address).
1881 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec t>(address, 0)), 0ul); 1884 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec t>(address, 0)), 0ul);
1882 // This should be equivalent to malloc(0). 1885 // This should be equivalent to malloc(0).
1883 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec t>(0, 0)), 0ul); 1886 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec t>(0, 0)), 0ul);
1884 } 1887 }
1885 1888
1886 TEST(HeapTest, SimpleAllocation) 1889 TEST(HeapTest, SimpleAllocation)
1887 { 1890 {
1891 Heap& heap = ThreadState::current()->heap();
1888 clearOutOldGarbage(); 1892 clearOutOldGarbage();
1889 EXPECT_EQ(0ul, Heap::objectPayloadSizeForTesting()); 1893 EXPECT_EQ(0ul, heap.objectPayloadSizeForTesting());
1890 1894
1891 // Allocate an object in the heap. 1895 // Allocate an object in the heap.
1892 HeapAllocatedArray* array = new HeapAllocatedArray(); 1896 HeapAllocatedArray* array = new HeapAllocatedArray();
1893 EXPECT_TRUE(Heap::objectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray )); 1897 EXPECT_TRUE(heap.objectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray) );
1894 1898
1895 // Sanity check of the contents in the heap. 1899 // Sanity check of the contents in the heap.
1896 EXPECT_EQ(0, array->at(0)); 1900 EXPECT_EQ(0, array->at(0));
1897 EXPECT_EQ(42, array->at(42)); 1901 EXPECT_EQ(42, array->at(42));
1898 EXPECT_EQ(0, array->at(128)); 1902 EXPECT_EQ(0, array->at(128));
1899 EXPECT_EQ(999 % 128, array->at(999)); 1903 EXPECT_EQ(999 % 128, array->at(999));
1900 } 1904 }
1901 1905
1902 TEST(HeapTest, SimplePersistent) 1906 TEST(HeapTest, SimplePersistent)
1903 { 1907 {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 // for the conservative stack scan to find. 2215 // for the conservative stack scan to find.
2212 EXPECT_EQ(width, bars->getWidth()); 2216 EXPECT_EQ(width, bars->getWidth());
2213 } 2217 }
2214 EXPECT_EQ(Bars::width + 1, Bar::s_live); 2218 EXPECT_EQ(Bars::width + 1, Bar::s_live);
2215 preciselyCollectGarbage(); 2219 preciselyCollectGarbage();
2216 EXPECT_EQ(0u, Bar::s_live); 2220 EXPECT_EQ(0u, Bar::s_live);
2217 } 2221 }
2218 2222
2219 TEST(HeapTest, HashMapOfMembers) 2223 TEST(HeapTest, HashMapOfMembers)
2220 { 2224 {
2225 Heap& heap = ThreadState::current()->heap();
2221 IntWrapper::s_destructorCalls = 0; 2226 IntWrapper::s_destructorCalls = 0;
2222 2227
2223 clearOutOldGarbage(); 2228 clearOutOldGarbage();
2224 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); 2229 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2225 { 2230 {
2226 typedef HeapHashMap< 2231 typedef HeapHashMap<
2227 Member<IntWrapper>, 2232 Member<IntWrapper>,
2228 Member<IntWrapper>, 2233 Member<IntWrapper>,
2229 DefaultHash<Member<IntWrapper>>::Hash, 2234 DefaultHash<Member<IntWrapper>>::Hash,
2230 HashTraits<Member<IntWrapper>>, 2235 HashTraits<Member<IntWrapper>>,
2231 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; 2236 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap;
2232 2237
2233 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); 2238 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap();
2234 2239
2235 map->clear(); 2240 map->clear();
2236 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); 2241 size_t afterSetWasCreated = heap.objectPayloadSizeForTesting();
2237 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); 2242 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize);
2238 2243
2239 preciselyCollectGarbage(); 2244 preciselyCollectGarbage();
2240 size_t afterGC = Heap::objectPayloadSizeForTesting(); 2245 size_t afterGC = heap.objectPayloadSizeForTesting();
2241 EXPECT_EQ(afterGC, afterSetWasCreated); 2246 EXPECT_EQ(afterGC, afterSetWasCreated);
2242 2247
2243 // If the additions below cause garbage collections, these 2248 // If the additions below cause garbage collections, these
2244 // pointers should be found by conservative stack scanning. 2249 // pointers should be found by conservative stack scanning.
2245 IntWrapper* one(IntWrapper::create(1)); 2250 IntWrapper* one(IntWrapper::create(1));
2246 IntWrapper* anotherOne(IntWrapper::create(1)); 2251 IntWrapper* anotherOne(IntWrapper::create(1));
2247 2252
2248 map->add(one, one); 2253 map->add(one, one);
2249 2254
2250 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); 2255 size_t afterOneAdd = heap.objectPayloadSizeForTesting();
2251 EXPECT_TRUE(afterOneAdd > afterGC); 2256 EXPECT_TRUE(afterOneAdd > afterGC);
2252 2257
2253 HeapObjectIdentityMap::iterator it(map->begin()); 2258 HeapObjectIdentityMap::iterator it(map->begin());
2254 HeapObjectIdentityMap::iterator it2(map->begin()); 2259 HeapObjectIdentityMap::iterator it2(map->begin());
2255 ++it; 2260 ++it;
2256 ++it2; 2261 ++it2;
2257 2262
2258 map->add(anotherOne, one); 2263 map->add(anotherOne, one);
2259 2264
2260 // The addition above can cause an allocation of a new 2265 // The addition above can cause an allocation of a new
2261 // backing store. We therefore garbage collect before 2266 // backing store. We therefore garbage collect before
2262 // taking the heap stats in order to get rid of the old 2267 // taking the heap stats in order to get rid of the old
2263 // backing store. We make sure to not use conservative 2268 // backing store. We make sure to not use conservative
2264 // stack scanning as that could find a pointer to the 2269 // stack scanning as that could find a pointer to the
2265 // old backing. 2270 // old backing.
2266 preciselyCollectGarbage(); 2271 preciselyCollectGarbage();
2267 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); 2272 size_t afterAddAndGC = heap.objectPayloadSizeForTesting();
2268 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); 2273 EXPECT_TRUE(afterAddAndGC >= afterOneAdd);
2269 2274
2270 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct. 2275 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin ct.
2271 2276
2272 preciselyCollectGarbage(); 2277 preciselyCollectGarbage();
2273 EXPECT_TRUE(map->contains(one)); 2278 EXPECT_TRUE(map->contains(one));
2274 EXPECT_TRUE(map->contains(anotherOne)); 2279 EXPECT_TRUE(map->contains(anotherOne));
2275 2280
2276 IntWrapper* gotten(map->get(one)); 2281 IntWrapper* gotten(map->get(one));
2277 EXPECT_EQ(gotten->value(), one->value()); 2282 EXPECT_EQ(gotten->value(), one->value());
2278 EXPECT_EQ(gotten, one); 2283 EXPECT_EQ(gotten, one);
2279 2284
2280 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); 2285 size_t afterGC2 = heap.objectPayloadSizeForTesting();
2281 EXPECT_EQ(afterGC2, afterAddAndGC); 2286 EXPECT_EQ(afterGC2, afterAddAndGC);
2282 2287
2283 IntWrapper* dozen = 0; 2288 IntWrapper* dozen = 0;
2284 2289
2285 for (int i = 1; i < 1000; i++) { // 999 iterations. 2290 for (int i = 1; i < 1000; i++) { // 999 iterations.
2286 IntWrapper* iWrapper(IntWrapper::create(i)); 2291 IntWrapper* iWrapper(IntWrapper::create(i));
2287 IntWrapper* iSquared(IntWrapper::create(i * i)); 2292 IntWrapper* iSquared(IntWrapper::create(i * i));
2288 map->add(iWrapper, iSquared); 2293 map->add(iWrapper, iSquared);
2289 if (i == 12) 2294 if (i == 12)
2290 dozen = iWrapper; 2295 dozen = iWrapper;
2291 } 2296 }
2292 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); 2297 size_t afterAdding1000 = heap.objectPayloadSizeForTesting();
2293 EXPECT_TRUE(afterAdding1000 > afterGC2); 2298 EXPECT_TRUE(afterAdding1000 > afterGC2);
2294 2299
2295 IntWrapper* gross(map->get(dozen)); 2300 IntWrapper* gross(map->get(dozen));
2296 EXPECT_EQ(gross->value(), 144); 2301 EXPECT_EQ(gross->value(), 144);
2297 2302
2298 // This should clear out any junk backings created by all the adds. 2303 // This should clear out any junk backings created by all the adds.
2299 preciselyCollectGarbage(); 2304 preciselyCollectGarbage();
2300 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); 2305 size_t afterGC3 = heap.objectPayloadSizeForTesting();
2301 EXPECT_TRUE(afterGC3 <= afterAdding1000); 2306 EXPECT_TRUE(afterGC3 <= afterAdding1000);
2302 } 2307 }
2303 2308
2304 preciselyCollectGarbage(); 2309 preciselyCollectGarbage();
2305 // The objects 'one', anotherOne, and the 999 other pairs. 2310 // The objects 'one', anotherOne, and the 999 other pairs.
2306 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); 2311 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000);
2307 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); 2312 size_t afterGC4 = heap.objectPayloadSizeForTesting();
2308 EXPECT_EQ(afterGC4, initialObjectPayloadSize); 2313 EXPECT_EQ(afterGC4, initialObjectPayloadSize);
2309 } 2314 }
2310 2315
2311 TEST(HeapTest, NestedAllocation) 2316 TEST(HeapTest, NestedAllocation)
2312 { 2317 {
2318 Heap& heap = ThreadState::current()->heap();
2313 clearOutOldGarbage(); 2319 clearOutOldGarbage();
2314 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); 2320 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2315 { 2321 {
2316 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create(); 2322 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll ocation::create();
2317 } 2323 }
2318 clearOutOldGarbage(); 2324 clearOutOldGarbage();
2319 size_t afterFree = Heap::objectPayloadSizeForTesting(); 2325 size_t afterFree = heap.objectPayloadSizeForTesting();
2320 EXPECT_TRUE(initialObjectPayloadSize == afterFree); 2326 EXPECT_TRUE(initialObjectPayloadSize == afterFree);
2321 } 2327 }
2322 2328
2323 TEST(HeapTest, LargeHeapObjects) 2329 TEST(HeapTest, LargeHeapObjects)
2324 { 2330 {
2331 Heap& heap = ThreadState::current()->heap();
2325 clearOutOldGarbage(); 2332 clearOutOldGarbage();
2326 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); 2333 size_t initialObjectPayloadSize = heap.objectPayloadSizeForTesting();
2327 size_t initialAllocatedSpace = Heap::allocatedSpace(); 2334 size_t initialAllocatedSpace = heap.heapStats().allocatedSpace();
2328 IntWrapper::s_destructorCalls = 0; 2335 IntWrapper::s_destructorCalls = 0;
2329 LargeHeapObject::s_destructorCalls = 0; 2336 LargeHeapObject::s_destructorCalls = 0;
2330 { 2337 {
2331 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated. 2338 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a llocated.
2332 Persistent<LargeHeapObject> object = LargeHeapObject::create(); 2339 Persistent<LargeHeapObject> object = LargeHeapObject::create();
2333 ASSERT(ThreadState::current()->findPageFromAddress(object)); 2340 ASSERT(ThreadState::current()->findPageFromAddress(object));
2334 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1)); 2341 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char *>(object.get()) + sizeof(LargeHeapObject) - 1));
2335 clearOutOldGarbage(); 2342 clearOutOldGarbage();
2336 size_t afterAllocation = Heap::allocatedSpace(); 2343 size_t afterAllocation = heap.heapStats().allocatedSpace();
2337 { 2344 {
2338 object->set(0, 'a'); 2345 object->set(0, 'a');
2339 EXPECT_EQ('a', object->get(0)); 2346 EXPECT_EQ('a', object->get(0));
2340 object->set(object->length() - 1, 'b'); 2347 object->set(object->length() - 1, 'b');
2341 EXPECT_EQ('b', object->get(object->length() - 1)); 2348 EXPECT_EQ('b', object->get(object->length() - 1));
2342 size_t expectedLargeHeapObjectPayloadSize = Heap::allocationSizeFrom Size(sizeof(LargeHeapObject)); 2349 size_t expectedLargeHeapObjectPayloadSize = Heap::allocationSizeFrom Size(sizeof(LargeHeapObject));
2343 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper); 2350 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz e + sizeof(IntWrapper);
2344 size_t actualObjectPayloadSize = Heap::objectPayloadSizeForTesting() - initialObjectPayloadSize; 2351 size_t actualObjectPayloadSize = heap.objectPayloadSizeForTesting() - initialObjectPayloadSize;
2345 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack); 2352 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s lack);
2346 // There is probably space for the IntWrapper in a heap page without 2353 // There is probably space for the IntWrapper in a heap page without
2347 // allocating extra pages. However, the IntWrapper allocation might cause 2354 // allocating extra pages. However, the IntWrapper allocation might cause
2348 // the addition of a heap page. 2355 // the addition of a heap page.
2349 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize; 2356 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte dLargeHeapObjectPayloadSize;
2350 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize; 2357 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec tAllocationSize;
2351 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize; 2358 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack + blinkPageSize;
2352 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); 2359 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation);
2353 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); 2360 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound);
2354 EXPECT_EQ(0, IntWrapper::s_destructorCalls); 2361 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
2355 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); 2362 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls);
2356 for (int i = 0; i < 10; i++) 2363 for (int i = 0; i < 10; i++)
2357 object = LargeHeapObject::create(); 2364 object = LargeHeapObject::create();
2358 } 2365 }
2359 clearOutOldGarbage(); 2366 clearOutOldGarbage();
2360 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); 2367 EXPECT_TRUE(heap.heapStats().allocatedSpace() == afterAllocation);
2361 EXPECT_EQ(10, IntWrapper::s_destructorCalls); 2368 EXPECT_EQ(10, IntWrapper::s_destructorCalls);
2362 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); 2369 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls);
2363 } 2370 }
2364 clearOutOldGarbage(); 2371 clearOutOldGarbage();
2365 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting()) ; 2372 EXPECT_TRUE(initialObjectPayloadSize == heap.objectPayloadSizeForTesting());
2366 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); 2373 EXPECT_TRUE(initialAllocatedSpace == heap.heapStats().allocatedSpace());
2367 EXPECT_EQ(11, IntWrapper::s_destructorCalls); 2374 EXPECT_EQ(11, IntWrapper::s_destructorCalls);
2368 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); 2375 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls);
2369 preciselyCollectGarbage(); 2376 preciselyCollectGarbage();
2370 } 2377 }
2371 2378
2372 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; 2379 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
2373 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; 2380 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped;
2374 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; 2381 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong;
2375 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; 2382 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak;
2376 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; 2383 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
3589 RefCountedAndGarbageCollected2::s_destructorCalls = 0; 3596 RefCountedAndGarbageCollected2::s_destructorCalls = 0;
3590 { 3597 {
3591 RefCountedAndGarbageCollected* pointer1 = 0; 3598 RefCountedAndGarbageCollected* pointer1 = 0;
3592 RefCountedAndGarbageCollected2* pointer2 = 0; 3599 RefCountedAndGarbageCollected2* pointer2 = 0;
3593 { 3600 {
3594 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar bageCollected::create(); 3601 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar bageCollected::create();
3595 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa rbageCollected2::create(); 3602 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa rbageCollected2::create();
3596 pointer1 = object1.get(); 3603 pointer1 = object1.get();
3597 pointer2 = object2.get(); 3604 pointer2 = object2.get();
3598 void* objects[2] = { object1.get(), object2.get() }; 3605 void* objects[2] = { object1.get(), object2.get() };
3599 RefCountedGarbageCollectedVisitor visitor(2, objects); 3606 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSwe ep);
3607 RefCountedGarbageCollectedVisitor visitor(2, objects, &visitorScope) ;
3600 ThreadState::current()->visitPersistents(&visitor); 3608 ThreadState::current()->visitPersistents(&visitor);
3601 EXPECT_TRUE(visitor.validate()); 3609 EXPECT_TRUE(visitor.validate());
3602
3603 conservativelyCollectGarbage();
3604 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3605 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3606 } 3610 }
3607 conservativelyCollectGarbage(); 3611 conservativelyCollectGarbage();
3608 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); 3612 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3609 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); 3613 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3610 3614
3611 // At this point, the reference counts of object1 and object2 are 0. 3615 conservativelyCollectGarbage();
3612 // Only pointer1 and pointer2 keep references to object1 and object2. 3616 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3613 void* objects[] = { 0 }; 3617 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3614 RefCountedGarbageCollectedVisitor visitor(0, objects); 3618
3615 ThreadState::current()->visitPersistents(&visitor); 3619 {
3616 EXPECT_TRUE(visitor.validate()); 3620 // At this point, the reference counts of object1 and object2 are 0.
3621 // Only pointer1 and pointer2 keep references to object1 and object2 .
3622 void* objects[] = { 0 };
3623 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSwe ep);
3624 RefCountedGarbageCollectedVisitor visitor(0, objects, &visitorScope) ;
3625 ThreadState::current()->visitPersistents(&visitor);
3626 EXPECT_TRUE(visitor.validate());
3627 }
3617 3628
3618 { 3629 {
3619 Persistent<RefCountedAndGarbageCollected> object1(pointer1); 3630 Persistent<RefCountedAndGarbageCollected> object1(pointer1);
3620 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); 3631 Persistent<RefCountedAndGarbageCollected2> object2(pointer2);
3621 void* objects[2] = { object1.get(), object2.get() }; 3632 void* objects[2] = { object1.get(), object2.get() };
3622 RefCountedGarbageCollectedVisitor visitor(2, objects); 3633 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSwe ep);
3634 RefCountedGarbageCollectedVisitor visitor(2, objects, &visitorScope) ;
3623 ThreadState::current()->visitPersistents(&visitor); 3635 ThreadState::current()->visitPersistents(&visitor);
3624 EXPECT_TRUE(visitor.validate()); 3636 EXPECT_TRUE(visitor.validate());
3625
3626 conservativelyCollectGarbage();
3627 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3628 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3629 } 3637 }
3638 conservativelyCollectGarbage();
3639 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3640 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3630 3641
3631 conservativelyCollectGarbage(); 3642 conservativelyCollectGarbage();
3632 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); 3643 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3633 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); 3644 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3634 } 3645 }
3635 3646
3636 preciselyCollectGarbage(); 3647 preciselyCollectGarbage();
3637 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); 3648 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3638 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); 3649 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls);
3639 } 3650 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3756 { 3767 {
3757 Persistent<Bar> barPersistent = Bar::create(); 3768 Persistent<Bar> barPersistent = Bar::create();
3758 Persistent<Foo> fooPersistent = Foo::create(barPersistent); 3769 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
3759 EXPECT_TRUE(barPersistent != fooPersistent); 3770 EXPECT_TRUE(barPersistent != fooPersistent);
3760 barPersistent = fooPersistent; 3771 barPersistent = fooPersistent;
3761 EXPECT_TRUE(barPersistent == fooPersistent); 3772 EXPECT_TRUE(barPersistent == fooPersistent);
3762 } 3773 }
3763 3774
3764 TEST(HeapTest, CheckAndMarkPointer) 3775 TEST(HeapTest, CheckAndMarkPointer)
3765 { 3776 {
3777 Heap& heap = ThreadState::current()->heap();
3766 clearOutOldGarbage(); 3778 clearOutOldGarbage();
3767 3779
3768 Vector<Address> objectAddresses; 3780 Vector<Address> objectAddresses;
3769 Vector<Address> endAddresses; 3781 Vector<Address> endAddresses;
3770 Address largeObjectAddress; 3782 Address largeObjectAddress;
3771 Address largeObjectEndAddress; 3783 Address largeObjectEndAddress;
3772 CountingVisitor visitor;
3773 for (int i = 0; i < 10; i++) { 3784 for (int i = 0; i < 10; i++) {
3774 SimpleObject* object = SimpleObject::create(); 3785 SimpleObject* object = SimpleObject::create();
3775 Address objectAddress = reinterpret_cast<Address>(object); 3786 Address objectAddress = reinterpret_cast<Address>(object);
3776 objectAddresses.append(objectAddress); 3787 objectAddresses.append(objectAddress);
3777 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1); 3788 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1);
3778 } 3789 }
3779 LargeHeapObject* largeObject = LargeHeapObject::create(); 3790 LargeHeapObject* largeObject = LargeHeapObject::create();
3780 largeObjectAddress = reinterpret_cast<Address>(largeObject); 3791 largeObjectAddress = reinterpret_cast<Address>(largeObject);
3781 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; 3792 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1;
3782 3793
3783 // This is a low-level test where we call checkAndMarkPointer. This method 3794 // This is a low-level test where we call checkAndMarkPointer. This method
3784 // causes the object start bitmap to be computed which requires the heap 3795 // causes the object start bitmap to be computed which requires the heap
3785 // to be in a consistent state (e.g. the free allocation area must be put 3796 // to be in a consistent state (e.g. the free allocation area must be put
3786 // into a free list header). However when we call makeConsistentForGC it 3797 // into a free list header). However when we call makeConsistentForGC it
3787 // also clears out the freelists so we have to rebuild those before trying 3798 // also clears out the freelists so we have to rebuild those before trying
3788 // to allocate anything again. We do this by forcing a GC after doing the 3799 // to allocate anything again. We do this by forcing a GC after doing the
3789 // checkAndMarkPointer tests. 3800 // checkAndMarkPointer tests.
3790 { 3801 {
3802 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSweep);
3803 CountingVisitor visitor(&visitorScope);
3791 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3804 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3792 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads. 3805 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
3793 Heap::flushHeapDoesNotContainCache(); 3806 heap.flushHeapDoesNotContainCache();
3794 for (size_t i = 0; i < objectAddresses.size(); i++) { 3807 for (size_t i = 0; i < objectAddresses.size(); i++) {
3795 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i])) ; 3808 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i]));
3796 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); 3809 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i]));
3797 } 3810 }
3798 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); 3811 EXPECT_EQ(objectAddresses.size() * 2, visitor.count());
3799 visitor.reset(); 3812 visitor.reset();
3800 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); 3813 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress));
3801 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); 3814 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress));
3802 EXPECT_EQ(2ul, visitor.count()); 3815 EXPECT_EQ(2ul, visitor.count());
3803 visitor.reset(); 3816 visitor.reset();
3804 } 3817 }
3805 // This forces a GC without stack scanning which results in the objects 3818 // This forces a GC without stack scanning which results in the objects
3806 // being collected. This will also rebuild the above mentioned freelists, 3819 // being collected. This will also rebuild the above mentioned freelists,
3807 // however we don't rely on that below since we don't have any allocations. 3820 // however we don't rely on that below since we don't have any allocations.
3808 clearOutOldGarbage(); 3821 clearOutOldGarbage();
3809 { 3822 {
3823 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSweep);
3824 CountingVisitor visitor(&visitorScope);
3810 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3825 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3811 EXPECT_TRUE(scope.allThreadsParked()); 3826 EXPECT_TRUE(scope.allThreadsParked());
3812 Heap::flushHeapDoesNotContainCache(); 3827 heap.flushHeapDoesNotContainCache();
3813 for (size_t i = 0; i < objectAddresses.size(); i++) { 3828 for (size_t i = 0; i < objectAddresses.size(); i++) {
3814 // We would like to assert that checkAndMarkPointer returned false 3829 // We would like to assert that checkAndMarkPointer returned false
3815 // here because the pointers no longer point into a valid object 3830 // here because the pointers no longer point into a valid object
3816 // (it's been freed by the GCs. But checkAndMarkPointer will return 3831 // (it's been freed by the GCs. But checkAndMarkPointer will return
3817 // true for any pointer that points into a heap page, regardless of 3832 // true for any pointer that points into a heap page, regardless of
3818 // whether it points at a valid object (this ensures the 3833 // whether it points at a valid object (this ensures the
3819 // correctness of the page-based on-heap address caches), so we 3834 // correctness of the page-based on-heap address caches), so we
3820 // can't make that assert. 3835 // can't make that assert.
3821 Heap::checkAndMarkPointer(&visitor, objectAddresses[i]); 3836 heap.checkAndMarkPointer(&visitor, objectAddresses[i]);
3822 Heap::checkAndMarkPointer(&visitor, endAddresses[i]); 3837 heap.checkAndMarkPointer(&visitor, endAddresses[i]);
3823 } 3838 }
3824 EXPECT_EQ(0ul, visitor.count()); 3839 EXPECT_EQ(0ul, visitor.count());
3825 Heap::checkAndMarkPointer(&visitor, largeObjectAddress); 3840 heap.checkAndMarkPointer(&visitor, largeObjectAddress);
3826 Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress); 3841 heap.checkAndMarkPointer(&visitor, largeObjectEndAddress);
3827 EXPECT_EQ(0ul, visitor.count()); 3842 EXPECT_EQ(0ul, visitor.count());
3828 } 3843 }
3829 // This round of GC is important to make sure that the object start 3844 // This round of GC is important to make sure that the object start
3830 // bitmap are cleared out and that the free lists are rebuild. 3845 // bitmap are cleared out and that the free lists are rebuild.
3831 clearOutOldGarbage(); 3846 clearOutOldGarbage();
3832 } 3847 }
3833 3848
3834 TEST(HeapTest, PersistentHeapCollectionTypes) 3849 TEST(HeapTest, PersistentHeapCollectionTypes)
3835 { 3850 {
3836 IntWrapper::s_destructorCalls = 0; 3851 IntWrapper::s_destructorCalls = 0;
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
4737 static void sleeperMainFunc() 4752 static void sleeperMainFunc()
4738 { 4753 {
4739 ThreadState::attach(); 4754 ThreadState::attach();
4740 s_sleeperRunning = true; 4755 s_sleeperRunning = true;
4741 4756
4742 // Simulate a long running op that is not entering a safepoint. 4757 // Simulate a long running op that is not entering a safepoint.
4743 while (!s_sleeperDone) { 4758 while (!s_sleeperDone) {
4744 testing::yieldCurrentThread(); 4759 testing::yieldCurrentThread();
4745 } 4760 }
4746 4761
4747 ThreadState::detach(); 4762 ThreadState::detachCurrentThread();
4748 s_sleeperRunning = false; 4763 s_sleeperRunning = false;
4749 } 4764 }
4750 4765
4751 static volatile bool s_sleeperRunning; 4766 static volatile bool s_sleeperRunning;
4752 static volatile bool s_sleeperDone; 4767 static volatile bool s_sleeperDone;
4753 }; 4768 };
4754 4769
4755 volatile bool GCParkingThreadTester::s_sleeperRunning = false; 4770 volatile bool GCParkingThreadTester::s_sleeperRunning = false;
4756 volatile bool GCParkingThreadTester::s_sleeperDone = false; 4771 volatile bool GCParkingThreadTester::s_sleeperDone = false;
4757 4772
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
5448 5463
5449 // Wake up the main thread when done sweeping. 5464 // Wake up the main thread when done sweeping.
5450 wakeMainThread(); 5465 wakeMainThread();
5451 5466
5452 // Wait with detach until the main thread says so. This is not strictly 5467 // Wait with detach until the main thread says so. This is not strictly
5453 // necessary, but it means the worker thread will not do its thread loca l 5468 // necessary, but it means the worker thread will not do its thread loca l
5454 // GCs just yet, making it easier to reason about that no new GC has occ urred 5469 // GCs just yet, making it easier to reason about that no new GC has occ urred
5455 // and the above sweep was the one finalizing the worker object. 5470 // and the above sweep was the one finalizing the worker object.
5456 parkWorkerThread(); 5471 parkWorkerThread();
5457 5472
5458 ThreadState::detach(); 5473 ThreadState::detachCurrentThread();
5459 } 5474 }
5460 5475
5461 static volatile uintptr_t s_workerObjectPointer; 5476 static volatile uintptr_t s_workerObjectPointer;
5462 }; 5477 };
5463 5478
5464 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; 5479 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0;
5465 5480
5466 TEST(HeapTest, ObjectDeadBit) 5481 TEST(HeapTest, ObjectDeadBit)
5467 { 5482 {
5468 DeadBitTester::test(); 5483 DeadBitTester::test();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5561 EXPECT_EQ(32, it->value->value()); 5576 EXPECT_EQ(32, it->value->value());
5562 } 5577 }
5563 5578
5564 // Disregarding the iterator but keeping the collection alive 5579 // Disregarding the iterator but keeping the collection alive
5565 // with a persistent should lead to weak processing. 5580 // with a persistent should lead to weak processing.
5566 preciselyCollectGarbage(); 5581 preciselyCollectGarbage();
5567 EXPECT_EQ(0u, collection->size()); 5582 EXPECT_EQ(0u, collection->size());
5568 } 5583 }
5569 5584
5570 wakeMainThread(); 5585 wakeMainThread();
5571 ThreadState::detach(); 5586 ThreadState::detachCurrentThread();
5572 } 5587 }
5573 5588
5574 static volatile uintptr_t s_workerObjectPointer; 5589 static volatile uintptr_t s_workerObjectPointer;
5575 }; 5590 };
5576 5591
5577 TEST(HeapTest, ThreadedStrongification) 5592 TEST(HeapTest, ThreadedStrongification)
5578 { 5593 {
5579 ThreadedStrongificationTester::test(); 5594 ThreadedStrongificationTester::test();
5580 } 5595 }
5581 5596
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5729 parkWorkerThread(); 5744 parkWorkerThread();
5730 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack); 5745 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH eapPointersOnStack);
5731 5746
5732 // We won't get here unless the lock is recursive since the sweep done 5747 // We won't get here unless the lock is recursive since the sweep done
5733 // in the constructor of SafePointAwareMutexLocker after 5748 // in the constructor of SafePointAwareMutexLocker after
5734 // getting the lock will not complete given the "dlo" destructor is 5749 // getting the lock will not complete given the "dlo" destructor is
5735 // waiting to get the same lock. 5750 // waiting to get the same lock.
5736 // Tell the main thread the worker has done its sweep. 5751 // Tell the main thread the worker has done its sweep.
5737 wakeMainThread(); 5752 wakeMainThread();
5738 5753
5739 ThreadState::detach(); 5754 ThreadState::detachCurrentThread();
5740 } 5755 }
5741 5756
5742 static volatile IntWrapper* s_workerObjectPointer; 5757 static volatile IntWrapper* s_workerObjectPointer;
5743 }; 5758 };
5744 5759
5745 TEST(HeapTest, RecursiveMutex) 5760 TEST(HeapTest, RecursiveMutex)
5746 { 5761 {
5747 RecursiveLockingTester::test(); 5762 RecursiveLockingTester::test();
5748 } 5763 }
5749 5764
(...skipping 27 matching lines...) Expand all
5777 // on one of the main thread's heaps does not upset the CTP invalidation 5792 // on one of the main thread's heaps does not upset the CTP invalidation
5778 // pass that ThreadState::detach() performs. 5793 // pass that ThreadState::detach() performs.
5779 ThreadState::attach(); 5794 ThreadState::attach();
5780 5795
5781 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(43)); 5796 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(43));
5782 5797
5783 // Wait for the main thread to detach. 5798 // Wait for the main thread to detach.
5784 wakeMainThread(); 5799 wakeMainThread();
5785 parkWorkerThread(); 5800 parkWorkerThread();
5786 5801
5787 ThreadState::detach(); 5802 ThreadState::detachCurrentThread();
5788 wakeMainThread(); 5803 wakeMainThread();
5789 } 5804 }
5790 }; 5805 };
5791 5806
5792 TEST(HeapTest, CrossThreadPersistentOnMainThread) 5807 TEST(HeapTest, CrossThreadPersistentOnMainThread)
5793 { 5808 {
5794 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(42)); 5809 CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(42));
5795 CrossThreadPersistentOnMainThreadTester::test(); 5810 CrossThreadPersistentOnMainThreadTester::test();
5796 } 5811 }
5797 5812
(...skipping 15 matching lines...) Expand all
5813 DISALLOW_NEW(); 5828 DISALLOW_NEW();
5814 public: 5829 public:
5815 PartObject() : m_obj(SimpleObject::create()) { } 5830 PartObject() : m_obj(SimpleObject::create()) { }
5816 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } 5831 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); }
5817 private: 5832 private:
5818 Member<SimpleObject> m_obj; 5833 Member<SimpleObject> m_obj;
5819 }; 5834 };
5820 5835
5821 TEST(HeapTest, TraceIfNeeded) 5836 TEST(HeapTest, TraceIfNeeded)
5822 { 5837 {
5823 CountingVisitor visitor; 5838 VisitorScope visitorScope(ThreadState::current(), BlinkGC::GCWithSweep);
5839 CountingVisitor visitor(&visitorScope);
5824 5840
5825 { 5841 {
5826 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = TraceIfNeededTester <RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); 5842 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = TraceIfNeededTester <RefPtr<OffHeapInt>>::create(OffHeapInt::create(42));
5827 visitor.reset(); 5843 visitor.reset();
5828 m_offHeap->trace(&visitor); 5844 m_offHeap->trace(&visitor);
5829 EXPECT_EQ(0u, visitor.count()); 5845 EXPECT_EQ(0u, visitor.count());
5830 } 5846 }
5831 5847
5832 { 5848 {
5833 TraceIfNeededTester<PartObject>* m_part = TraceIfNeededTester<PartObject >::create(); 5849 TraceIfNeededTester<PartObject>* m_part = TraceIfNeededTester<PartObject >::create();
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
6447 *object = DestructorLockingObject::create(); 6463 *object = DestructorLockingObject::create();
6448 wakeMainThread(); 6464 wakeMainThread();
6449 parkWorkerThread(); 6465 parkWorkerThread();
6450 6466
6451 // Step 4: Run a GC. 6467 // Step 4: Run a GC.
6452 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B linkGC::ForcedGC); 6468 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B linkGC::ForcedGC);
6453 wakeMainThread(); 6469 wakeMainThread();
6454 parkWorkerThread(); 6470 parkWorkerThread();
6455 6471
6456 // Step 6: Finish. 6472 // Step 6: Finish.
6457 ThreadState::detach(); 6473 ThreadState::detachCurrentThread();
6458 wakeMainThread(); 6474 wakeMainThread();
6459 } 6475 }
6460 6476
6461 } // anonymous namespace 6477 } // anonymous namespace
6462 6478
6463 TEST(HeapTest, CrossThreadWeakPersistent) 6479 TEST(HeapTest, CrossThreadWeakPersistent)
6464 { 6480 {
6465 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread, 6481 // Create an object in the worker thread, have a CrossThreadWeakPersistent p ointing to it on the main thread,
6466 // clear the reference in the worker thread, run a GC in the worker thread, and see if the 6482 // clear the reference in the worker thread, run a GC in the worker thread, and see if the
6467 // CrossThreadWeakPersistent is cleared. 6483 // CrossThreadWeakPersistent is cleared.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6526 EXPECT_EQ(1u, vector2.size()); 6542 EXPECT_EQ(1u, vector2.size());
6527 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables 6543 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables
6528 // Vector<>s with inline capacity, remove. 6544 // Vector<>s with inline capacity, remove.
6529 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) 6545 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
6530 EXPECT_EQ(16u, vector1.capacity()); 6546 EXPECT_EQ(16u, vector1.capacity());
6531 EXPECT_EQ(16u, vector2.capacity()); 6547 EXPECT_EQ(16u, vector2.capacity());
6532 #endif 6548 #endif
6533 } 6549 }
6534 6550
6535 } // namespace blink 6551 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698