| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |