Index: third_party/WebKit/Source/platform/heap/HeapTest.cpp |
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp |
index 9969e20de01005536c9790c7545b50e395b641e1..3a85dc212a7dd06bdaf4a5b849bc44c26956979b 100644 |
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp |
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp |
@@ -305,60 +305,6 @@ class TestGCScope { |
bool m_parkedAllThreads; // False if we fail to park all threads |
}; |
-#define DEFINE_VISITOR_METHODS(Type) \ |
- void mark(const Type* object, TraceCallback callback) override { \ |
- if (object) \ |
- m_count++; \ |
- } \ |
- bool isMarked(const Type*) override { return false; } \ |
- bool ensureMarked(const Type* objectPointer) override { \ |
- return ensureMarked(objectPointer); \ |
- } |
- |
-class CountingVisitor : public Visitor { |
- public: |
- explicit CountingVisitor(ThreadState* state) |
- : Visitor(state, VisitorMarkingMode::ThreadLocalMarking), |
- m_scope(&state->heap().stackFrameDepth()), |
- m_count(0) {} |
- |
- void mark(const void* object, TraceCallback) override { |
- if (object) |
- m_count++; |
- } |
- |
- void markHeader(HeapObjectHeader* header, TraceCallback callback) override { |
- ASSERT(header->payload()); |
- m_count++; |
- } |
- |
- void registerDelayedMarkNoTracing(const void*) override {} |
- void registerWeakMembers(const void*, const void*, WeakCallback) override {} |
- void registerWeakTable(const void*, |
- EphemeronCallback, |
- EphemeronCallback) override {} |
-#if DCHECK_IS_ON() |
- bool weakTableRegistered(const void*) override { return false; } |
-#endif |
- void registerWeakCellWithCallback(void**, WeakCallback) override {} |
- bool ensureMarked(const void* objectPointer) override { |
- if (!objectPointer || |
- HeapObjectHeader::fromPayload(objectPointer)->isMarked()) |
- return false; |
- markNoTracing(objectPointer); |
- return true; |
- } |
- |
- size_t count() { return m_count; } |
- void reset() { m_count = 0; } |
- |
- private: |
- StackFrameDepthScope m_scope; |
- size_t m_count; |
-}; |
- |
-#undef DEFINE_VISITOR_METHODS |
- |
class SimpleObject : public GarbageCollected<SimpleObject> { |
public: |
static SimpleObject* create() { return new SimpleObject(); } |
@@ -1020,58 +966,6 @@ class RefCountedAndGarbageCollected2 |
int RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
-#define DEFINE_VISITOR_METHODS(Type) \ |
- void mark(const Type* object, TraceCallback callback) override { \ |
- mark(object); \ |
- } |
- |
-class RefCountedGarbageCollectedVisitor : public CountingVisitor { |
- public: |
- RefCountedGarbageCollectedVisitor(ThreadState* state, |
- int expected, |
- void** objects) |
- : CountingVisitor(state), |
- m_count(0), |
- m_expectedCount(expected), |
- m_expectedObjects(objects) {} |
- |
- void mark(const void* ptr) { markNoTrace(ptr); } |
- |
- virtual void markNoTrace(const void* ptr) { |
- if (!ptr) |
- return; |
- if (m_count < m_expectedCount) |
- EXPECT_TRUE(expectedObject(ptr)); |
- else |
- EXPECT_FALSE(expectedObject(ptr)); |
- m_count++; |
- } |
- |
- void mark(const void* ptr, TraceCallback) override { mark(ptr); } |
- |
- void markHeader(HeapObjectHeader* header, TraceCallback callback) override { |
- mark(header->payload()); |
- } |
- |
- bool validate() { return m_count >= m_expectedCount; } |
- void reset() { m_count = 0; } |
- |
- private: |
- bool expectedObject(const void* ptr) { |
- for (int i = 0; i < m_expectedCount; i++) { |
- if (m_expectedObjects[i] == ptr) |
- return true; |
- } |
- return false; |
- } |
- |
- int m_count; |
- int m_expectedCount; |
- void** m_expectedObjects; |
-}; |
- |
-#undef DEFINE_VISITOR_METHODS |
- |
class Weak : public Bar { |
public: |
static Weak* create(Bar* strong, Bar* weak) { return new Weak(strong, weak); } |
@@ -3745,69 +3639,6 @@ TEST(HeapTest, RefCountedGarbageCollected) { |
EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); |
} |
-TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) { |
- RefCountedAndGarbageCollected::s_destructorCalls = 0; |
- RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
- { |
- RefCountedAndGarbageCollected* pointer1 = 0; |
- RefCountedAndGarbageCollected2* pointer2 = 0; |
- { |
- Persistent<RefCountedAndGarbageCollected> object1 = |
- RefCountedAndGarbageCollected::create(); |
- Persistent<RefCountedAndGarbageCollected2> object2 = |
- RefCountedAndGarbageCollected2::create(); |
- pointer1 = object1.get(); |
- pointer2 = object2.get(); |
- void* objects[2] = {object1.get(), object2.get()}; |
- ThreadState::GCForbiddenScope gcScope(ThreadState::current()); |
- RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, |
- objects); |
- ThreadState::current()->visitPersistents(&visitor); |
- EXPECT_TRUE(visitor.validate()); |
- } |
- conservativelyCollectGarbage(); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
- |
- conservativelyCollectGarbage(); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
- |
- { |
- // At this point, the reference counts of object1 and object2 are 0. |
- // Only pointer1 and pointer2 keep references to object1 and object2. |
- void* objects[] = {0}; |
- ThreadState::GCForbiddenScope gcScope(ThreadState::current()); |
- RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 0, |
- objects); |
- ThreadState::current()->visitPersistents(&visitor); |
- EXPECT_TRUE(visitor.validate()); |
- } |
- |
- { |
- Persistent<RefCountedAndGarbageCollected> object1(pointer1); |
- Persistent<RefCountedAndGarbageCollected2> object2(pointer2); |
- void* objects[2] = {object1.get(), object2.get()}; |
- ThreadState::GCForbiddenScope gcScope(ThreadState::current()); |
- RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2, |
- objects); |
- ThreadState::current()->visitPersistents(&visitor); |
- EXPECT_TRUE(visitor.validate()); |
- } |
- conservativelyCollectGarbage(); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
- |
- conservativelyCollectGarbage(); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
- EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
- } |
- |
- preciselyCollectGarbage(); |
- EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
- EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); |
-} |
- |
TEST(HeapTest, WeakMembers) { |
Bar::s_live = 0; |
{ |
@@ -3911,7 +3742,21 @@ TEST(HeapTest, Comparisons) { |
EXPECT_TRUE(barPersistent == fooPersistent); |
} |
+#if DCHECK_IS_ON() |
+namespace { |
+ |
+static size_t s_checkMarkCount = 0; |
+ |
+bool reportMarkedPointer(HeapObjectHeader*) { |
+ s_checkMarkCount++; |
+ // Do not try to mark the located heap object. |
+ return true; |
+} |
+} |
+#endif |
+ |
TEST(HeapTest, CheckAndMarkPointer) { |
+#if DCHECK_IS_ON() |
ThreadHeap& heap = ThreadState::current()->heap(); |
clearOutOldGarbage(); |
@@ -3939,20 +3784,25 @@ TEST(HeapTest, CheckAndMarkPointer) { |
{ |
TestGCScope scope(BlinkGC::HeapPointersOnStack); |
ThreadState::GCForbiddenScope gcScope(ThreadState::current()); |
- CountingVisitor visitor(ThreadState::current()); |
+ Visitor visitor(ThreadState::current(), |
+ VisitorMarkingMode::ThreadLocalMarking); |
EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not |
// park all threads. |
heap.flushHeapDoesNotContainCache(); |
for (size_t i = 0; i < objectAddresses.size(); i++) { |
- EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); |
- EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); |
+ EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i], |
+ reportMarkedPointer)); |
+ EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i], |
+ reportMarkedPointer)); |
} |
- EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
- visitor.reset(); |
- EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); |
- EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); |
- EXPECT_EQ(2ul, visitor.count()); |
- visitor.reset(); |
+ EXPECT_EQ(objectAddresses.size() * 2, s_checkMarkCount); |
+ s_checkMarkCount = 0; |
+ EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress, |
+ reportMarkedPointer)); |
+ EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress, |
+ reportMarkedPointer)); |
+ EXPECT_EQ(2ul, s_checkMarkCount); |
+ s_checkMarkCount = 0ul; |
} |
// This forces a GC without stack scanning which results in the objects |
// being collected. This will also rebuild the above mentioned freelists, |
@@ -3961,7 +3811,8 @@ TEST(HeapTest, CheckAndMarkPointer) { |
{ |
TestGCScope scope(BlinkGC::HeapPointersOnStack); |
ThreadState::GCForbiddenScope gcScope(ThreadState::current()); |
- CountingVisitor visitor(ThreadState::current()); |
+ Visitor visitor(ThreadState::current(), |
+ VisitorMarkingMode::ThreadLocalMarking); |
EXPECT_TRUE(scope.allThreadsParked()); |
heap.flushHeapDoesNotContainCache(); |
for (size_t i = 0; i < objectAddresses.size(); i++) { |
@@ -3972,17 +3823,20 @@ TEST(HeapTest, CheckAndMarkPointer) { |
// whether it points at a valid object (this ensures the |
// correctness of the page-based on-heap address caches), so we |
// can't make that assert. |
- heap.checkAndMarkPointer(&visitor, objectAddresses[i]); |
- heap.checkAndMarkPointer(&visitor, endAddresses[i]); |
+ heap.checkAndMarkPointer(&visitor, objectAddresses[i], |
+ reportMarkedPointer); |
+ heap.checkAndMarkPointer(&visitor, endAddresses[i], reportMarkedPointer); |
} |
- EXPECT_EQ(0ul, visitor.count()); |
- heap.checkAndMarkPointer(&visitor, largeObjectAddress); |
- heap.checkAndMarkPointer(&visitor, largeObjectEndAddress); |
- EXPECT_EQ(0ul, visitor.count()); |
+ EXPECT_EQ(0ul, s_checkMarkCount); |
+ heap.checkAndMarkPointer(&visitor, largeObjectAddress, reportMarkedPointer); |
+ heap.checkAndMarkPointer(&visitor, largeObjectEndAddress, |
+ reportMarkedPointer); |
+ EXPECT_EQ(0ul, s_checkMarkCount); |
} |
// This round of GC is important to make sure that the object start |
// bitmap are cleared out and that the free lists are rebuild. |
clearOutOldGarbage(); |
+#endif |
} |
TEST(HeapTest, PersistentHeapCollectionTypes) { |
@@ -5626,45 +5480,6 @@ class PartObject { |
Member<SimpleObject> m_obj; |
}; |
-TEST(HeapTest, TraceIfNeeded) { |
- ThreadState::GCForbiddenScope scope(ThreadState::current()); |
- CountingVisitor visitor(ThreadState::current()); |
- |
- { |
- TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap = |
- TraceIfNeededTester<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42)); |
- visitor.reset(); |
- m_offHeap->trace(&visitor); |
- EXPECT_EQ(0u, visitor.count()); |
- } |
- |
- { |
- TraceIfNeededTester<PartObject>* m_part = |
- TraceIfNeededTester<PartObject>::create(); |
- visitor.reset(); |
- m_part->trace(&visitor); |
- EXPECT_EQ(1u, visitor.count()); |
- } |
- |
- { |
- TraceIfNeededTester<Member<SimpleObject>>* m_obj = |
- TraceIfNeededTester<Member<SimpleObject>>::create( |
- Member<SimpleObject>(SimpleObject::create())); |
- visitor.reset(); |
- m_obj->trace(&visitor); |
- EXPECT_EQ(1u, visitor.count()); |
- } |
- |
- { |
- TraceIfNeededTester<HeapVector<Member<SimpleObject>>>* m_vec = |
- TraceIfNeededTester<HeapVector<Member<SimpleObject>>>::create(); |
- m_vec->obj().push_back(SimpleObject::create()); |
- visitor.reset(); |
- m_vec->trace(&visitor); |
- EXPECT_EQ(2u, visitor.count()); |
- } |
-} |
- |
class AllocatesOnAssignment { |
public: |
AllocatesOnAssignment(std::nullptr_t) : m_value(nullptr) {} |