| 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(ThreadState* state) |
| 286 : Visitor(Visitor::ThreadLocalMarking) | 286 : Visitor(state, Visitor::ThreadLocalMarking) |
| 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 int RefCountedAndGarbageCollected2::s_destructorCalls = 0; | 1026 int RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
| 1027 | 1027 |
| 1028 #define DEFINE_VISITOR_METHODS(Type) \ | 1028 #define DEFINE_VISITOR_METHODS(Type) \ |
| 1029 void mark(const Type* object, TraceCallback callback) override \ | 1029 void mark(const Type* object, TraceCallback callback) override \ |
| 1030 { \ | 1030 { \ |
| 1031 mark(object); \ | 1031 mark(object); \ |
| 1032 } \ | 1032 } \ |
| 1033 | 1033 |
| 1034 class RefCountedGarbageCollectedVisitor : public CountingVisitor { | 1034 class RefCountedGarbageCollectedVisitor : public CountingVisitor { |
| 1035 public: | 1035 public: |
| 1036 RefCountedGarbageCollectedVisitor(int expected, void** objects) | 1036 RefCountedGarbageCollectedVisitor(ThreadState* state, int expected, void** o
bjects) |
| 1037 : m_count(0) | 1037 : CountingVisitor(state) |
| 1038 , m_count(0) |
| 1038 , m_expectedCount(expected) | 1039 , m_expectedCount(expected) |
| 1039 , m_expectedObjects(objects) | 1040 , m_expectedObjects(objects) |
| 1040 { | 1041 { |
| 1041 } | 1042 } |
| 1042 | 1043 |
| 1043 void mark(const void* ptr) { markNoTrace(ptr); } | 1044 void mark(const void* ptr) { markNoTrace(ptr); } |
| 1044 | 1045 |
| 1045 virtual void markNoTrace(const void* ptr) | 1046 virtual void markNoTrace(const void* ptr) |
| 1046 { | 1047 { |
| 1047 if (!ptr) | 1048 if (!ptr) |
| (...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3589 RefCountedAndGarbageCollected2::s_destructorCalls = 0; | 3590 RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
| 3590 { | 3591 { |
| 3591 RefCountedAndGarbageCollected* pointer1 = 0; | 3592 RefCountedAndGarbageCollected* pointer1 = 0; |
| 3592 RefCountedAndGarbageCollected2* pointer2 = 0; | 3593 RefCountedAndGarbageCollected2* pointer2 = 0; |
| 3593 { | 3594 { |
| 3594 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); | 3595 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); |
| 3595 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); | 3596 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); |
| 3596 pointer1 = object1.get(); | 3597 pointer1 = object1.get(); |
| 3597 pointer2 = object2.get(); | 3598 pointer2 = object2.get(); |
| 3598 void* objects[2] = { object1.get(), object2.get() }; | 3599 void* objects[2] = { object1.get(), object2.get() }; |
| 3599 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3600 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2,
objects); |
| 3600 ThreadState::current()->visitPersistents(&visitor); | 3601 ThreadState::current()->visitPersistents(&visitor); |
| 3601 EXPECT_TRUE(visitor.validate()); | 3602 EXPECT_TRUE(visitor.validate()); |
| 3602 | |
| 3603 conservativelyCollectGarbage(); | |
| 3604 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | |
| 3605 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | |
| 3606 } | 3603 } |
| 3607 conservativelyCollectGarbage(); | 3604 conservativelyCollectGarbage(); |
| 3608 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3605 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3609 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3606 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3610 | 3607 |
| 3611 // At this point, the reference counts of object1 and object2 are 0. | 3608 conservativelyCollectGarbage(); |
| 3612 // Only pointer1 and pointer2 keep references to object1 and object2. | 3609 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3613 void* objects[] = { 0 }; | 3610 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3614 RefCountedGarbageCollectedVisitor visitor(0, objects); | 3611 |
| 3615 ThreadState::current()->visitPersistents(&visitor); | 3612 { |
| 3616 EXPECT_TRUE(visitor.validate()); | 3613 // At this point, the reference counts of object1 and object2 are 0. |
| 3614 // Only pointer1 and pointer2 keep references to object1 and object2
. |
| 3615 void* objects[] = { 0 }; |
| 3616 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 0,
objects); |
| 3617 ThreadState::current()->visitPersistents(&visitor); |
| 3618 EXPECT_TRUE(visitor.validate()); |
| 3619 } |
| 3617 | 3620 |
| 3618 { | 3621 { |
| 3619 Persistent<RefCountedAndGarbageCollected> object1(pointer1); | 3622 Persistent<RefCountedAndGarbageCollected> object1(pointer1); |
| 3620 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); | 3623 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); |
| 3621 void* objects[2] = { object1.get(), object2.get() }; | 3624 void* objects[2] = { object1.get(), object2.get() }; |
| 3622 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3625 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2,
objects); |
| 3623 ThreadState::current()->visitPersistents(&visitor); | 3626 ThreadState::current()->visitPersistents(&visitor); |
| 3624 EXPECT_TRUE(visitor.validate()); | 3627 EXPECT_TRUE(visitor.validate()); |
| 3625 | |
| 3626 conservativelyCollectGarbage(); | |
| 3627 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | |
| 3628 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | |
| 3629 } | 3628 } |
| 3629 conservativelyCollectGarbage(); |
| 3630 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3631 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3630 | 3632 |
| 3631 conservativelyCollectGarbage(); | 3633 conservativelyCollectGarbage(); |
| 3632 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3634 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3633 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3635 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3634 } | 3636 } |
| 3635 | 3637 |
| 3636 preciselyCollectGarbage(); | 3638 preciselyCollectGarbage(); |
| 3637 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3639 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3638 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); | 3640 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3639 } | 3641 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3762 } | 3764 } |
| 3763 | 3765 |
| 3764 TEST(HeapTest, CheckAndMarkPointer) | 3766 TEST(HeapTest, CheckAndMarkPointer) |
| 3765 { | 3767 { |
| 3766 clearOutOldGarbage(); | 3768 clearOutOldGarbage(); |
| 3767 | 3769 |
| 3768 Vector<Address> objectAddresses; | 3770 Vector<Address> objectAddresses; |
| 3769 Vector<Address> endAddresses; | 3771 Vector<Address> endAddresses; |
| 3770 Address largeObjectAddress; | 3772 Address largeObjectAddress; |
| 3771 Address largeObjectEndAddress; | 3773 Address largeObjectEndAddress; |
| 3772 CountingVisitor visitor; | |
| 3773 for (int i = 0; i < 10; i++) { | 3774 for (int i = 0; i < 10; i++) { |
| 3774 SimpleObject* object = SimpleObject::create(); | 3775 SimpleObject* object = SimpleObject::create(); |
| 3775 Address objectAddress = reinterpret_cast<Address>(object); | 3776 Address objectAddress = reinterpret_cast<Address>(object); |
| 3776 objectAddresses.append(objectAddress); | 3777 objectAddresses.append(objectAddress); |
| 3777 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1); | 3778 endAddresses.append(objectAddress + sizeof(SimpleObject) - 1); |
| 3778 } | 3779 } |
| 3779 LargeHeapObject* largeObject = LargeHeapObject::create(); | 3780 LargeHeapObject* largeObject = LargeHeapObject::create(); |
| 3780 largeObjectAddress = reinterpret_cast<Address>(largeObject); | 3781 largeObjectAddress = reinterpret_cast<Address>(largeObject); |
| 3781 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; | 3782 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; |
| 3782 | 3783 |
| 3783 // This is a low-level test where we call checkAndMarkPointer. This method | 3784 // 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 | 3785 // 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 | 3786 // 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 | 3787 // 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 | 3788 // 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 | 3789 // to allocate anything again. We do this by forcing a GC after doing the |
| 3789 // checkAndMarkPointer tests. | 3790 // checkAndMarkPointer tests. |
| 3790 { | 3791 { |
| 3791 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3792 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3793 CountingVisitor visitor(ThreadState::current()); |
| 3792 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. | 3794 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. |
| 3793 Heap::flushHeapDoesNotContainCache(); | 3795 Heap::flushHeapDoesNotContainCache(); |
| 3794 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3796 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3795 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
; | 3797 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
; |
| 3796 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); | 3798 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); |
| 3797 } | 3799 } |
| 3798 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 3800 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
| 3799 visitor.reset(); | 3801 visitor.reset(); |
| 3800 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); | 3802 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); |
| 3801 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 3803 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); |
| 3802 EXPECT_EQ(2ul, visitor.count()); | 3804 EXPECT_EQ(2ul, visitor.count()); |
| 3803 visitor.reset(); | 3805 visitor.reset(); |
| 3804 } | 3806 } |
| 3805 // This forces a GC without stack scanning which results in the objects | 3807 // This forces a GC without stack scanning which results in the objects |
| 3806 // being collected. This will also rebuild the above mentioned freelists, | 3808 // 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. | 3809 // however we don't rely on that below since we don't have any allocations. |
| 3808 clearOutOldGarbage(); | 3810 clearOutOldGarbage(); |
| 3809 { | 3811 { |
| 3810 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3812 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3813 CountingVisitor visitor(ThreadState::current()); |
| 3811 EXPECT_TRUE(scope.allThreadsParked()); | 3814 EXPECT_TRUE(scope.allThreadsParked()); |
| 3812 Heap::flushHeapDoesNotContainCache(); | 3815 Heap::flushHeapDoesNotContainCache(); |
| 3813 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3816 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3814 // We would like to assert that checkAndMarkPointer returned false | 3817 // We would like to assert that checkAndMarkPointer returned false |
| 3815 // here because the pointers no longer point into a valid object | 3818 // here because the pointers no longer point into a valid object |
| 3816 // (it's been freed by the GCs. But checkAndMarkPointer will return | 3819 // (it's been freed by the GCs. But checkAndMarkPointer will return |
| 3817 // true for any pointer that points into a heap page, regardless of | 3820 // true for any pointer that points into a heap page, regardless of |
| 3818 // whether it points at a valid object (this ensures the | 3821 // whether it points at a valid object (this ensures the |
| 3819 // correctness of the page-based on-heap address caches), so we | 3822 // correctness of the page-based on-heap address caches), so we |
| 3820 // can't make that assert. | 3823 // can't make that assert. |
| (...skipping 1992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5813 DISALLOW_NEW(); | 5816 DISALLOW_NEW(); |
| 5814 public: | 5817 public: |
| 5815 PartObject() : m_obj(SimpleObject::create()) { } | 5818 PartObject() : m_obj(SimpleObject::create()) { } |
| 5816 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } | 5819 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } |
| 5817 private: | 5820 private: |
| 5818 Member<SimpleObject> m_obj; | 5821 Member<SimpleObject> m_obj; |
| 5819 }; | 5822 }; |
| 5820 | 5823 |
| 5821 TEST(HeapTest, TraceIfNeeded) | 5824 TEST(HeapTest, TraceIfNeeded) |
| 5822 { | 5825 { |
| 5823 CountingVisitor visitor; | 5826 CountingVisitor visitor(ThreadState::current()); |
| 5824 | 5827 |
| 5825 { | 5828 { |
| 5826 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = TraceIfNeededTester
<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); | 5829 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = TraceIfNeededTester
<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); |
| 5827 visitor.reset(); | 5830 visitor.reset(); |
| 5828 m_offHeap->trace(&visitor); | 5831 m_offHeap->trace(&visitor); |
| 5829 EXPECT_EQ(0u, visitor.count()); | 5832 EXPECT_EQ(0u, visitor.count()); |
| 5830 } | 5833 } |
| 5831 | 5834 |
| 5832 { | 5835 { |
| 5833 TraceIfNeededTester<PartObject>* m_part = TraceIfNeededTester<PartObject
>::create(); | 5836 TraceIfNeededTester<PartObject>* m_part = TraceIfNeededTester<PartObject
>::create(); |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6526 EXPECT_EQ(1u, vector2.size()); | 6529 EXPECT_EQ(1u, vector2.size()); |
| 6527 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables | 6530 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables |
| 6528 // Vector<>s with inline capacity, remove. | 6531 // Vector<>s with inline capacity, remove. |
| 6529 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) | 6532 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) |
| 6530 EXPECT_EQ(16u, vector1.capacity()); | 6533 EXPECT_EQ(16u, vector1.capacity()); |
| 6531 EXPECT_EQ(16u, vector2.capacity()); | 6534 EXPECT_EQ(16u, vector2.capacity()); |
| 6532 #endif | 6535 #endif |
| 6533 } | 6536 } |
| 6534 | 6537 |
| 6535 } // namespace blink | 6538 } // namespace blink |
| OLD | NEW |