| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef TraceTraits_h | 5 #ifndef TraceTraits_h |
| 6 #define TraceTraits_h | 6 #define TraceTraits_h |
| 7 | 7 |
| 8 #include "platform/heap/GCInfo.h" | 8 #include "platform/heap/GCInfo.h" |
| 9 #include "platform/heap/Heap.h" | 9 #include "platform/heap/Heap.h" |
| 10 #include "platform/heap/InlinedGlobalMarkingVisitor.h" | 10 #include "platform/heap/InlinedGlobalMarkingVisitor.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 template<typename T> class WeakMember; | 30 template<typename T> class WeakMember; |
| 31 | 31 |
| 32 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrai
t; | 32 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrai
t; |
| 33 | 33 |
| 34 template<typename T> | 34 template<typename T> |
| 35 class DefaultTraceTrait<T, false> { | 35 class DefaultTraceTrait<T, false> { |
| 36 public: | 36 public: |
| 37 template<typename VisitorDispatcher> | 37 template<typename VisitorDispatcher> |
| 38 static void mark(VisitorDispatcher visitor, const T* t) | 38 static void mark(VisitorDispatcher visitor, const T* t) |
| 39 { | 39 { |
| 40 #if ENABLE(ASSERT) |
| 41 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index()); |
| 42 #endif |
| 40 // Default mark method of the trait just calls the two-argument mark | 43 // Default mark method of the trait just calls the two-argument mark |
| 41 // method on the visitor. The second argument is the static trace method | 44 // method on the visitor. The second argument is the static trace method |
| 42 // of the trait, which by default calls the instance method | 45 // of the trait, which by default calls the instance method |
| 43 // trace(Visitor*) on the object. | 46 // trace(Visitor*) on the object. |
| 44 // | 47 // |
| 45 // If the trait allows it, invoke the trace callback right here on the | 48 // If the trait allows it, invoke the trace callback right here on the |
| 46 // not-yet-marked object. | 49 // not-yet-marked object. |
| 47 if (TraceEagerlyTrait<T>::value) { | 50 if (TraceEagerlyTrait<T>::value) { |
| 48 // Protect against too deep trace call chains, and the | 51 // Protect against too deep trace call chains, and the |
| 49 // unbounded system stack usage they can bring about. | 52 // unbounded system stack usage they can bring about. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 60 #endif | 63 #endif |
| 61 if (LIKELY(StackFrameDepth::isSafeToRecurse())) { | 64 if (LIKELY(StackFrameDepth::isSafeToRecurse())) { |
| 62 if (visitor->ensureMarked(t)) { | 65 if (visitor->ensureMarked(t)) { |
| 63 TraceTrait<T>::trace(visitor, const_cast<T*>(t)); | 66 TraceTrait<T>::trace(visitor, const_cast<T*>(t)); |
| 64 } | 67 } |
| 65 return; | 68 return; |
| 66 } | 69 } |
| 67 } | 70 } |
| 68 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 71 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
| 69 } | 72 } |
| 70 | |
| 71 #if ENABLE(ASSERT) | |
| 72 static void checkGCInfo(const T* t) | |
| 73 { | |
| 74 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index()); | |
| 75 } | |
| 76 #endif | |
| 77 }; | 73 }; |
| 78 | 74 |
| 79 template<typename T> | 75 template<typename T> |
| 80 class DefaultTraceTrait<T, true> { | 76 class DefaultTraceTrait<T, true> { |
| 81 public: | 77 public: |
| 82 template<typename VisitorDispatcher> | 78 template<typename VisitorDispatcher> |
| 83 static void mark(VisitorDispatcher visitor, const T* self) | 79 static void mark(VisitorDispatcher visitor, const T* self) |
| 84 { | 80 { |
| 85 if (!self) | 81 if (!self) |
| 86 return; | 82 return; |
| 87 | 83 |
| 88 // If you hit this ASSERT, it means that there is a dangling pointer | 84 // If you hit this ASSERT, it means that there is a dangling pointer |
| 89 // from a live thread heap to a dead thread heap. We must eliminate | 85 // from a live thread heap to a dead thread heap. We must eliminate |
| 90 // the dangling pointer. | 86 // the dangling pointer. |
| 91 // Release builds don't have the ASSERT, but it is OK because | 87 // Release builds don't have the ASSERT, but it is OK because |
| 92 // release builds will crash at the following self->adjustAndMark | 88 // release builds will crash at the following self->adjustAndMark |
| 93 // because all the entries of the orphaned heaps are zeroed out and | 89 // because all the entries of the orphaned heaps are zeroed out and |
| 94 // thus the item does not have a valid vtable. | 90 // thus the item does not have a valid vtable. |
| 95 ASSERT(!pageFromObject(self)->orphaned()); | 91 ASSERT(!pageFromObject(self)->orphaned()); |
| 96 self->adjustAndMark(visitor); | 92 self->adjustAndMark(visitor); |
| 97 } | 93 } |
| 98 | |
| 99 #if ENABLE(ASSERT) | |
| 100 static void checkGCInfo(const T*) { } | |
| 101 #endif | |
| 102 }; | 94 }; |
| 103 | 95 |
| 104 template<typename T, bool needsTracing> | 96 template<typename T, bool needsTracing> |
| 105 struct TraceIfEnabled; | 97 struct TraceIfEnabled; |
| 106 | 98 |
| 107 template<typename T> | 99 template<typename T> |
| 108 struct TraceIfEnabled<T, false> { | 100 struct TraceIfEnabled<T, false> { |
| 109 template<typename VisitorDispatcher> | 101 template<typename VisitorDispatcher> |
| 110 static void trace(VisitorDispatcher, T&) { } | 102 static void trace(VisitorDispatcher, T&) { } |
| 111 }; | 103 }; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 class TraceTrait { | 143 class TraceTrait { |
| 152 public: | 144 public: |
| 153 static void trace(Visitor*, void* self); | 145 static void trace(Visitor*, void* self); |
| 154 static void trace(InlinedGlobalMarkingVisitor, void* self); | 146 static void trace(InlinedGlobalMarkingVisitor, void* self); |
| 155 | 147 |
| 156 template<typename VisitorDispatcher> | 148 template<typename VisitorDispatcher> |
| 157 static void mark(VisitorDispatcher visitor, const T* t) | 149 static void mark(VisitorDispatcher visitor, const T* t) |
| 158 { | 150 { |
| 159 DefaultTraceTrait<T>::mark(visitor, t); | 151 DefaultTraceTrait<T>::mark(visitor, t); |
| 160 } | 152 } |
| 161 | |
| 162 #if ENABLE(ASSERT) | |
| 163 static void checkGCInfo(const T* t) | |
| 164 { | |
| 165 DefaultTraceTrait<T>::checkGCInfo(t); | |
| 166 } | |
| 167 #endif | |
| 168 }; | 153 }; |
| 169 | 154 |
| 170 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 155 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
| 171 | 156 |
| 172 template<typename T> | 157 template<typename T> |
| 173 void TraceTrait<T>::trace(Visitor* visitor, void* self) | 158 void TraceTrait<T>::trace(Visitor* visitor, void* self) |
| 174 { | 159 { |
| 175 if (visitor->isGlobalMarkingVisitor()) { | 160 if (visitor->isGlobalMarkingVisitor()) { |
| 176 // Switch to inlined global marking dispatch. | 161 // Switch to inlined global marking dispatch. |
| 177 static_cast<T*>(self)->trace(InlinedGlobalMarkingVisitor(visitor)); | 162 static_cast<T*>(self)->trace(InlinedGlobalMarkingVisitor(visitor)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 196 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); | 181 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); |
| 197 if (WTF::ShouldBeTraced<Traits>::value) | 182 if (WTF::ShouldBeTraced<Traits>::value) |
| 198 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | 183 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
| 199 } | 184 } |
| 200 | 185 |
| 201 template<typename VisitorDispatcher> | 186 template<typename VisitorDispatcher> |
| 202 static void mark(VisitorDispatcher visitor, const Backing* backing) | 187 static void mark(VisitorDispatcher visitor, const Backing* backing) |
| 203 { | 188 { |
| 204 DefaultTraceTrait<Backing>::mark(visitor, backing); | 189 DefaultTraceTrait<Backing>::mark(visitor, backing); |
| 205 } | 190 } |
| 206 static void checkGCInfo(Visitor* visitor, const Backing* backing) | |
| 207 { | |
| 208 #if ENABLE(ASSERT) | |
| 209 DefaultTraceTrait<Backing>::checkGCInfo(backing); | |
| 210 #endif | |
| 211 } | |
| 212 }; | 191 }; |
| 213 | 192 |
| 214 // The trace trait for the heap hashtable backing is used when we find a | 193 // The trace trait for the heap hashtable backing is used when we find a |
| 215 // direct pointer to the backing from the conservative stack scanner. This | 194 // direct pointer to the backing from the conservative stack scanner. This |
| 216 // normally indicates that there is an ongoing iteration over the table, and so | 195 // normally indicates that there is an ongoing iteration over the table, and so |
| 217 // we disable weak processing of table entries. When the backing is found | 196 // we disable weak processing of table entries. When the backing is found |
| 218 // through the owning hash table we mark differently, in order to do weak | 197 // through the owning hash table we mark differently, in order to do weak |
| 219 // processing. | 198 // processing. |
| 220 template<typename Table> | 199 template<typename Table> |
| 221 struct TraceTrait<HeapHashTableBacking<Table>> { | 200 struct TraceTrait<HeapHashTableBacking<Table>> { |
| 222 using Backing = HeapHashTableBacking<Table>; | 201 using Backing = HeapHashTableBacking<Table>; |
| 223 using Traits = typename Table::ValueTraits; | 202 using Traits = typename Table::ValueTraits; |
| 224 | 203 |
| 225 template<typename VisitorDispatcher> | 204 template<typename VisitorDispatcher> |
| 226 static void trace(VisitorDispatcher visitor, void* self) | 205 static void trace(VisitorDispatcher visitor, void* self) |
| 227 { | 206 { |
| 228 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 207 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
| 229 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); | 208 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); |
| 230 } | 209 } |
| 231 | 210 |
| 232 template<typename VisitorDispatcher> | 211 template<typename VisitorDispatcher> |
| 233 static void mark(VisitorDispatcher visitor, const Backing* backing) | 212 static void mark(VisitorDispatcher visitor, const Backing* backing) |
| 234 { | 213 { |
| 235 DefaultTraceTrait<Backing>::mark(visitor, backing); | 214 DefaultTraceTrait<Backing>::mark(visitor, backing); |
| 236 } | 215 } |
| 237 static void checkGCInfo(Visitor* visitor, const Backing* backing) | |
| 238 { | |
| 239 #if ENABLE(ASSERT) | |
| 240 DefaultTraceTrait<Backing>::checkGCInfo(backing); | |
| 241 #endif | |
| 242 } | |
| 243 }; | 216 }; |
| 244 | 217 |
| 245 // This trace trait for std::pair will null weak members if their referent is | 218 // This trace trait for std::pair will null weak members if their referent is |
| 246 // collected. If you have a collection that contain weakness it does not remove | 219 // collected. If you have a collection that contain weakness it does not remove |
| 247 // entries from the collection that contain nulled weak members. | 220 // entries from the collection that contain nulled weak members. |
| 248 template<typename T, typename U> | 221 template<typename T, typename U> |
| 249 class TraceTrait<std::pair<T, U>> { | 222 class TraceTrait<std::pair<T, U>> { |
| 250 public: | 223 public: |
| 251 static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::Is
Weak<T>::value; | 224 static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::Is
Weak<T>::value; |
| 252 static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::I
sWeak<U>::value; | 225 static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::I
sWeak<U>::value; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 // since iterating over the hash table backing will find the whole | 541 // since iterating over the hash table backing will find the whole |
| 569 // chain. | 542 // chain. |
| 570 visitor->markNoTracing(node); | 543 visitor->markNoTracing(node); |
| 571 return false; | 544 return false; |
| 572 } | 545 } |
| 573 }; | 546 }; |
| 574 | 547 |
| 575 } // namespace WTF | 548 } // namespace WTF |
| 576 | 549 |
| 577 #endif | 550 #endif |
| OLD | NEW |