| 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 |