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 |