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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 131 |
132 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> StrongWeakPair; | 132 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> StrongWeakPair; |
133 | 133 |
134 struct PairWithWeakHandling : public StrongWeakPair { | 134 struct PairWithWeakHandling : public StrongWeakPair { |
135 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | 135 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
136 | 136 |
137 public: | 137 public: |
138 // Regular constructor. | 138 // Regular constructor. |
139 PairWithWeakHandling(IntWrapper* one, IntWrapper* two) | 139 PairWithWeakHandling(IntWrapper* one, IntWrapper* two) |
140 : StrongWeakPair(one, two) { | 140 : StrongWeakPair(one, two) { |
141 ASSERT( | 141 ASSERT(one); // We use null first field to indicate empty slots in the hash |
142 one); // We use null first field to indicate empty slots in the hash ta
ble. | 142 // table. |
143 } | 143 } |
144 | 144 |
145 // The HashTable (via the HashTrait) calls this constructor with a | 145 // The HashTable (via the HashTrait) calls this constructor with a |
146 // placement new to mark slots in the hash table as being deleted. We will | 146 // placement new to mark slots in the hash table as being deleted. We will |
147 // never call trace or the destructor on these slots. We mark ourselves delete
d | 147 // never call trace or the destructor on these slots. We mark ourselves |
| 148 // deleted |
148 // with a pointer to -1 in the first field. | 149 // with a pointer to -1 in the first field. |
149 PairWithWeakHandling(WTF::HashTableDeletedValueType) | 150 PairWithWeakHandling(WTF::HashTableDeletedValueType) |
150 : StrongWeakPair(reinterpret_cast<IntWrapper*>(-1), nullptr) {} | 151 : StrongWeakPair(reinterpret_cast<IntWrapper*>(-1), nullptr) {} |
151 | 152 |
152 // Used by the HashTable (via the HashTrait) to skip deleted slots in the | 153 // Used by the HashTable (via the HashTrait) to skip deleted slots in the |
153 // table. Recognizes objects that were 'constructed' using the above | 154 // table. Recognizes objects that were 'constructed' using the above |
154 // constructor. | 155 // constructor. |
155 bool isHashTableDeletedValue() const { | 156 bool isHashTableDeletedValue() const { |
156 return first == reinterpret_cast<IntWrapper*>(-1); | 157 return first == reinterpret_cast<IntWrapper*>(-1); |
157 } | 158 } |
158 | 159 |
159 // Since we don't allocate independent objects of this type, we don't need | 160 // Since we don't allocate independent objects of this type, we don't need |
160 // a regular trace method. Instead, we use a traceInCollection method. If | 161 // a regular trace method. Instead, we use a traceInCollection method. If |
161 // the entry should be deleted from the collection we return true and don't | 162 // the entry should be deleted from the collection we return true and don't |
162 // trace the strong pointer. | 163 // trace the strong pointer. |
163 template <typename VisitorDispatcher> | 164 template <typename VisitorDispatcher> |
164 bool traceInCollection(VisitorDispatcher visitor, | 165 bool traceInCollection(VisitorDispatcher visitor, |
165 WTF::ShouldWeakPointersBeMarkedStrongly strongify) { | 166 WTF::ShouldWeakPointersBeMarkedStrongly strongify) { |
166 visitor->traceInCollection(second, strongify); | 167 visitor->traceInCollection(second, strongify); |
167 if (!ThreadHeap::isHeapObjectAlive(second)) | 168 if (!ThreadHeap::isHeapObjectAlive(second)) |
168 return true; | 169 return true; |
169 // FIXME: traceInCollection is also called from WeakProcessing to check if t
he entry is dead. | 170 // FIXME: traceInCollection is also called from WeakProcessing to check if |
170 // The below if avoids calling trace in that case by only calling trace when
|first| is not yet marked. | 171 // the entry is dead. |
| 172 // The below if avoids calling trace in that case by only calling trace when |
| 173 // |first| is not yet marked. |
171 if (!ThreadHeap::isHeapObjectAlive(first)) | 174 if (!ThreadHeap::isHeapObjectAlive(first)) |
172 visitor->trace(first); | 175 visitor->trace(first); |
173 return false; | 176 return false; |
174 } | 177 } |
175 }; | 178 }; |
176 | 179 |
177 template <typename T> | 180 template <typename T> |
178 struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<T> { | 181 struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<T> { |
179 // We want to treat the object as a weak object in the sense that it can | 182 // We want to treat the object as a weak object in the sense that it can |
180 // disappear from hash sets and hash maps. | 183 // disappear from hash sets and hash maps. |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 | 582 |
580 if (gcCount < gcPerThread) { | 583 if (gcCount < gcPerThread) { |
581 preciselyCollectGarbage(); | 584 preciselyCollectGarbage(); |
582 gcCount++; | 585 gcCount++; |
583 atomicIncrement(&m_gcCount); | 586 atomicIncrement(&m_gcCount); |
584 } | 587 } |
585 | 588 |
586 // Taking snapshot shouldn't have any bad side effect. | 589 // Taking snapshot shouldn't have any bad side effect. |
587 // TODO(haraken): This snapshot GC causes crashes, so disable | 590 // TODO(haraken): This snapshot GC causes crashes, so disable |
588 // it at the moment. Fix the crash and enable it. | 591 // it at the moment. Fix the crash and enable it. |
589 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::T
akeSnapshot, BlinkGC::ForcedGC); | 592 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, |
| 593 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); |
590 preciselyCollectGarbage(); | 594 preciselyCollectGarbage(); |
591 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 595 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
592 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 596 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
593 } | 597 } |
594 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 598 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
595 testing::yieldCurrentThread(); | 599 testing::yieldCurrentThread(); |
596 } | 600 } |
597 | 601 |
598 ThreadState::detachCurrentThread(); | 602 ThreadState::detachCurrentThread(); |
599 atomicDecrement(&m_threadsToFinish); | 603 atomicDecrement(&m_threadsToFinish); |
(...skipping 25 matching lines...) Expand all Loading... |
625 | 629 |
626 if (gcCount < gcPerThread) { | 630 if (gcCount < gcPerThread) { |
627 preciselyCollectGarbage(); | 631 preciselyCollectGarbage(); |
628 gcCount++; | 632 gcCount++; |
629 atomicIncrement(&m_gcCount); | 633 atomicIncrement(&m_gcCount); |
630 } | 634 } |
631 | 635 |
632 // Taking snapshot shouldn't have any bad side effect. | 636 // Taking snapshot shouldn't have any bad side effect. |
633 // TODO(haraken): This snapshot GC causes crashes, so disable | 637 // TODO(haraken): This snapshot GC causes crashes, so disable |
634 // it at the moment. Fix the crash and enable it. | 638 // it at the moment. Fix the crash and enable it. |
635 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::T
akeSnapshot, BlinkGC::ForcedGC); | 639 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, |
| 640 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); |
636 preciselyCollectGarbage(); | 641 preciselyCollectGarbage(); |
637 EXPECT_TRUE(weakMap->isEmpty()); | 642 EXPECT_TRUE(weakMap->isEmpty()); |
638 EXPECT_TRUE(weakMap2.isEmpty()); | 643 EXPECT_TRUE(weakMap2.isEmpty()); |
639 } | 644 } |
640 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 645 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
641 testing::yieldCurrentThread(); | 646 testing::yieldCurrentThread(); |
642 } | 647 } |
643 ThreadState::detachCurrentThread(); | 648 ThreadState::detachCurrentThread(); |
644 atomicDecrement(&m_threadsToFinish); | 649 atomicDecrement(&m_threadsToFinish); |
645 } | 650 } |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 { | 1653 { |
1649 size_t slack = 0; | 1654 size_t slack = 0; |
1650 | 1655 |
1651 // When the test starts there may already have been leaked some memory | 1656 // When the test starts there may already have been leaked some memory |
1652 // on the heap, so we establish a base line. | 1657 // on the heap, so we establish a base line. |
1653 size_t baseLevel = initialObjectPayloadSize; | 1658 size_t baseLevel = initialObjectPayloadSize; |
1654 bool testPagesAllocated = !baseLevel; | 1659 bool testPagesAllocated = !baseLevel; |
1655 if (testPagesAllocated) | 1660 if (testPagesAllocated) |
1656 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul); | 1661 EXPECT_EQ(heap.heapStats().allocatedSpace(), 0ul); |
1657 | 1662 |
1658 // This allocates objects on the general heap which should add a page of mem
ory. | 1663 // This allocates objects on the general heap which should add a page of |
| 1664 // memory. |
1659 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); | 1665 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); |
1660 slack += 4; | 1666 slack += 4; |
1661 memset(alloc32, 40, 32); | 1667 memset(alloc32, 40, 32); |
1662 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); | 1668 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); |
1663 slack += 4; | 1669 slack += 4; |
1664 memset(alloc64, 27, 64); | 1670 memset(alloc64, 27, 64); |
1665 | 1671 |
1666 size_t total = 96; | 1672 size_t total = 96; |
1667 | 1673 |
1668 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), | 1674 CheckWithSlack(baseLevel + total, heap.objectPayloadSizeForTesting(), |
(...skipping 2268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3937 // This is a low-level test where we call checkAndMarkPointer. This method | 3943 // This is a low-level test where we call checkAndMarkPointer. This method |
3938 // causes the object start bitmap to be computed which requires the heap | 3944 // causes the object start bitmap to be computed which requires the heap |
3939 // to be in a consistent state (e.g. the free allocation area must be put | 3945 // to be in a consistent state (e.g. the free allocation area must be put |
3940 // into a free list header). However when we call makeConsistentForGC it | 3946 // into a free list header). However when we call makeConsistentForGC it |
3941 // also clears out the freelists so we have to rebuild those before trying | 3947 // also clears out the freelists so we have to rebuild those before trying |
3942 // to allocate anything again. We do this by forcing a GC after doing the | 3948 // to allocate anything again. We do this by forcing a GC after doing the |
3943 // checkAndMarkPointer tests. | 3949 // checkAndMarkPointer tests. |
3944 { | 3950 { |
3945 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3951 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
3946 CountingVisitor visitor(ThreadState::current()); | 3952 CountingVisitor visitor(ThreadState::current()); |
3947 EXPECT_TRUE( | 3953 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not |
3948 scope | 3954 // park all threads. |
3949 .allThreadsParked()); // Fail the test if we could not park all thr
eads. | |
3950 heap.flushHeapDoesNotContainCache(); | 3955 heap.flushHeapDoesNotContainCache(); |
3951 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3956 for (size_t i = 0; i < objectAddresses.size(); i++) { |
3952 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); | 3957 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, objectAddresses[i])); |
3953 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); | 3958 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, endAddresses[i])); |
3954 } | 3959 } |
3955 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 3960 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
3956 visitor.reset(); | 3961 visitor.reset(); |
3957 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); | 3962 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectAddress)); |
3958 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 3963 EXPECT_TRUE(heap.checkAndMarkPointer(&visitor, largeObjectEndAddress)); |
3959 EXPECT_EQ(2ul, visitor.count()); | 3964 EXPECT_EQ(2ul, visitor.count()); |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4884 // weak processing may have taken place. | 4889 // weak processing may have taken place. |
4885 if (set3->size()) { | 4890 if (set3->size()) { |
4886 Iterator i3 = set3->begin(); | 4891 Iterator i3 = set3->begin(); |
4887 EXPECT_EQ(2, i3->first->value()); | 4892 EXPECT_EQ(2, i3->first->value()); |
4888 EXPECT_EQ(3, i3->second->value()); | 4893 EXPECT_EQ(3, i3->second->value()); |
4889 } | 4894 } |
4890 } | 4895 } |
4891 preciselyCollectGarbage(); | 4896 preciselyCollectGarbage(); |
4892 EXPECT_EQ(0u, set1->size()); | 4897 EXPECT_EQ(0u, set1->size()); |
4893 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); | 4898 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); |
4894 set1->add(PairWithWeakHandling( | 4899 // This one gets zapped at GC time because nothing holds the 103 alive. |
4895 livingInt, | 4900 set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); |
4896 IntWrapper::create( | |
4897 103))); // This one gets zapped at GC time because nothing holds the
103 alive. | |
4898 set1->add(PairWithWeakHandling( | 4901 set1->add(PairWithWeakHandling( |
4899 IntWrapper::create(103), | 4902 IntWrapper::create(103), |
4900 IntWrapper::create(103))); // This one gets zapped too. | 4903 IntWrapper::create(103))); // This one gets zapped too. |
4901 set1->add(PairWithWeakHandling(livingInt, livingInt)); | 4904 set1->add(PairWithWeakHandling(livingInt, livingInt)); |
4902 set1->add(PairWithWeakHandling( | 4905 // This one is identical to the previous and doesn't add anything. |
4903 livingInt, | 4906 set1->add(PairWithWeakHandling(livingInt, livingInt)); |
4904 livingInt)); // This one is identical to the previous and doesn't add any
thing. | |
4905 EXPECT_EQ(4u, set1->size()); | 4907 EXPECT_EQ(4u, set1->size()); |
4906 preciselyCollectGarbage(); | 4908 preciselyCollectGarbage(); |
4907 EXPECT_EQ(2u, set1->size()); | 4909 EXPECT_EQ(2u, set1->size()); |
4908 Iterator i1 = set1->begin(); | 4910 Iterator i1 = set1->begin(); |
4909 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4911 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
4910 EXPECT_EQ(livingInt, i1->second); | 4912 EXPECT_EQ(livingInt, i1->second); |
4911 ++i1; | 4913 ++i1; |
4912 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4914 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
4913 EXPECT_EQ(livingInt, i1->second); | 4915 EXPECT_EQ(livingInt, i1->second); |
4914 } | 4916 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4965 } | 4967 } |
4966 preciselyCollectGarbage(); | 4968 preciselyCollectGarbage(); |
4967 | 4969 |
4968 EXPECT_EQ(0u, map1->size()); | 4970 EXPECT_EQ(0u, map1->size()); |
4969 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 4971 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
4970 | 4972 |
4971 OffHeapInt::s_destructorCalls = 0; | 4973 OffHeapInt::s_destructorCalls = 0; |
4972 | 4974 |
4973 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), | 4975 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), |
4974 OffHeapInt::create(2000)); | 4976 OffHeapInt::create(2000)); |
4975 map1->add( | 4977 map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), |
4976 PairWithWeakHandling(livingInt, IntWrapper::create(103)), | 4978 OffHeapInt::create(2001)); // This one gets zapped at GC time |
4977 OffHeapInt::create( | 4979 // because nothing holds the 103 alive. |
4978 2001)); // This one gets zapped at GC time because nothing holds the
103 alive. | |
4979 map1->add( | 4980 map1->add( |
4980 PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103)), | 4981 PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(103)), |
4981 OffHeapInt::create(2002)); // This one gets zapped too. | 4982 OffHeapInt::create(2002)); // This one gets zapped too. |
4982 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 4983 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
4983 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); | 4984 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); |
4984 map1->add( | 4985 map1->add(PairWithWeakHandling(livingInt, livingInt), |
4985 PairWithWeakHandling(livingInt, livingInt), | 4986 dupeInt); // This one is identical to the previous and doesn't add |
4986 dupeInt); // This one is identical to the previous and doesn't add anythi
ng. | 4987 // anything. |
4987 dupeInt.clear(); | 4988 dupeInt.clear(); |
4988 | 4989 |
4989 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4990 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
4990 EXPECT_EQ(4u, map1->size()); | 4991 EXPECT_EQ(4u, map1->size()); |
4991 preciselyCollectGarbage(); | 4992 preciselyCollectGarbage(); |
4992 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 4993 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
4993 EXPECT_EQ(2u, map1->size()); | 4994 EXPECT_EQ(2u, map1->size()); |
4994 Iterator i1 = map1->begin(); | 4995 Iterator i1 = map1->begin(); |
4995 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); | 4996 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); |
4996 EXPECT_EQ(livingInt, i1->key.second); | 4997 EXPECT_EQ(livingInt, i1->key.second); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5048 } | 5049 } |
5049 preciselyCollectGarbage(); | 5050 preciselyCollectGarbage(); |
5050 | 5051 |
5051 EXPECT_EQ(0u, map1->size()); | 5052 EXPECT_EQ(0u, map1->size()); |
5052 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 5053 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
5053 | 5054 |
5054 OffHeapInt::s_destructorCalls = 0; | 5055 OffHeapInt::s_destructorCalls = 0; |
5055 | 5056 |
5056 map1->add(OffHeapInt::create(2000), | 5057 map1->add(OffHeapInt::create(2000), |
5057 PairWithWeakHandling(IntWrapper::create(103), livingInt)); | 5058 PairWithWeakHandling(IntWrapper::create(103), livingInt)); |
5058 map1->add( | 5059 // This one gets zapped at GC time because nothing holds the 103 alive. |
5059 OffHeapInt::create(2001), | 5060 map1->add(OffHeapInt::create(2001), |
5060 PairWithWeakHandling( | 5061 PairWithWeakHandling(livingInt, IntWrapper::create(103))); |
5061 livingInt, | |
5062 IntWrapper::create( | |
5063 103))); // This one gets zapped at GC time because nothing holds
the 103 alive. | |
5064 map1->add(OffHeapInt::create(2002), | 5062 map1->add(OffHeapInt::create(2002), |
5065 PairWithWeakHandling( | 5063 PairWithWeakHandling( |
5066 IntWrapper::create(103), | 5064 IntWrapper::create(103), |
5067 IntWrapper::create(103))); // This one gets zapped too. | 5065 IntWrapper::create(103))); // This one gets zapped too. |
5068 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 5066 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
5069 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); | 5067 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); |
5070 map1->add( | 5068 // This one is identical to the previous and doesn't add anything. |
5071 dupeInt, | 5069 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); |
5072 PairWithWeakHandling( | |
5073 livingInt, | |
5074 livingInt)); // This one is identical to the previous and doesn't add
anything. | |
5075 dupeInt.clear(); | 5070 dupeInt.clear(); |
5076 | 5071 |
5077 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 5072 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
5078 EXPECT_EQ(4u, map1->size()); | 5073 EXPECT_EQ(4u, map1->size()); |
5079 preciselyCollectGarbage(); | 5074 preciselyCollectGarbage(); |
5080 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 5075 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
5081 EXPECT_EQ(2u, map1->size()); | 5076 EXPECT_EQ(2u, map1->size()); |
5082 Iterator i1 = map1->begin(); | 5077 Iterator i1 = map1->begin(); |
5083 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt); | 5078 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt); |
5084 EXPECT_EQ(livingInt, i1->value.second); | 5079 EXPECT_EQ(livingInt, i1->value.second); |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5549 // until leaving the safepoint scope. | 5544 // until leaving the safepoint scope. |
5550 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 5545 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
5551 parkWorkerThread(); | 5546 parkWorkerThread(); |
5552 } | 5547 } |
5553 | 5548 |
5554 // Wake up the main thread when done sweeping. | 5549 // Wake up the main thread when done sweeping. |
5555 wakeMainThread(); | 5550 wakeMainThread(); |
5556 | 5551 |
5557 // Wait with detach until the main thread says so. This is not strictly | 5552 // Wait with detach until the main thread says so. This is not strictly |
5558 // necessary, but it means the worker thread will not do its thread local | 5553 // necessary, but it means the worker thread will not do its thread local |
5559 // GCs just yet, making it easier to reason about that no new GC has occurre
d | 5554 // GCs just yet, making it easier to reason about that no new GC has |
5560 // and the above sweep was the one finalizing the worker object. | 5555 // occurred and the above sweep was the one finalizing the worker object. |
5561 parkWorkerThread(); | 5556 parkWorkerThread(); |
5562 | 5557 |
5563 ThreadState::detachCurrentThread(); | 5558 ThreadState::detachCurrentThread(); |
5564 } | 5559 } |
5565 | 5560 |
5566 static volatile uintptr_t s_workerObjectPointer; | 5561 static volatile uintptr_t s_workerObjectPointer; |
5567 }; | 5562 }; |
5568 | 5563 |
5569 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; | 5564 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; |
5570 | 5565 |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6380 } | 6375 } |
6381 | 6376 |
6382 DEFINE_INLINE_VIRTUAL_TRACE() {} | 6377 DEFINE_INLINE_VIRTUAL_TRACE() {} |
6383 }; | 6378 }; |
6384 | 6379 |
6385 class TestMixinAllocationB : public TestMixinAllocationA { | 6380 class TestMixinAllocationB : public TestMixinAllocationA { |
6386 USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationB); | 6381 USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationB); |
6387 | 6382 |
6388 public: | 6383 public: |
6389 TestMixinAllocationB() | 6384 TestMixinAllocationB() |
6390 : m_a(new TestMixinAllocationA()) // Construct object during a mixin cons
truction. | 6385 : m_a(new TestMixinAllocationA()) // Construct object during a mixin |
| 6386 // construction. |
6391 { | 6387 { |
6392 // Completely wrong in general, but test only | 6388 // Completely wrong in general, but test only |
6393 // runs this constructor while constructing another mixin. | 6389 // runs this constructor while constructing another mixin. |
6394 ASSERT(ThreadState::current()->isGCForbidden()); | 6390 ASSERT(ThreadState::current()->isGCForbidden()); |
6395 } | 6391 } |
6396 | 6392 |
6397 DEFINE_INLINE_TRACE() { | 6393 DEFINE_INLINE_TRACE() { |
6398 visitor->trace(m_a); | 6394 visitor->trace(m_a); |
6399 TestMixinAllocationA::trace(visitor); | 6395 TestMixinAllocationA::trace(visitor); |
6400 } | 6396 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6513 parkWorkerThread(); | 6509 parkWorkerThread(); |
6514 | 6510 |
6515 // Step 6: Finish. | 6511 // Step 6: Finish. |
6516 ThreadState::detachCurrentThread(); | 6512 ThreadState::detachCurrentThread(); |
6517 wakeMainThread(); | 6513 wakeMainThread(); |
6518 } | 6514 } |
6519 | 6515 |
6520 } // anonymous namespace | 6516 } // anonymous namespace |
6521 | 6517 |
6522 TEST(HeapTest, CrossThreadWeakPersistent) { | 6518 TEST(HeapTest, CrossThreadWeakPersistent) { |
6523 // Create an object in the worker thread, have a CrossThreadWeakPersistent poi
nting to it on the main thread, | 6519 // Create an object in the worker thread, have a CrossThreadWeakPersistent |
6524 // clear the reference in the worker thread, run a GC in the worker thread, an
d see if the | 6520 // pointing to it on the main thread, clear the reference in the worker |
| 6521 // thread, run a GC in the worker thread, and see if the |
6525 // CrossThreadWeakPersistent is cleared. | 6522 // CrossThreadWeakPersistent is cleared. |
6526 | 6523 |
6527 DestructorLockingObject::s_destructorCalls = 0; | 6524 DestructorLockingObject::s_destructorCalls = 0; |
6528 | 6525 |
6529 // Step 1: Initiate a worker thread, and wait for |object| to get allocated on
the worker thread. | 6526 // Step 1: Initiate a worker thread, and wait for |object| to get allocated on |
| 6527 // the worker thread. |
6530 MutexLocker mainThreadMutexLocker(mainThreadMutex()); | 6528 MutexLocker mainThreadMutexLocker(mainThreadMutex()); |
6531 std::unique_ptr<WebThread> workerThread = | 6529 std::unique_ptr<WebThread> workerThread = |
6532 wrapUnique(Platform::current()->createThread("Test Worker Thread")); | 6530 wrapUnique(Platform::current()->createThread("Test Worker Thread")); |
6533 DestructorLockingObject* object = nullptr; | 6531 DestructorLockingObject* object = nullptr; |
6534 workerThread->getWebTaskRunner()->postTask( | 6532 workerThread->getWebTaskRunner()->postTask( |
6535 BLINK_FROM_HERE, | 6533 BLINK_FROM_HERE, |
6536 crossThreadBind(workerThreadMainForCrossThreadWeakPersistentTest, | 6534 crossThreadBind(workerThreadMainForCrossThreadWeakPersistentTest, |
6537 crossThreadUnretained(&object))); | 6535 crossThreadUnretained(&object))); |
6538 parkMainThread(); | 6536 parkMainThread(); |
6539 | 6537 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6586 EXPECT_EQ(1u, vector2.size()); | 6584 EXPECT_EQ(1u, vector2.size()); |
6587 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables | 6585 // TODO(Oilpan): when Vector.h's contiguous container support no longer disables |
6588 // Vector<>s with inline capacity, remove. | 6586 // Vector<>s with inline capacity, remove. |
6589 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) | 6587 #if !defined(ANNOTATE_CONTIGUOUS_CONTAINER) |
6590 EXPECT_EQ(16u, vector1.capacity()); | 6588 EXPECT_EQ(16u, vector1.capacity()); |
6591 EXPECT_EQ(16u, vector2.capacity()); | 6589 EXPECT_EQ(16u, vector2.capacity()); |
6592 #endif | 6590 #endif |
6593 } | 6591 } |
6594 | 6592 |
6595 TEST(HeapTest, TestStaticLocals) { | 6593 TEST(HeapTest, TestStaticLocals) { |
6596 // Sanity check DEFINE_STATIC_LOCAL()s over heap allocated objects and collect
ions. | 6594 // Sanity check DEFINE_STATIC_LOCAL()s over heap allocated objects and |
| 6595 // collections. |
6597 | 6596 |
6598 DEFINE_STATIC_LOCAL(IntWrapper, intWrapper, (new IntWrapper(33))); | 6597 DEFINE_STATIC_LOCAL(IntWrapper, intWrapper, (new IntWrapper(33))); |
6599 DEFINE_STATIC_LOCAL(PersistentHeapVector<Member<IntWrapper>>, | 6598 DEFINE_STATIC_LOCAL(PersistentHeapVector<Member<IntWrapper>>, |
6600 persistentHeapVectorIntWrapper, ()); | 6599 persistentHeapVectorIntWrapper, ()); |
6601 DEFINE_STATIC_LOCAL(HeapVector<Member<IntWrapper>>, heapVectorIntWrapper, | 6600 DEFINE_STATIC_LOCAL(HeapVector<Member<IntWrapper>>, heapVectorIntWrapper, |
6602 (new HeapVector<Member<IntWrapper>>)); | 6601 (new HeapVector<Member<IntWrapper>>)); |
6603 | 6602 |
6604 EXPECT_EQ(33, intWrapper.value()); | 6603 EXPECT_EQ(33, intWrapper.value()); |
6605 EXPECT_EQ(0u, persistentHeapVectorIntWrapper.size()); | 6604 EXPECT_EQ(0u, persistentHeapVectorIntWrapper.size()); |
6606 EXPECT_EQ(0u, heapVectorIntWrapper.size()); | 6605 EXPECT_EQ(0u, heapVectorIntWrapper.size()); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6802 "HeapVector"); | 6801 "HeapVector"); |
6803 static_assert( | 6802 static_assert( |
6804 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, | 6803 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, |
6805 "HeapDeque"); | 6804 "HeapDeque"); |
6806 static_assert(WTF::IsGarbageCollectedType< | 6805 static_assert(WTF::IsGarbageCollectedType< |
6807 HeapTerminatedArray<Member<IntWrapper>>>::value, | 6806 HeapTerminatedArray<Member<IntWrapper>>>::value, |
6808 "HeapTerminatedArray"); | 6807 "HeapTerminatedArray"); |
6809 } | 6808 } |
6810 | 6809 |
6811 } // namespace blink | 6810 } // namespace blink |
OLD | NEW |