OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 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 30 matching lines...) Expand all Loading... |
41 #include "wtf/Functional.h" | 41 #include "wtf/Functional.h" |
42 #include "wtf/HashFunctions.h" | 42 #include "wtf/HashFunctions.h" |
43 #include "wtf/Locker.h" | 43 #include "wtf/Locker.h" |
44 #include "wtf/MainThread.h" | 44 #include "wtf/MainThread.h" |
45 #include "wtf/RawPtr.h" | 45 #include "wtf/RawPtr.h" |
46 #include "wtf/RefCounted.h" | 46 #include "wtf/RefCounted.h" |
47 #include "wtf/TypeTraits.h" | 47 #include "wtf/TypeTraits.h" |
48 | 48 |
49 namespace blink { | 49 namespace blink { |
50 | 50 |
51 enum PersistentConfiguration { | 51 enum WeaknessPersistentConfiguration { |
52 NormalPersistentConfiguration, | 52 NonWeakPersistentConfiguration, |
53 WeakPersistentConfiguration, | 53 WeakPersistentConfiguration |
54 CrossThreadPersistentConfiguration, | |
55 }; | 54 }; |
56 | 55 |
57 template<typename T, PersistentConfiguration persistentConfiguration> | 56 enum CrossThreadnessPersistentConfiguration { |
| 57 SingleThreadPersistentConfiguration, |
| 58 CrossThreadPersistentConfiguration |
| 59 }; |
| 60 |
| 61 template<typename T, WeaknessPersistentConfiguration weaknessConfiguration, Cros
sThreadnessPersistentConfiguration crossThreadnessConfiguration> |
58 class PersistentBase { | 62 class PersistentBase { |
59 public: | 63 public: |
60 PersistentBase() : m_raw(nullptr) | 64 PersistentBase() : m_raw(nullptr) |
61 { | 65 { |
62 initialize(); | 66 initialize(); |
63 } | 67 } |
64 | 68 |
65 PersistentBase(std::nullptr_t) : m_raw(nullptr) | 69 PersistentBase(std::nullptr_t) : m_raw(nullptr) |
66 { | 70 { |
67 initialize(); | 71 initialize(); |
(...skipping 14 matching lines...) Expand all Loading... |
82 } | 86 } |
83 | 87 |
84 PersistentBase(const PersistentBase& other) : m_raw(other) | 88 PersistentBase(const PersistentBase& other) : m_raw(other) |
85 { | 89 { |
86 initialize(); | 90 initialize(); |
87 checkPointer(); | 91 checkPointer(); |
88 recordBacktrace(); | 92 recordBacktrace(); |
89 } | 93 } |
90 | 94 |
91 template<typename U> | 95 template<typename U> |
92 PersistentBase(const PersistentBase<U, persistentConfiguration>& other) : m_
raw(other) | 96 PersistentBase(const PersistentBase<U, weaknessConfiguration, crossThreadnes
sConfiguration>& other) : m_raw(other) |
93 { | 97 { |
94 initialize(); | 98 initialize(); |
95 checkPointer(); | 99 checkPointer(); |
96 recordBacktrace(); | 100 recordBacktrace(); |
97 } | 101 } |
98 | 102 |
99 template<typename U> | 103 template<typename U> |
100 PersistentBase(const Member<U>& other) : m_raw(other) | 104 PersistentBase(const Member<U>& other) : m_raw(other) |
101 { | 105 { |
102 initialize(); | 106 initialize(); |
(...skipping 13 matching lines...) Expand all Loading... |
116 { | 120 { |
117 uninitialize(); | 121 uninitialize(); |
118 m_raw = nullptr; | 122 m_raw = nullptr; |
119 } | 123 } |
120 | 124 |
121 template<typename VisitorDispatcher> | 125 template<typename VisitorDispatcher> |
122 void trace(VisitorDispatcher visitor) | 126 void trace(VisitorDispatcher visitor) |
123 { | 127 { |
124 static_assert(sizeof(T), "T must be fully defined"); | 128 static_assert(sizeof(T), "T must be fully defined"); |
125 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); | 129 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); |
126 if (persistentConfiguration == WeakPersistentConfiguration) { | 130 if (weaknessConfiguration == WeakPersistentConfiguration) { |
127 visitor->registerWeakCell(&m_raw); | 131 visitor->registerWeakCell(&m_raw); |
128 } else { | 132 } else { |
129 visitor->mark(m_raw); | 133 visitor->mark(m_raw); |
130 } | 134 } |
131 } | 135 } |
132 | 136 |
133 RawPtr<T> release() | 137 RawPtr<T> release() |
134 { | 138 { |
135 RawPtr<T> result = m_raw; | 139 RawPtr<T> result = m_raw; |
136 m_raw = nullptr; | 140 m_raw = nullptr; |
(...skipping 25 matching lines...) Expand all Loading... |
162 | 166 |
163 PersistentBase& operator=(const PersistentBase& other) | 167 PersistentBase& operator=(const PersistentBase& other) |
164 { | 168 { |
165 m_raw = other; | 169 m_raw = other; |
166 checkPointer(); | 170 checkPointer(); |
167 recordBacktrace(); | 171 recordBacktrace(); |
168 return *this; | 172 return *this; |
169 } | 173 } |
170 | 174 |
171 template<typename U> | 175 template<typename U> |
172 PersistentBase& operator=(const PersistentBase<U, persistentConfiguration>&
other) | 176 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro
ssThreadnessConfiguration>& other) |
173 { | 177 { |
174 m_raw = other; | 178 m_raw = other; |
175 checkPointer(); | 179 checkPointer(); |
176 recordBacktrace(); | 180 recordBacktrace(); |
177 return *this; | 181 return *this; |
178 } | 182 } |
179 | 183 |
180 template<typename U> | 184 template<typename U> |
181 PersistentBase& operator=(const Member<U>& other) | 185 PersistentBase& operator=(const Member<U>& other) |
182 { | 186 { |
(...skipping 10 matching lines...) Expand all Loading... |
193 checkPointer(); | 197 checkPointer(); |
194 recordBacktrace(); | 198 recordBacktrace(); |
195 return *this; | 199 return *this; |
196 } | 200 } |
197 | 201 |
198 | 202 |
199 private: | 203 private: |
200 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 204 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
201 void initialize() | 205 void initialize() |
202 { | 206 { |
203 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, pers
istentConfiguration>, &PersistentBase<T, persistentConfiguration>::trace>::tramp
oline; | 207 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; |
204 if (persistentConfiguration == CrossThreadPersistentConfiguration) { | 208 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
205 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca
tePersistentNode(this, traceCallback); | 209 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca
tePersistentNode(this, traceCallback); |
206 } else { | 210 } else { |
207 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); | 211 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); |
208 ASSERT(state->checkThread()); | 212 ASSERT(state->checkThread()); |
209 m_persistentNode = state->persistentRegion()->allocatePersistentNode
(this, traceCallback); | 213 m_persistentNode = state->persistentRegion()->allocatePersistentNode
(this, traceCallback); |
210 state->persistentAllocated(); | 214 state->persistentAllocated(); |
211 #if ENABLE(ASSERT) | 215 #if ENABLE(ASSERT) |
212 m_state = state; | 216 m_state = state; |
213 #endif | 217 #endif |
214 } | 218 } |
215 } | 219 } |
216 | 220 |
217 void uninitialize() | 221 void uninitialize() |
218 { | 222 { |
219 if (persistentConfiguration == CrossThreadPersistentConfiguration) { | 223 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
220 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers
istentNode); | 224 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers
istentNode); |
221 } else { | 225 } else { |
222 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); | 226 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); |
223 ASSERT(state->checkThread()); | 227 ASSERT(state->checkThread()); |
224 // Persistent handle must be created and destructed in the same thre
ad. | 228 // Persistent handle must be created and destructed in the same thre
ad. |
225 ASSERT(m_state == state); | 229 ASSERT(m_state == state); |
226 state->persistentRegion()->freePersistentNode(m_persistentNode); | 230 state->persistentRegion()->freePersistentNode(m_persistentNode); |
227 state->persistentFreed(); | 231 state->persistentFreed(); |
228 } | 232 } |
229 } | 233 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 #endif | 269 #endif |
266 }; | 270 }; |
267 | 271 |
268 // Persistent is a way to create a strong pointer from an on-heap object | 272 // Persistent is a way to create a strong pointer from an on-heap object |
269 // to another on-heap object. As long as the Persistent handle is alive | 273 // to another on-heap object. As long as the Persistent handle is alive |
270 // the GC will keep the object pointed to alive. The Persistent handle is | 274 // the GC will keep the object pointed to alive. The Persistent handle is |
271 // always a GC root from the point of view of the GC. | 275 // always a GC root from the point of view of the GC. |
272 // | 276 // |
273 // We have to construct and destruct Persistent in the same thread. | 277 // We have to construct and destruct Persistent in the same thread. |
274 template<typename T> | 278 template<typename T> |
275 class Persistent : public PersistentBase<T, NormalPersistentConfiguration> { | 279 class Persistent : public PersistentBase<T, NonWeakPersistentConfiguration, Sing
leThreadPersistentConfiguration> { |
276 typedef PersistentBase<T, NormalPersistentConfiguration> Parent; | 280 typedef PersistentBase<T, NonWeakPersistentConfiguration, SingleThreadPersis
tentConfiguration> Parent; |
277 public: | 281 public: |
278 Persistent() : Parent() { } | 282 Persistent() : Parent() { } |
279 Persistent(std::nullptr_t) : Parent(nullptr) { } | 283 Persistent(std::nullptr_t) : Parent(nullptr) { } |
280 Persistent(T* raw) : Parent(raw) { } | 284 Persistent(T* raw) : Parent(raw) { } |
281 Persistent(T& raw) : Parent(raw) { } | 285 Persistent(T& raw) : Parent(raw) { } |
282 Persistent(const Persistent& other) : Parent(other) { } | 286 Persistent(const Persistent& other) : Parent(other) { } |
283 template<typename U> | 287 template<typename U> |
284 Persistent(const Persistent<U>& other) : Parent(other) { } | 288 Persistent(const Persistent<U>& other) : Parent(other) { } |
285 template<typename U> | 289 template<typename U> |
286 Persistent(const Member<U>& other) : Parent(other) { } | 290 Persistent(const Member<U>& other) : Parent(other) { } |
287 template<typename U> | 291 template<typename U> |
288 Persistent(const RawPtr<U>& other) : Parent(other.get()) { } | 292 Persistent(const RawPtr<U>& other) : Parent(other.get()) { } |
289 }; | 293 }; |
290 | 294 |
291 // WeakPersistent is a way to create a weak pointer from an off-heap object | 295 // WeakPersistent is a way to create a weak pointer from an off-heap object |
292 // to an on-heap object. The m_raw is automatically cleared when the pointee | 296 // to an on-heap object. The m_raw is automatically cleared when the pointee |
293 // gets collected. | 297 // gets collected. |
294 // | 298 // |
295 // We have to construct and destruct WeakPersistent in the same thread. | 299 // We have to construct and destruct WeakPersistent in the same thread. |
296 // | 300 // |
297 // Note that collections of WeakPersistents are not supported. Use a persistent | 301 // Note that collections of WeakPersistents are not supported. Use a persistent |
298 // collection of WeakMembers instead. | 302 // collection of WeakMembers instead. |
299 // | 303 // |
300 // HashSet<WeakPersistent<T>> m_set; // wrong | 304 // HashSet<WeakPersistent<T>> m_set; // wrong |
301 // PersistentHeapHashSet<WeakMember<T>> m_set; // correct | 305 // PersistentHeapHashSet<WeakMember<T>> m_set; // correct |
302 template<typename T> | 306 template<typename T> |
303 class WeakPersistent : public PersistentBase<T, WeakPersistentConfiguration> { | 307 class WeakPersistent : public PersistentBase<T, WeakPersistentConfiguration, Sin
gleThreadPersistentConfiguration> { |
304 typedef PersistentBase<T, WeakPersistentConfiguration> Parent; | 308 typedef PersistentBase<T, WeakPersistentConfiguration, SingleThreadPersisten
tConfiguration> Parent; |
305 public: | 309 public: |
306 WeakPersistent() : Parent() { } | 310 WeakPersistent() : Parent() { } |
307 WeakPersistent(std::nullptr_t) : Parent(nullptr) { } | 311 WeakPersistent(std::nullptr_t) : Parent(nullptr) { } |
308 WeakPersistent(T* raw) : Parent(raw) { } | 312 WeakPersistent(T* raw) : Parent(raw) { } |
309 WeakPersistent(T& raw) : Parent(raw) { } | 313 WeakPersistent(T& raw) : Parent(raw) { } |
310 WeakPersistent(const WeakPersistent& other) : Parent(other) { } | 314 WeakPersistent(const WeakPersistent& other) : Parent(other) { } |
311 template<typename U> | 315 template<typename U> |
312 WeakPersistent(const WeakPersistent<U>& other) : Parent(other) { } | 316 WeakPersistent(const WeakPersistent<U>& other) : Parent(other) { } |
313 template<typename U> | 317 template<typename U> |
314 WeakPersistent(const Member<U>& other) : Parent(other) { } | 318 WeakPersistent(const Member<U>& other) : Parent(other) { } |
315 template<typename U> | 319 template<typename U> |
316 WeakPersistent(const RawPtr<U>& other) : Parent(other.get()) { } | 320 WeakPersistent(const RawPtr<U>& other) : Parent(other.get()) { } |
317 }; | 321 }; |
318 | 322 |
319 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread | 323 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread |
320 // different from the construction thread. | 324 // different from the construction thread. |
321 template<typename T> | 325 template<typename T> |
322 class CrossThreadPersistent : public PersistentBase<T, CrossThreadPersistentConf
iguration> { | 326 class CrossThreadPersistent : public PersistentBase<T, NonWeakPersistentConfigur
ation, CrossThreadPersistentConfiguration> { |
323 typedef PersistentBase<T, CrossThreadPersistentConfiguration> Parent; | 327 typedef PersistentBase<T, NonWeakPersistentConfiguration, CrossThreadPersist
entConfiguration> Parent; |
324 public: | 328 public: |
325 CrossThreadPersistent() : Parent() { } | 329 CrossThreadPersistent() : Parent() { } |
326 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } | 330 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } |
327 CrossThreadPersistent(T* raw) : Parent(raw) { } | 331 CrossThreadPersistent(T* raw) : Parent(raw) { } |
328 CrossThreadPersistent(T& raw) : Parent(raw) { } | 332 CrossThreadPersistent(T& raw) : Parent(raw) { } |
329 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) {
} | 333 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) {
} |
330 template<typename U> | 334 template<typename U> |
331 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other)
{ } | 335 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other)
{ } |
332 template<typename U> | 336 template<typename U> |
333 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } | 337 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } |
334 template<typename U> | 338 template<typename U> |
335 CrossThreadPersistent(const RawPtr<U>& other) : Parent(other.get()) { } | 339 CrossThreadPersistent(const RawPtr<U>& other) : Parent(other.get()) { } |
336 }; | 340 }; |
337 | 341 |
| 342 template<typename T> |
| 343 class CrossThreadWeakPersistent : public PersistentBase<T, WeakPersistentConfigu
ration, CrossThreadPersistentConfiguration> { |
| 344 typedef PersistentBase<T, WeakPersistentConfiguration, CrossThreadPersistent
Configuration> Parent; |
| 345 public: |
| 346 CrossThreadWeakPersistent() : Parent() { } |
| 347 CrossThreadWeakPersistent(std::nullptr_t) : Parent(nullptr) { } |
| 348 CrossThreadWeakPersistent(T* raw) : Parent(raw) { } |
| 349 CrossThreadWeakPersistent(T& raw) : Parent(raw) { } |
| 350 CrossThreadWeakPersistent(const CrossThreadWeakPersistent& other) : Parent(o
ther) { } |
| 351 template<typename U> |
| 352 CrossThreadWeakPersistent(const CrossThreadWeakPersistent<U>& other) : Paren
t(other) { } |
| 353 template<typename U> |
| 354 CrossThreadWeakPersistent(const Member<U>& other) : Parent(other) { } |
| 355 template<typename U> |
| 356 CrossThreadWeakPersistent(const RawPtr<U>& other) : Parent(other.get()) { } |
| 357 }; |
| 358 |
338 // PersistentNode must be the left-most class to let the | 359 // PersistentNode must be the left-most class to let the |
339 // visitor->trace(static_cast<Collection*>(this)) trace the correct position. | 360 // visitor->trace(static_cast<Collection*>(this)) trace the correct position. |
340 // FIXME: derive affinity based on the collection. | 361 // FIXME: derive affinity based on the collection. |
341 template<typename Collection> | 362 template<typename Collection> |
342 class PersistentHeapCollectionBase : public Collection { | 363 class PersistentHeapCollectionBase : public Collection { |
343 // We overload the various new and delete operators with using the WTF Defau
ltAllocator to ensure persistent | 364 // We overload the various new and delete operators with using the WTF Defau
ltAllocator to ensure persistent |
344 // heap collections are always allocated off-heap. This allows persistent co
llections to be used in | 365 // heap collections are always allocated off-heap. This allows persistent co
llections to be used in |
345 // DEFINE_STATIC_LOCAL et. al. | 366 // DEFINE_STATIC_LOCAL et. al. |
346 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); | 367 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); |
347 public: | 368 public: |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin
k::IsGarbageCollectedType<T>::value> { | 1177 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin
k::IsGarbageCollectedType<T>::value> { |
1157 static_assert(sizeof(T), "T must be fully defined"); | 1178 static_assert(sizeof(T), "T must be fully defined"); |
1158 }; | 1179 }; |
1159 | 1180 |
1160 template<typename T> | 1181 template<typename T> |
1161 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1182 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1162 | 1183 |
1163 } // namespace WTF | 1184 } // namespace WTF |
1164 | 1185 |
1165 #endif | 1186 #endif |
OLD | NEW |