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

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

Issue 2652923002: Devirtualize Visitor and remove inline visitor specialization. (Closed)
Patch Set: rebased Created 3 years, 10 months 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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 m_state->heap().resume(); 298 m_state->heap().resume();
299 } 299 }
300 } 300 }
301 301
302 private: 302 private:
303 ThreadState* m_state; 303 ThreadState* m_state;
304 SafePointScope m_safePointScope; 304 SafePointScope m_safePointScope;
305 bool m_parkedAllThreads; // False if we fail to park all threads 305 bool m_parkedAllThreads; // False if we fail to park all threads
306 }; 306 };
307 307
308 #define DEFINE_VISITOR_METHODS(Type) \
309 void mark(const Type* object, TraceCallback callback) override { \
310 if (object) \
311 m_count++; \
312 } \
313 bool isMarked(const Type*) override { return false; } \
314 bool ensureMarked(const Type* objectPointer) override { \
315 return ensureMarked(objectPointer); \
316 }
317
318 class CountingVisitor : public Visitor {
319 public:
320 explicit CountingVisitor(ThreadState* state)
321 : Visitor(state, VisitorMarkingMode::ThreadLocalMarking),
322 m_scope(&state->heap().stackFrameDepth()),
323 m_count(0) {}
324
325 void mark(const void* object, TraceCallback) override {
326 if (object)
327 m_count++;
328 }
329
330 void markHeader(HeapObjectHeader* header, TraceCallback callback) override {
331 ASSERT(header->payload());
332 m_count++;
333 }
334
335 void registerDelayedMarkNoTracing(const void*) override {}
336 void registerWeakMembers(const void*, const void*, WeakCallback) override {}
337 void registerWeakTable(const void*,
338 EphemeronCallback,
339 EphemeronCallback) override {}
340 #if DCHECK_IS_ON()
341 bool weakTableRegistered(const void*) override { return false; }
342 #endif
343 void registerWeakCellWithCallback(void**, WeakCallback) override {}
344 bool ensureMarked(const void* objectPointer) override {
345 if (!objectPointer ||
346 HeapObjectHeader::fromPayload(objectPointer)->isMarked())
347 return false;
348 markNoTracing(objectPointer);
349 return true;
350 }
351
352 size_t count() { return m_count; }
353 void reset() { m_count = 0; }
354
355 private:
356 StackFrameDepthScope m_scope;
357 size_t m_count;
358 };
359
360 #undef DEFINE_VISITOR_METHODS
361
362 class SimpleObject : public GarbageCollected<SimpleObject> { 308 class SimpleObject : public GarbageCollected<SimpleObject> {
363 public: 309 public:
364 static SimpleObject* create() { return new SimpleObject(); } 310 static SimpleObject* create() { return new SimpleObject(); }
365 DEFINE_INLINE_TRACE() {} 311 DEFINE_INLINE_TRACE() {}
366 char getPayload(int i) { return payload[i]; } 312 char getPayload(int i) { return payload[i]; }
367 // This virtual method is unused but it is here to make sure 313 // This virtual method is unused but it is here to make sure
368 // that this object has a vtable. This object is used 314 // that this object has a vtable. This object is used
369 // as the super class for objects that also have garbage 315 // as the super class for objects that also have garbage
370 // collected mixins and having a virtual here makes sure 316 // collected mixins and having a virtual here makes sure
371 // that adjustment is needed both for marking and for isAlive 317 // that adjustment is needed both for marking and for isAlive
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 959
1014 private: 960 private:
1015 RefCountedAndGarbageCollected2() : m_refCount(0) {} 961 RefCountedAndGarbageCollected2() : m_refCount(0) {}
1016 962
1017 int m_refCount; 963 int m_refCount;
1018 SelfKeepAlive<RefCountedAndGarbageCollected2> m_keepAlive; 964 SelfKeepAlive<RefCountedAndGarbageCollected2> m_keepAlive;
1019 }; 965 };
1020 966
1021 int RefCountedAndGarbageCollected2::s_destructorCalls = 0; 967 int RefCountedAndGarbageCollected2::s_destructorCalls = 0;
1022 968
1023 #define DEFINE_VISITOR_METHODS(Type) \
1024 void mark(const Type* object, TraceCallback callback) override { \
1025 mark(object); \
1026 }
1027
1028 class RefCountedGarbageCollectedVisitor : public CountingVisitor {
1029 public:
1030 RefCountedGarbageCollectedVisitor(ThreadState* state,
1031 int expected,
1032 void** objects)
1033 : CountingVisitor(state),
1034 m_count(0),
1035 m_expectedCount(expected),
1036 m_expectedObjects(objects) {}
1037
1038 void mark(const void* ptr) { markNoTrace(ptr); }
1039
1040 virtual void markNoTrace(const void* ptr) {
1041 if (!ptr)
1042 return;
1043 if (m_count < m_expectedCount)
1044 EXPECT_TRUE(expectedObject(ptr));
1045 else
1046 EXPECT_FALSE(expectedObject(ptr));
1047 m_count++;
1048 }
1049
1050 void mark(const void* ptr, TraceCallback) override { mark(ptr); }
1051
1052 void markHeader(HeapObjectHeader* header, TraceCallback callback) override {
1053 mark(header->payload());
1054 }
1055
1056 bool validate() { return m_count >= m_expectedCount; }
1057 void reset() { m_count = 0; }
1058
1059 private:
1060 bool expectedObject(const void* ptr) {
1061 for (int i = 0; i < m_expectedCount; i++) {
1062 if (m_expectedObjects[i] == ptr)
1063 return true;
1064 }
1065 return false;
1066 }
1067
1068 int m_count;
1069 int m_expectedCount;
1070 void** m_expectedObjects;
1071 };
1072
1073 #undef DEFINE_VISITOR_METHODS
1074
1075 class Weak : public Bar { 969 class Weak : public Bar {
1076 public: 970 public:
1077 static Weak* create(Bar* strong, Bar* weak) { return new Weak(strong, weak); } 971 static Weak* create(Bar* strong, Bar* weak) { return new Weak(strong, weak); }
1078 972
1079 DEFINE_INLINE_VIRTUAL_TRACE() { 973 DEFINE_INLINE_VIRTUAL_TRACE() {
1080 visitor->trace(m_strongBar); 974 visitor->trace(m_strongBar);
1081 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this); 975 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this);
1082 } 976 }
1083 977
1084 void zapWeakMembers(Visitor* visitor) { 978 void zapWeakMembers(Visitor* visitor) {
(...skipping 2653 matching lines...) Expand 10 before | Expand all | Expand 10 after
3738 // increased to 1. 3632 // increased to 1.
3739 preciselyCollectGarbage(); 3633 preciselyCollectGarbage();
3740 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); 3634 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3741 } 3635 }
3742 // Both persistent handle is gone and ref count is zero so the 3636 // Both persistent handle is gone and ref count is zero so the
3743 // object can be collected. 3637 // object can be collected.
3744 preciselyCollectGarbage(); 3638 preciselyCollectGarbage();
3745 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); 3639 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls);
3746 } 3640 }
3747 3641
3748 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) {
3749 RefCountedAndGarbageCollected::s_destructorCalls = 0;
3750 RefCountedAndGarbageCollected2::s_destructorCalls = 0;
3751 {
3752 RefCountedAndGarbageCollected* pointer1 = 0;
3753 RefCountedAndGarbageCollected2* pointer2 = 0;
3754 {
3755 Persistent<RefCountedAndGarbageCollected> object1 =
3756 RefCountedAndGarbageCollected::create();
3757 Persistent<RefCountedAndGarbageCollected2> object2 =
3758 RefCountedAndGarbageCollected2::create();
3759 pointer1 = object1.get();
3760 pointer2 = object2.get();
3761 void* objects[2] = {object1.get(), object2.get()};
3762 ThreadState::GCForbiddenScope gcScope(ThreadState::current());
3763 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2,
3764 objects);
3765 ThreadState::current()->visitPersistents(&visitor);
3766 EXPECT_TRUE(visitor.validate());
3767 }
3768 conservativelyCollectGarbage();
3769 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3770 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3771
3772 conservativelyCollectGarbage();
3773 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3774 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3775
3776 {
3777 // At this point, the reference counts of object1 and object2 are 0.
3778 // Only pointer1 and pointer2 keep references to object1 and object2.
3779 void* objects[] = {0};
3780 ThreadState::GCForbiddenScope gcScope(ThreadState::current());
3781 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 0,
3782 objects);
3783 ThreadState::current()->visitPersistents(&visitor);
3784 EXPECT_TRUE(visitor.validate());
3785 }
3786
3787 {
3788 Persistent<RefCountedAndGarbageCollected> object1(pointer1);
3789 Persistent<RefCountedAndGarbageCollected2> object2(pointer2);
3790 void* objects[2] = {object1.get(), object2.get()};
3791 ThreadState::GCForbiddenScope gcScope(ThreadState::current());
3792 RefCountedGarbageCollectedVisitor visitor(ThreadState::current(), 2,
3793 objects);
3794 ThreadState::current()->visitPersistents(&visitor);
3795 EXPECT_TRUE(visitor.validate());
3796 }
3797 conservativelyCollectGarbage();
3798 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3799 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3800
3801 conservativelyCollectGarbage();
3802 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls);
3803 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls);
3804 }
3805
3806 preciselyCollectGarbage();
3807 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls);
3808 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls);
3809 }
3810
3811 TEST(HeapTest, WeakMembers) { 3642 TEST(HeapTest, WeakMembers) {
3812 Bar::s_live = 0; 3643 Bar::s_live = 0;
3813 { 3644 {
3814 Persistent<Bar> h1 = Bar::create(); 3645 Persistent<Bar> h1 = Bar::create();
3815 Persistent<Weak> h4; 3646 Persistent<Weak> h4;
3816 Persistent<WithWeakMember> h5; 3647 Persistent<WithWeakMember> h5;
3817 preciselyCollectGarbage(); 3648 preciselyCollectGarbage();
3818 ASSERT_EQ(1u, Bar::s_live); // h1 is live. 3649 ASSERT_EQ(1u, Bar::s_live); // h1 is live.
3819 { 3650 {
3820 Bar* h2 = Bar::create(); 3651 Bar* h2 = Bar::create();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 } 3735 }
3905 3736
3906 TEST(HeapTest, Comparisons) { 3737 TEST(HeapTest, Comparisons) {
3907 Persistent<Bar> barPersistent = Bar::create(); 3738 Persistent<Bar> barPersistent = Bar::create();
3908 Persistent<Foo> fooPersistent = Foo::create(barPersistent); 3739 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
3909 EXPECT_TRUE(barPersistent != fooPersistent); 3740 EXPECT_TRUE(barPersistent != fooPersistent);
3910 barPersistent = fooPersistent; 3741 barPersistent = fooPersistent;
3911 EXPECT_TRUE(barPersistent == fooPersistent); 3742 EXPECT_TRUE(barPersistent == fooPersistent);
3912 } 3743 }
3913 3744
3745 #if DCHECK_IS_ON()
3746 namespace {
3747
3748 static size_t s_checkMarkCount = 0;
3749
3750 bool reportMarkedPointer(HeapObjectHeader*) {
3751 s_checkMarkCount++;
3752 // Do not try to mark the located heap object.
3753 return true;
3754 }
3755 }
3756 #endif
3757
3914 TEST(HeapTest, CheckAndMarkPointer) { 3758 TEST(HeapTest, CheckAndMarkPointer) {
3759 #if DCHECK_IS_ON()
3915 ThreadHeap& heap = ThreadState::current()->heap(); 3760 ThreadHeap& heap = ThreadState::current()->heap();
3916 clearOutOldGarbage(); 3761 clearOutOldGarbage();
3917 3762
3918 Vector<Address> objectAddresses; 3763 Vector<Address> objectAddresses;
3919 Vector<Address> endAddresses; 3764 Vector<Address> endAddresses;
3920 Address largeObjectAddress; 3765 Address largeObjectAddress;
3921 Address largeObjectEndAddress; 3766 Address largeObjectEndAddress;
3922 for (int i = 0; i < 10; i++) { 3767 for (int i = 0; i < 10; i++) {
3923 SimpleObject* object = SimpleObject::create(); 3768 SimpleObject* object = SimpleObject::create();
3924 Address objectAddress = reinterpret_cast<Address>(object); 3769 Address objectAddress = reinterpret_cast<Address>(object);
3925 objectAddresses.push_back(objectAddress); 3770 objectAddresses.push_back(objectAddress);
3926 endAddresses.push_back(objectAddress + sizeof(SimpleObject) - 1); 3771 endAddresses.push_back(objectAddress + sizeof(SimpleObject) - 1);
3927 } 3772 }
3928 LargeHeapObject* largeObject = LargeHeapObject::create(); 3773 LargeHeapObject* largeObject = LargeHeapObject::create();
3929 largeObjectAddress = reinterpret_cast<Address>(largeObject); 3774 largeObjectAddress = reinterpret_cast<Address>(largeObject);
3930 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; 3775 largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1;
3931 3776
3932 // This is a low-level test where we call checkAndMarkPointer. This method 3777 // This is a low-level test where we call checkAndMarkPointer. This method
3933 // causes the object start bitmap to be computed which requires the heap 3778 // causes the object start bitmap to be computed which requires the heap
3934 // to be in a consistent state (e.g. the free allocation area must be put 3779 // to be in a consistent state (e.g. the free allocation area must be put
3935 // into a free list header). However when we call makeConsistentForGC it 3780 // into a free list header). However when we call makeConsistentForGC it
3936 // also clears out the freelists so we have to rebuild those before trying 3781 // also clears out the freelists so we have to rebuild those before trying
3937 // to allocate anything again. We do this by forcing a GC after doing the 3782 // to allocate anything again. We do this by forcing a GC after doing the
3938 // checkAndMarkPointer tests. 3783 // checkAndMarkPointer tests.
3939 { 3784 {
3940 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3785 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3941 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); 3786 ThreadState::GCForbiddenScope gcScope(ThreadState::current());
3942 CountingVisitor visitor(ThreadState::current()); 3787 Visitor visitor(ThreadState::current(),
3788 VisitorMarkingMode::ThreadLocalMarking);
3943 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not 3789 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
3944 // park all threads. 3790 // park all threads.
3945 heap.flushHeapDoesNotContainCache(); 3791 heap.flushHeapDoesNotContainCache();
3946 for (size_t i = 0; i < objectAddresses.size(); i++) { 3792 for (size_t i = 0; i < objectAddresses.size(); i++) {
3947 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); 3793 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i],
3948 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); 3794 reportMarkedPointer));
3795 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i],
3796 reportMarkedPointer));
3949 } 3797 }
3950 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); 3798 EXPECT_EQ(objectAddresses.size() * 2, s_checkMarkCount);
3951 visitor.reset(); 3799 s_checkMarkCount = 0;
3952 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); 3800 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress,
3953 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); 3801 reportMarkedPointer));
3954 EXPECT_EQ(2ul, visitor.count()); 3802 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress,
3955 visitor.reset(); 3803 reportMarkedPointer));
3804 EXPECT_EQ(2ul, s_checkMarkCount);
3805 s_checkMarkCount = 0ul;
3956 } 3806 }
3957 // This forces a GC without stack scanning which results in the objects 3807 // This forces a GC without stack scanning which results in the objects
3958 // being collected. This will also rebuild the above mentioned freelists, 3808 // being collected. This will also rebuild the above mentioned freelists,
3959 // however we don't rely on that below since we don't have any allocations. 3809 // however we don't rely on that below since we don't have any allocations.
3960 clearOutOldGarbage(); 3810 clearOutOldGarbage();
3961 { 3811 {
3962 TestGCScope scope(BlinkGC::HeapPointersOnStack); 3812 TestGCScope scope(BlinkGC::HeapPointersOnStack);
3963 ThreadState::GCForbiddenScope gcScope(ThreadState::current()); 3813 ThreadState::GCForbiddenScope gcScope(ThreadState::current());
3964 CountingVisitor visitor(ThreadState::current()); 3814 Visitor visitor(ThreadState::current(),
3815 VisitorMarkingMode::ThreadLocalMarking);
3965 EXPECT_TRUE(scope.allThreadsParked()); 3816 EXPECT_TRUE(scope.allThreadsParked());
3966 heap.flushHeapDoesNotContainCache(); 3817 heap.flushHeapDoesNotContainCache();
3967 for (size_t i = 0; i < objectAddresses.size(); i++) { 3818 for (size_t i = 0; i < objectAddresses.size(); i++) {
3968 // We would like to assert that checkAndMarkPointer returned false 3819 // We would like to assert that checkAndMarkPointer returned false
3969 // here because the pointers no longer point into a valid object 3820 // here because the pointers no longer point into a valid object
3970 // (it's been freed by the GCs. But checkAndMarkPointer will return 3821 // (it's been freed by the GCs. But checkAndMarkPointer will return
3971 // true for any pointer that points into a heap page, regardless of 3822 // true for any pointer that points into a heap page, regardless of
3972 // whether it points at a valid object (this ensures the 3823 // whether it points at a valid object (this ensures the
3973 // correctness of the page-based on-heap address caches), so we 3824 // correctness of the page-based on-heap address caches), so we
3974 // can't make that assert. 3825 // can't make that assert.
3975 heap.checkAndMarkPointer(&visitor, objectAddresses[i]); 3826 heap.checkAndMarkPointer(&visitor, objectAddresses[i],
3976 heap.checkAndMarkPointer(&visitor, endAddresses[i]); 3827 reportMarkedPointer);
3828 heap.checkAndMarkPointer(&visitor, endAddresses[i], reportMarkedPointer);
3977 } 3829 }
3978 EXPECT_EQ(0ul, visitor.count()); 3830 EXPECT_EQ(0ul, s_checkMarkCount);
3979 heap.checkAndMarkPointer(&visitor, largeObjectAddress); 3831 heap.checkAndMarkPointer(&visitor, largeObjectAddress, reportMarkedPointer);
3980 heap.checkAndMarkPointer(&visitor, largeObjectEndAddress); 3832 heap.checkAndMarkPointer(&visitor, largeObjectEndAddress,
3981 EXPECT_EQ(0ul, visitor.count()); 3833 reportMarkedPointer);
3834 EXPECT_EQ(0ul, s_checkMarkCount);
3982 } 3835 }
3983 // This round of GC is important to make sure that the object start 3836 // This round of GC is important to make sure that the object start
3984 // bitmap are cleared out and that the free lists are rebuild. 3837 // bitmap are cleared out and that the free lists are rebuild.
3985 clearOutOldGarbage(); 3838 clearOutOldGarbage();
3839 #endif
3986 } 3840 }
3987 3841
3988 TEST(HeapTest, PersistentHeapCollectionTypes) { 3842 TEST(HeapTest, PersistentHeapCollectionTypes) {
3989 IntWrapper::s_destructorCalls = 0; 3843 IntWrapper::s_destructorCalls = 0;
3990 3844
3991 typedef HeapVector<Member<IntWrapper>> Vec; 3845 typedef HeapVector<Member<IntWrapper>> Vec;
3992 typedef PersistentHeapVector<Member<IntWrapper>> PVec; 3846 typedef PersistentHeapVector<Member<IntWrapper>> PVec;
3993 typedef PersistentHeapHashSet<Member<IntWrapper>> PSet; 3847 typedef PersistentHeapHashSet<Member<IntWrapper>> PSet;
3994 typedef PersistentHeapListHashSet<Member<IntWrapper>> PListSet; 3848 typedef PersistentHeapListHashSet<Member<IntWrapper>> PListSet;
3995 typedef PersistentHeapLinkedHashSet<Member<IntWrapper>> PLinkedSet; 3849 typedef PersistentHeapLinkedHashSet<Member<IntWrapper>> PLinkedSet;
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after
5619 DISALLOW_NEW(); 5473 DISALLOW_NEW();
5620 5474
5621 public: 5475 public:
5622 PartObject() : m_obj(SimpleObject::create()) {} 5476 PartObject() : m_obj(SimpleObject::create()) {}
5623 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); } 5477 DEFINE_INLINE_TRACE() { visitor->trace(m_obj); }
5624 5478
5625 private: 5479 private:
5626 Member<SimpleObject> m_obj; 5480 Member<SimpleObject> m_obj;
5627 }; 5481 };
5628 5482
5629 TEST(HeapTest, TraceIfNeeded) {
5630 ThreadState::GCForbiddenScope scope(ThreadState::current());
5631 CountingVisitor visitor(ThreadState::current());
5632
5633 {
5634 TraceIfNeededTester<RefPtr<OffHeapInt>>* m_offHeap =
5635 TraceIfNeededTester<RefPtr<OffHeapInt>>::create(OffHeapInt::create(42));
5636 visitor.reset();
5637 m_offHeap->trace(&visitor);
5638 EXPECT_EQ(0u, visitor.count());
5639 }
5640
5641 {
5642 TraceIfNeededTester<PartObject>* m_part =
5643 TraceIfNeededTester<PartObject>::create();
5644 visitor.reset();
5645 m_part->trace(&visitor);
5646 EXPECT_EQ(1u, visitor.count());
5647 }
5648
5649 {
5650 TraceIfNeededTester<Member<SimpleObject>>* m_obj =
5651 TraceIfNeededTester<Member<SimpleObject>>::create(
5652 Member<SimpleObject>(SimpleObject::create()));
5653 visitor.reset();
5654 m_obj->trace(&visitor);
5655 EXPECT_EQ(1u, visitor.count());
5656 }
5657
5658 {
5659 TraceIfNeededTester<HeapVector<Member<SimpleObject>>>* m_vec =
5660 TraceIfNeededTester<HeapVector<Member<SimpleObject>>>::create();
5661 m_vec->obj().push_back(SimpleObject::create());
5662 visitor.reset();
5663 m_vec->trace(&visitor);
5664 EXPECT_EQ(2u, visitor.count());
5665 }
5666 }
5667
5668 class AllocatesOnAssignment { 5483 class AllocatesOnAssignment {
5669 public: 5484 public:
5670 AllocatesOnAssignment(std::nullptr_t) : m_value(nullptr) {} 5485 AllocatesOnAssignment(std::nullptr_t) : m_value(nullptr) {}
5671 AllocatesOnAssignment(int x) : m_value(new IntWrapper(x)) {} 5486 AllocatesOnAssignment(int x) : m_value(new IntWrapper(x)) {}
5672 AllocatesOnAssignment(IntWrapper* x) : m_value(x) {} 5487 AllocatesOnAssignment(IntWrapper* x) : m_value(x) {}
5673 5488
5674 AllocatesOnAssignment& operator=(const AllocatesOnAssignment x) { 5489 AllocatesOnAssignment& operator=(const AllocatesOnAssignment x) {
5675 m_value = x.m_value; 5490 m_value = x.m_value;
5676 return *this; 5491 return *this;
5677 } 5492 }
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
6561 "HeapVector"); 6376 "HeapVector");
6562 static_assert( 6377 static_assert(
6563 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, 6378 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value,
6564 "HeapDeque"); 6379 "HeapDeque");
6565 static_assert(WTF::IsGarbageCollectedType< 6380 static_assert(WTF::IsGarbageCollectedType<
6566 HeapTerminatedArray<Member<IntWrapper>>>::value, 6381 HeapTerminatedArray<Member<IntWrapper>>>::value,
6567 "HeapTerminatedArray"); 6382 "HeapTerminatedArray");
6568 } 6383 }
6569 6384
6570 } // namespace blink 6385 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698