Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/WebKit/Source/platform/heap/HeapTest.cpp

Issue 2531973002: Simple BlinkGC heap compaction. (Closed)
Patch Set: add pointer alignment handling to SparseHeapBitmap Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698