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()); |
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 |