| 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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 #endif | 342 #endif |
| 343 void registerWeakCellWithCallback(void**, WeakCallback) override {} | 343 void registerWeakCellWithCallback(void**, WeakCallback) override {} |
| 344 bool ensureMarked(const void* objectPointer) override { | 344 bool ensureMarked(const void* objectPointer) override { |
| 345 if (!objectPointer || | 345 if (!objectPointer || |
| 346 HeapObjectHeader::fromPayload(objectPointer)->isMarked()) | 346 HeapObjectHeader::fromPayload(objectPointer)->isMarked()) |
| 347 return false; | 347 return false; |
| 348 markNoTracing(objectPointer); | 348 markNoTracing(objectPointer); |
| 349 return true; | 349 return true; |
| 350 } | 350 } |
| 351 | 351 |
| 352 void registerMovingObjectReference(MovableReference*) override {} | |
| 353 | |
| 354 void registerMovingObjectCallback(MovableReference, | |
| 355 MovingObjectCallback, | |
| 356 void*) override {} | |
| 357 | |
| 358 size_t count() { return m_count; } | 352 size_t count() { return m_count; } |
| 359 void reset() { m_count = 0; } | 353 void reset() { m_count = 0; } |
| 360 | 354 |
| 361 private: | 355 private: |
| 362 StackFrameDepthScope m_scope; | 356 StackFrameDepthScope m_scope; |
| 363 size_t m_count; | 357 size_t m_count; |
| 364 }; | 358 }; |
| 365 | 359 |
| 366 #undef DEFINE_VISITOR_METHODS | 360 #undef DEFINE_VISITOR_METHODS |
| 367 | 361 |
| (...skipping 3396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3764 RefCountedAndGarbageCollected* pointer1 = 0; | 3758 RefCountedAndGarbageCollected* pointer1 = 0; |
| 3765 RefCountedAndGarbageCollected2* pointer2 = 0; | 3759 RefCountedAndGarbageCollected2* pointer2 = 0; |
| 3766 { | 3760 { |
| 3767 Persistent<RefCountedAndGarbageCollected> object1 = | 3761 Persistent<RefCountedAndGarbageCollected> object1 = |
| 3768 RefCountedAndGarbageCollected::create(); | 3762 RefCountedAndGarbageCollected::create(); |
| 3769 Persistent<RefCountedAndGarbageCollected2> object2 = | 3763 Persistent<RefCountedAndGarbageCollected2> object2 = |
| 3770 RefCountedAndGarbageCollected2::create(); | 3764 RefCountedAndGarbageCollected2::create(); |
| 3771 pointer1 = object1.get(); | 3765 pointer1 = object1.get(); |
| 3772 pointer2 = object2.get(); | 3766 pointer2 = object2.get(); |
| 3773 void* objects[2] = {object1.get(), object2.get()}; | 3767 void* objects[2] = {object1.get(), object2.get()}; |
| 3774 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); | |
| 3775 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, | 3768 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, |
| 3776 objects); | 3769 objects); |
| 3777 ThreadState::current()->visitPersistents(&visitor); | 3770 ThreadState::current()->visitPersistents(&visitor); |
| 3778 EXPECT_TRUE(visitor.validate()); | 3771 EXPECT_TRUE(visitor.validate()); |
| 3779 } | 3772 } |
| 3780 conservativelyCollectGarbage(); | 3773 conservativelyCollectGarbage(); |
| 3781 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3774 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3782 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3775 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3783 | 3776 |
| 3784 conservativelyCollectGarbage(); | 3777 conservativelyCollectGarbage(); |
| 3785 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3778 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3786 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3779 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3787 | 3780 |
| 3788 { | 3781 { |
| 3789 // At this point, the reference counts of object1 and object2 are 0. | 3782 // At this point, the reference counts of object1 and object2 are 0. |
| 3790 // Only pointer1 and pointer2 keep references to object1 and object2. | 3783 // Only pointer1 and pointer2 keep references to object1 and object2. |
| 3791 void* objects[] = {0}; | 3784 void* objects[] = {0}; |
| 3792 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); | |
| 3793 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 0, | 3785 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 0, |
| 3794 objects); | 3786 objects); |
| 3795 ThreadState::current()->visitPersistents(&visitor); | 3787 ThreadState::current()->visitPersistents(&visitor); |
| 3796 EXPECT_TRUE(visitor.validate()); | 3788 EXPECT_TRUE(visitor.validate()); |
| 3797 } | 3789 } |
| 3798 | 3790 |
| 3799 { | 3791 { |
| 3800 Persistent<RefCountedAndGarbageCollected> object1(pointer1); | 3792 Persistent<RefCountedAndGarbageCollected> object1(pointer1); |
| 3801 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); | 3793 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); |
| 3802 void* objects[2] = {object1.get(), object2.get()}; | 3794 void* objects[2] = {object1.get(), object2.get()}; |
| 3803 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); | |
| 3804 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, | 3795 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, |
| 3805 objects); | 3796 objects); |
| 3806 ThreadState::current()->visitPersistents(&visitor); | 3797 ThreadState::current()->visitPersistents(&visitor); |
| 3807 EXPECT_TRUE(visitor.validate()); | 3798 EXPECT_TRUE(visitor.validate()); |
| 3808 } | 3799 } |
| 3809 conservativelyCollectGarbage(); | 3800 conservativelyCollectGarbage(); |
| 3810 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3801 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
| 3811 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3802 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
| 3812 | 3803 |
| 3813 conservativelyCollectGarbage(); | 3804 conservativelyCollectGarbage(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3957 | 3948 |
| 3958 // This is a low-level test where we call checkAndMarkPointer. This method | 3949 // This is a low-level test where we call checkAndMarkPointer. This method |
| 3959 // causes the object start bitmap to be computed which requires the heap | 3950 // causes the object start bitmap to be computed which requires the heap |
| 3960 // to be in a consistent state (e.g. the free allocation area must be put | 3951 // to be in a consistent state (e.g. the free allocation area must be put |
| 3961 // into a free list header). However when we call makeConsistentForGC it | 3952 // into a free list header). However when we call makeConsistentForGC it |
| 3962 // also clears out the freelists so we have to rebuild those before trying | 3953 // also clears out the freelists so we have to rebuild those before trying |
| 3963 // to allocate anything again. We do this by forcing a GC after doing the | 3954 // to allocate anything again. We do this by forcing a GC after doing the |
| 3964 // checkAndMarkPointer tests. | 3955 // checkAndMarkPointer tests. |
| 3965 { | 3956 { |
| 3966 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3957 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3967 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); | |
| 3968 CountingVisitor visitor(ThreadState::current()); | 3958 CountingVisitor visitor(ThreadState::current()); |
| 3969 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not | 3959 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not |
| 3970 // park all threads. | 3960 // park all threads. |
| 3971 heap.flushHeapDoesNotContainCache(); | 3961 heap.flushHeapDoesNotContainCache(); |
| 3972 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3962 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3973 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); | 3963 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); |
| 3974 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); | 3964 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); |
| 3975 } | 3965 } |
| 3976 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 3966 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
| 3977 visitor.reset(); | 3967 visitor.reset(); |
| 3978 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); | 3968 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); |
| 3979 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 3969 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); |
| 3980 EXPECT_EQ(2ul, visitor.count()); | 3970 EXPECT_EQ(2ul, visitor.count()); |
| 3981 visitor.reset(); | 3971 visitor.reset(); |
| 3982 } | 3972 } |
| 3983 // This forces a GC without stack scanning which results in the objects | 3973 // This forces a GC without stack scanning which results in the objects |
| 3984 // being collected. This will also rebuild the above mentioned freelists, | 3974 // being collected. This will also rebuild the above mentioned freelists, |
| 3985 // however we don't rely on that below since we don't have any allocations. | 3975 // however we don't rely on that below since we don't have any allocations. |
| 3986 clearOutOldGarbage(); | 3976 clearOutOldGarbage(); |
| 3987 { | 3977 { |
| 3988 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3978 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3989 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); | |
| 3990 CountingVisitor visitor(ThreadState::current()); | 3979 CountingVisitor visitor(ThreadState::current()); |
| 3991 EXPECT_TRUE(scope.allThreadsParked()); | 3980 EXPECT_TRUE(scope.allThreadsParked()); |
| 3992 heap.flushHeapDoesNotContainCache(); | 3981 heap.flushHeapDoesNotContainCache(); |
| 3993 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3982 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3994 // We would like to assert that checkAndMarkPointer returned false | 3983 // We would like to assert that checkAndMarkPointer returned false |
| 3995 // here because the pointers no longer point into a valid object | 3984 // here because the pointers no longer point into a valid object |
| 3996 // (it's been freed by the GCs. But checkAndMarkPointer will return | 3985 // (it's been freed by the GCs. But checkAndMarkPointer will return |
| 3997 // true for any pointer that points into a heap page, regardless of | 3986 // true for any pointer that points into a heap page, regardless of |
| 3998 // whether it points at a valid object (this ensures the | 3987 // whether it points at a valid object (this ensures the |
| 3999 // correctness of the page-based on-heap address caches), so we | 3988 // correctness of the page-based on-heap address caches), so we |
| (...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5878 | 5867 |
| 5879 public: | 5868 public: |
| 5880 PartObject() : m_obj(SimpleObject::create()) {} | 5869 PartObject() : m_obj(SimpleObject::create()) {} |
| 5881 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } | 5870 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } |
| 5882 | 5871 |
| 5883 private: | 5872 private: |
| 5884 Member<SimpleObject> m_obj; | 5873 Member<SimpleObject> m_obj; |
| 5885 }; | 5874 }; |
| 5886 | 5875 |
| 5887 TEST(HeapTest, TraceIfNeeded) { | 5876 TEST(HeapTest, TraceIfNeeded) { |
| 5888 ThreadState::GCForbiddenScope scope(ThreadState::current()); | |
| 5889 CountingVisitor visitor(ThreadState::current()); | 5877 CountingVisitor visitor(ThreadState::current()); |
| 5890 | 5878 |
| 5891 { | 5879 { |
| 5892 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = | 5880 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = |
| 5893 TraceIfNeededTester<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); | 5881 TraceIfNeededTester<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); |
| 5894 visitor.reset(); | 5882 visitor.reset(); |
| 5895 m_offHeap->trace(&visitor); | 5883 m_offHeap->trace(&visitor); |
| 5896 EXPECT_EQ(0u, visitor.count()); | 5884 EXPECT_EQ(0u, visitor.count()); |
| 5897 } | 5885 } |
| 5898 | 5886 |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6819 "HeapVector"); | 6807 "HeapVector"); |
| 6820 static_assert( | 6808 static_assert( |
| 6821 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, | 6809 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, |
| 6822 "HeapDeque"); | 6810 "HeapDeque"); |
| 6823 static_assert(WTF::IsGarbageCollectedType< | 6811 static_assert(WTF::IsGarbageCollectedType< |
| 6824 HeapTerminatedArray<Member<IntWrapper>>>::value, | 6812 HeapTerminatedArray<Member<IntWrapper>>>::value, |
| 6825 "HeapTerminatedArray"); | 6813 "HeapTerminatedArray"); |
| 6826 } | 6814 } |
| 6827 | 6815 |
| 6828 } // namespace blink | 6816 } // namespace blink |
| OLD | NEW |