| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // No locking required. Just check that we are at the right thread. | 97 // No locking required. Just check that we are at the right thread. |
| 98 class Lock { | 98 class Lock { |
| 99 public: | 99 public: |
| 100 Lock() { state()->checkThread(); } | 100 Lock() { state()->checkThread(); } |
| 101 }; | 101 }; |
| 102 | 102 |
| 103 private: | 103 private: |
| 104 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); } | 104 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); } |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 // RootsAccessor for Persistent that provides synchronized access to global | |
| 108 // list of persistent handles. Can be used for persistent handles that are | |
| 109 // passed between threads. | |
| 110 class GlobalPersistents { | |
| 111 public: | |
| 112 static PersistentNode* roots() { return ThreadState::globalRoots(); } | |
| 113 | |
| 114 class Lock { | |
| 115 public: | |
| 116 Lock() : m_locker(ThreadState::globalRootsMutex()) { } | |
| 117 private: | |
| 118 MutexLocker m_locker; | |
| 119 }; | |
| 120 }; | |
| 121 | |
| 122 // Base class for persistent handles. RootsAccessor specifies which list to | 107 // Base class for persistent handles. RootsAccessor specifies which list to |
| 123 // link resulting handle into. Owner specifies the class containing trace | 108 // link resulting handle into. Owner specifies the class containing trace |
| 124 // method. | 109 // method. |
| 125 template<typename RootsAccessor, typename Owner> | 110 template<typename RootsAccessor, typename Owner> |
| 126 class PersistentBase : public PersistentNode { | 111 class PersistentBase : public PersistentNode { |
| 127 public: | 112 public: |
| 128 ~PersistentBase() | 113 ~PersistentBase() |
| 129 { | 114 { |
| 130 typename RootsAccessor::Lock lock; | 115 typename RootsAccessor::Lock lock; |
| 131 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is u
sing the same roots list. | 116 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is u
sing the same roots list. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 151 } | 136 } |
| 152 | 137 |
| 153 inline explicit PersistentBase(const PersistentBase& otherref) | 138 inline explicit PersistentBase(const PersistentBase& otherref) |
| 154 : PersistentNode(otherref.m_trace) | 139 : PersistentNode(otherref.m_trace) |
| 155 #if ENABLE(ASSERT) | 140 #if ENABLE(ASSERT) |
| 156 , m_roots(RootsAccessor::roots()) | 141 , m_roots(RootsAccessor::roots()) |
| 157 #endif | 142 #endif |
| 158 { | 143 { |
| 159 // We don't support allocation of thread local Persistents while doing | 144 // We don't support allocation of thread local Persistents while doing |
| 160 // thread shutdown/cleanup. | 145 // thread shutdown/cleanup. |
| 161 ASSERT(!ThreadState::current()->isTerminating()); | |
| 162 typename RootsAccessor::Lock lock; | 146 typename RootsAccessor::Lock lock; |
| 163 ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same
list. | 147 ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same
list. |
| 164 PersistentBase* other = const_cast<PersistentBase*>(&otherref); | 148 PersistentBase* other = const_cast<PersistentBase*>(&otherref); |
| 165 m_prev = other; | 149 m_prev = other; |
| 166 m_next = other->m_next; | 150 m_next = other->m_next; |
| 167 other->m_next = this; | 151 other->m_next = this; |
| 168 m_next->m_prev = this; | 152 m_next->m_prev = this; |
| 169 } | 153 } |
| 170 | 154 |
| 171 inline PersistentBase& operator=(const PersistentBase& otherref) { return *t
his; } | 155 inline PersistentBase& operator=(const PersistentBase& otherref) { return *t
his; } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 private: | 189 private: |
| 206 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P
ersistentAnchor::trace>::trampoline) | 190 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P
ersistentAnchor::trace>::trampoline) |
| 207 { | 191 { |
| 208 m_next = this; | 192 m_next = this; |
| 209 m_prev = this; | 193 m_prev = this; |
| 210 } | 194 } |
| 211 | 195 |
| 212 friend class ThreadState; | 196 friend class ThreadState; |
| 213 }; | 197 }; |
| 214 | 198 |
| 215 #if ENABLE(ASSERT) | |
| 216 // For global persistent handles we cannot check that the | |
| 217 // pointer is in the heap because that would involve | |
| 218 // inspecting the heap of running threads. | |
| 219 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \ | |
| 220 bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>:
:value; \ | |
| 221 ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::A
ffinity>::state()->contains(pointer)) | |
| 222 #else | |
| 223 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) | |
| 224 #endif | |
| 225 | |
| 226 template<typename T> | 199 template<typename T> |
| 227 class CrossThreadPersistent; | 200 class CrossThreadPersistent; |
| 228 | 201 |
| 229 // Persistent handles are used to store pointers into the | 202 // Persistent handles are used to store pointers into the |
| 230 // managed heap. As long as the Persistent handle is alive | 203 // managed heap. As long as the Persistent handle is alive |
| 231 // the GC will keep the object pointed to alive. Persistent | 204 // the GC will keep the object pointed to alive. Persistent |
| 232 // handles can be stored in objects and they are not scoped. | 205 // handles can be stored in objects and they are not scoped. |
| 233 // Persistent handles must not be used to contain pointers | 206 // Persistent handles must not be used to contain pointers |
| 234 // between objects that are in the managed heap. They are only | 207 // between objects that are in the managed heap. They are only |
| 235 // meant to point to managed heap objects from variables/members | 208 // meant to point to managed heap objects from variables/members |
| 236 // outside the managed heap. | 209 // outside the managed heap. |
| 237 // | 210 // |
| 238 // A Persistent is always a GC root from the point of view of | 211 // A Persistent is always a GC root from the point of view of |
| 239 // the garbage collector. | 212 // the garbage collector. |
| 240 // | 213 // |
| 241 // We have to construct and destruct Persistent with default RootsAccessor in | 214 // We have to construct and destruct Persistent with default RootsAccessor in |
| 242 // the same thread. | 215 // the same thread. |
| 243 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<Threadin
gTrait<T>::Affinity > */ > | 216 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<Threadin
gTrait<T>::Affinity > */ > |
| 244 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAcces
sor> > { | 217 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAcces
sor> > { |
| 245 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); | 218 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); |
| 246 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); | 219 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); |
| 247 public: | 220 public: |
| 248 Persistent() : m_raw(0) { } | 221 Persistent() : m_raw(0) { } |
| 249 | 222 |
| 250 Persistent(std::nullptr_t) : m_raw(0) { } | 223 Persistent(std::nullptr_t) : m_raw(0) { } |
| 251 | 224 |
| 252 Persistent(T* raw) : m_raw(raw) | 225 Persistent(T* raw) : m_raw(raw) |
| 253 { | 226 { |
| 254 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); | |
| 255 recordBacktrace(); | 227 recordBacktrace(); |
| 256 } | 228 } |
| 257 | 229 |
| 258 explicit Persistent(T& raw) : m_raw(&raw) | 230 explicit Persistent(T& raw) : m_raw(&raw) |
| 259 { | 231 { |
| 260 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); | |
| 261 recordBacktrace(); | 232 recordBacktrace(); |
| 262 } | 233 } |
| 263 | 234 |
| 264 Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); } | 235 Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); } |
| 265 | 236 |
| 266 template<typename U> | 237 template<typename U> |
| 267 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recor
dBacktrace(); } | 238 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recor
dBacktrace(); } |
| 268 | 239 |
| 269 template<typename U> | 240 template<typename U> |
| 270 Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); } | 241 Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 | 337 |
| 367 String m_tracingName; | 338 String m_tracingName; |
| 368 #else | 339 #else |
| 369 inline void recordBacktrace() const { } | 340 inline void recordBacktrace() const { } |
| 370 #endif | 341 #endif |
| 371 T* m_raw; | 342 T* m_raw; |
| 372 | 343 |
| 373 friend class CrossThreadPersistent<T>; | 344 friend class CrossThreadPersistent<T>; |
| 374 }; | 345 }; |
| 375 | 346 |
| 376 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread | |
| 377 // different from the construction thread. | |
| 378 template<typename T> | |
| 379 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { | |
| 380 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); | |
| 381 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); | |
| 382 public: | |
| 383 CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { } | |
| 384 | |
| 385 using Persistent<T, GlobalPersistents>::operator=; | |
| 386 }; | |
| 387 | |
| 388 // FIXME: derive affinity based on the collection. | 347 // FIXME: derive affinity based on the collection. |
| 389 template<typename Collection, ThreadAffinity Affinity = AnyThread> | 348 template<typename Collection, ThreadAffinity Affinity = AnyThread> |
| 390 class PersistentHeapCollectionBase | 349 class PersistentHeapCollectionBase |
| 391 : public Collection | 350 : public Collection |
| 392 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColl
ectionBase<Collection, Affinity> > { | 351 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColl
ectionBase<Collection, Affinity> > { |
| 393 // We overload the various new and delete operators with using the WTF Defau
ltAllocator to ensure persistent | 352 // We overload the various new and delete operators with using the WTF Defau
ltAllocator to ensure persistent |
| 394 // heap collections are always allocated off-heap. This allows persistent co
llections to be used in | 353 // heap collections are always allocated off-heap. This allows persistent co
llections to be used in |
| 395 // DEFINE_STATIC_LOCAL et. al. | 354 // DEFINE_STATIC_LOCAL et. al. |
| 396 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); | 355 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); |
| 397 public: | 356 public: |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, false> { | 864 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, false> { |
| 906 }; | 865 }; |
| 907 | 866 |
| 908 template<typename T> | 867 template<typename T> |
| 909 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, fal
se> { | 868 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, fal
se> { |
| 910 }; | 869 }; |
| 911 | 870 |
| 912 } // namespace WTF | 871 } // namespace WTF |
| 913 | 872 |
| 914 #endif | 873 #endif |
| OLD | NEW |