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