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 29 matching lines...) Expand all Loading... |
40 class WeakPersistent; | 40 class WeakPersistent; |
41 | 41 |
42 template <typename T, bool = NeedsAdjustAndMark<T>::value> | 42 template <typename T, bool = NeedsAdjustAndMark<T>::value> |
43 class AdjustAndMarkTrait; | 43 class AdjustAndMarkTrait; |
44 | 44 |
45 template <typename T> | 45 template <typename T> |
46 class AdjustAndMarkTrait<T, false> { | 46 class AdjustAndMarkTrait<T, false> { |
47 STATIC_ONLY(AdjustAndMarkTrait); | 47 STATIC_ONLY(AdjustAndMarkTrait); |
48 | 48 |
49 public: | 49 public: |
50 static void markAndTraceWrapper(const WrapperVisitor* visitor, const T* t) { | |
51 if (visitor->markWrapperHeader(heapObjectHeader(t))) { | |
52 visitor->markWrappersInAllWorlds(t); | |
53 visitor->dispatchTraceWrappers(t); | |
54 } | |
55 } | |
56 static void markWrapperNoTracing(const WrapperVisitor* visitor, const T* t) { | |
57 DCHECK(!heapObjectHeader(t)->isWrapperHeaderMarked()); | |
58 visitor->markWrapperHeader(heapObjectHeader(t)); | |
59 } | |
60 static void traceMarkedWrapper(const WrapperVisitor* visitor, const T* t) { | |
61 DCHECK(heapObjectHeader(t)->isWrapperHeaderMarked()); | |
62 // The term *mark* is misleading here as we effectively trace through the | |
63 // API boundary, i.e., tell V8 that an object is alive. Actual marking | |
64 // will be done in V8. | |
65 visitor->markWrappersInAllWorlds(t); | |
66 visitor->dispatchTraceWrappers(t); | |
67 } | |
68 static HeapObjectHeader* heapObjectHeader(const T* t) { | |
69 return HeapObjectHeader::fromPayload(t); | |
70 } | |
71 | |
72 template <typename VisitorDispatcher> | 50 template <typename VisitorDispatcher> |
73 static void mark(VisitorDispatcher visitor, const T* t) { | 51 static void mark(VisitorDispatcher visitor, const T* t) { |
74 #if ENABLE(ASSERT) | 52 #if ENABLE(ASSERT) |
75 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index()); | 53 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index()); |
76 #endif | 54 #endif |
77 // Default mark method of the trait just calls the two-argument mark | 55 // Default mark method of the trait just calls the two-argument mark |
78 // method on the visitor. The second argument is the static trace method | 56 // method on the visitor. The second argument is the static trace method |
79 // of the trait, which by default calls the instance method | 57 // of the trait, which by default calls the instance method |
80 // trace(Visitor*) on the object. | 58 // trace(Visitor*) on the object. |
81 // | 59 // |
(...skipping 22 matching lines...) Expand all Loading... |
104 } | 82 } |
105 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 83 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
106 } | 84 } |
107 }; | 85 }; |
108 | 86 |
109 template <typename T> | 87 template <typename T> |
110 class AdjustAndMarkTrait<T, true> { | 88 class AdjustAndMarkTrait<T, true> { |
111 STATIC_ONLY(AdjustAndMarkTrait); | 89 STATIC_ONLY(AdjustAndMarkTrait); |
112 | 90 |
113 public: | 91 public: |
114 static void markAndTraceWrapper(const WrapperVisitor* visitor, const T* t) { | |
115 t->adjustAndMarkAndTraceWrapper(visitor); | |
116 } | |
117 static void markWrapperNoTracing(const WrapperVisitor* visitor, const T* t) { | |
118 t->adjustAndMarkWrapperNoTracing(visitor); | |
119 } | |
120 static void traceMarkedWrapper(const WrapperVisitor* visitor, const T* t) { | |
121 t->adjustAndTraceMarkedWrapper(visitor); | |
122 } | |
123 static HeapObjectHeader* heapObjectHeader(const T* t) { | |
124 return t->adjustAndGetHeapObjectHeader(); | |
125 } | |
126 | |
127 template <typename VisitorDispatcher> | 92 template <typename VisitorDispatcher> |
128 static void mark(VisitorDispatcher visitor, const T* self) { | 93 static void mark(VisitorDispatcher visitor, const T* self) { |
129 if (!self) | 94 if (!self) |
130 return; | 95 return; |
131 | 96 |
132 // If you hit this ASSERT, it means that there is a dangling pointer | 97 // If you hit this ASSERT, it means that there is a dangling pointer |
133 // from a live thread heap to a dead thread heap. We must eliminate | 98 // from a live thread heap to a dead thread heap. We must eliminate |
134 // the dangling pointer. | 99 // the dangling pointer. |
135 // Release builds don't have the ASSERT, but it is OK because | 100 // Release builds don't have the ASSERT, but it is OK because |
136 // release builds will crash at the following self->adjustAndMark | 101 // release builds will crash at the following self->adjustAndMark |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 // to the start of the object in the Blink garbage-collected heap. In | 181 // to the start of the object in the Blink garbage-collected heap. In |
217 // that case the pointer has to be adjusted before marking. | 182 // that case the pointer has to be adjusted before marking. |
218 template <typename T> | 183 template <typename T> |
219 class TraceTrait { | 184 class TraceTrait { |
220 STATIC_ONLY(TraceTrait); | 185 STATIC_ONLY(TraceTrait); |
221 | 186 |
222 public: | 187 public: |
223 static void trace(Visitor*, void* self); | 188 static void trace(Visitor*, void* self); |
224 static void trace(InlinedGlobalMarkingVisitor, void* self); | 189 static void trace(InlinedGlobalMarkingVisitor, void* self); |
225 | 190 |
226 static void markAndTraceWrapper(const WrapperVisitor* visitor, | 191 static void markAndTraceWrapper(const WrapperVisitor*, const void*); |
227 const void* t) { | 192 static void markWrapperNoTracing(const WrapperVisitor*, const void*); |
228 static_assert(CanTraceWrappers<T>::value, | 193 static void traceMarkedWrapper(const WrapperVisitor*, const void*); |
229 "T should be able to trace wrappers. See " | 194 static HeapObjectHeader* heapObjectHeader(const void*); |
230 "dispatchTraceWrappers in WrapperVisitor.h"); | |
231 AdjustAndMarkTrait<T>::markAndTraceWrapper(visitor, | |
232 reinterpret_cast<const T*>(t)); | |
233 } | |
234 static void markWrapperNoTracing(const WrapperVisitor* visitor, | |
235 const void* t) { | |
236 static_assert(CanTraceWrappers<T>::value, | |
237 "T should be able to trace wrappers. See " | |
238 "dispatchTraceWrappers in WrapperVisitor.h"); | |
239 AdjustAndMarkTrait<T>::markWrapperNoTracing(visitor, | |
240 reinterpret_cast<const T*>(t)); | |
241 } | |
242 static void traceMarkedWrapper(const WrapperVisitor* visitor, const void* t) { | |
243 static_assert(CanTraceWrappers<T>::value, | |
244 "T should be able to trace wrappers. See " | |
245 "dispatchTraceWrappers in WrapperVisitor.h"); | |
246 AdjustAndMarkTrait<T>::traceMarkedWrapper(visitor, | |
247 reinterpret_cast<const T*>(t)); | |
248 } | |
249 static HeapObjectHeader* heapObjectHeader(const void* t) { | |
250 static_assert(CanTraceWrappers<T>::value, | |
251 "T should be able to trace wrappers. See " | |
252 "dispatchTraceWrappers in WrapperVisitor.h"); | |
253 return AdjustAndMarkTrait<T>::heapObjectHeader( | |
254 reinterpret_cast<const T*>(t)); | |
255 } | |
256 | 195 |
257 template <typename VisitorDispatcher> | 196 template <typename VisitorDispatcher> |
258 static void mark(VisitorDispatcher visitor, const T* t) { | 197 static void mark(VisitorDispatcher visitor, const T* t) { |
259 AdjustAndMarkTrait<T>::mark(visitor, t); | 198 AdjustAndMarkTrait<T>::mark(visitor, t); |
260 } | 199 } |
| 200 |
| 201 private: |
| 202 static const T* ToWrapperTracingType(const void* t) { |
| 203 static_assert(CanTraceWrappers<T>::value, |
| 204 "T should be able to trace wrappers. See " |
| 205 "dispatchTraceWrappers in WrapperVisitor.h"); |
| 206 static_assert(!NeedsAdjustAndMark<T>::value, |
| 207 "wrapper tracing is not supported within mixins"); |
| 208 #if DCHECK_IS_ON() |
| 209 DCHECK(HeapObjectHeader::fromPayload(t)->checkHeader()); |
| 210 #endif |
| 211 return reinterpret_cast<const T*>(t); |
| 212 } |
261 }; | 213 }; |
262 | 214 |
263 template <typename T> | 215 template <typename T> |
264 class TraceTrait<const T> : public TraceTrait<T> {}; | 216 class TraceTrait<const T> : public TraceTrait<T> {}; |
265 | 217 |
266 template <typename T> | 218 template <typename T> |
267 void TraceTrait<T>::trace(Visitor* visitor, void* self) { | 219 void TraceTrait<T>::trace(Visitor* visitor, void* self) { |
268 static_assert(WTF::IsTraceable<T>::value, "T should not be traced"); | 220 static_assert(WTF::IsTraceable<T>::value, "T should not be traced"); |
269 if (visitor->isGlobalMarking()) { | 221 if (visitor->isGlobalMarking()) { |
270 // Switch to inlined global marking dispatch. | 222 // Switch to inlined global marking dispatch. |
271 static_cast<T*>(self)->trace(InlinedGlobalMarkingVisitor( | 223 static_cast<T*>(self)->trace(InlinedGlobalMarkingVisitor( |
272 visitor->state(), visitor->getMarkingMode())); | 224 visitor->state(), visitor->getMarkingMode())); |
273 } else { | 225 } else { |
274 static_cast<T*>(self)->trace(visitor); | 226 static_cast<T*>(self)->trace(visitor); |
275 } | 227 } |
276 } | 228 } |
277 | 229 |
278 template <typename T> | 230 template <typename T> |
279 void TraceTrait<T>::trace(InlinedGlobalMarkingVisitor visitor, void* self) { | 231 void TraceTrait<T>::trace(InlinedGlobalMarkingVisitor visitor, void* self) { |
280 static_assert(WTF::IsTraceable<T>::value, "T should not be traced"); | 232 static_assert(WTF::IsTraceable<T>::value, "T should not be traced"); |
281 static_cast<T*>(self)->trace(visitor); | 233 static_cast<T*>(self)->trace(visitor); |
282 } | 234 } |
283 | 235 |
| 236 template <typename T> |
| 237 void TraceTrait<T>::markAndTraceWrapper(const WrapperVisitor* visitor, |
| 238 const void* t) { |
| 239 const T* traceable = ToWrapperTracingType(t); |
| 240 if (visitor->markWrapperHeader(heapObjectHeader(traceable))) { |
| 241 visitor->markWrappersInAllWorlds(traceable); |
| 242 visitor->dispatchTraceWrappers(traceable); |
| 243 } |
| 244 } |
| 245 |
| 246 template <typename T> |
| 247 void TraceTrait<T>::markWrapperNoTracing(const WrapperVisitor* visitor, |
| 248 const void* t) { |
| 249 const T* traceable = ToWrapperTracingType(t); |
| 250 DCHECK(!heapObjectHeader(traceable)->isWrapperHeaderMarked()); |
| 251 visitor->markWrapperHeader(heapObjectHeader(traceable)); |
| 252 } |
| 253 |
| 254 template <typename T> |
| 255 void TraceTrait<T>::traceMarkedWrapper(const WrapperVisitor* visitor, |
| 256 const void* t) { |
| 257 const T* traceable = ToWrapperTracingType(t); |
| 258 DCHECK(heapObjectHeader(t)->isWrapperHeaderMarked()); |
| 259 // The term *mark* is misleading here as we effectively trace through the |
| 260 // API boundary, i.e., tell V8 that an object is alive. Actual marking |
| 261 // will be done in V8. |
| 262 visitor->markWrappersInAllWorlds(traceable); |
| 263 visitor->dispatchTraceWrappers(traceable); |
| 264 } |
| 265 |
| 266 template <typename T> |
| 267 HeapObjectHeader* TraceTrait<T>::heapObjectHeader(const void* t) { |
| 268 return HeapObjectHeader::fromPayload(ToWrapperTracingType(t)); |
| 269 } |
| 270 |
284 template <typename T, typename Traits> | 271 template <typename T, typename Traits> |
285 struct TraceTrait<HeapVectorBacking<T, Traits>> { | 272 struct TraceTrait<HeapVectorBacking<T, Traits>> { |
286 STATIC_ONLY(TraceTrait); | 273 STATIC_ONLY(TraceTrait); |
287 using Backing = HeapVectorBacking<T, Traits>; | 274 using Backing = HeapVectorBacking<T, Traits>; |
288 | 275 |
289 template <typename VisitorDispatcher> | 276 template <typename VisitorDispatcher> |
290 static void trace(VisitorDispatcher visitor, void* self) { | 277 static void trace(VisitorDispatcher visitor, void* self) { |
291 static_assert(!WTF::IsWeak<T>::value, | 278 static_assert(!WTF::IsWeak<T>::value, |
292 "weakness in HeapVectors and HeapDeques are not supported"); | 279 "weakness in HeapVectors and HeapDeques are not supported"); |
293 if (WTF::IsTraceableInCollectionTrait<Traits>::value) | 280 if (WTF::IsTraceableInCollectionTrait<Traits>::value) |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 // since iterating over the hash table backing will find the whole | 802 // since iterating over the hash table backing will find the whole |
816 // chain. | 803 // chain. |
817 visitor->markNoTracing(node); | 804 visitor->markNoTracing(node); |
818 return false; | 805 return false; |
819 } | 806 } |
820 }; | 807 }; |
821 | 808 |
822 } // namespace WTF | 809 } // namespace WTF |
823 | 810 |
824 #endif | 811 #endif |
OLD | NEW |