| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 Persistent_h | 5 #ifndef Persistent_h |
| 6 #define Persistent_h | 6 #define Persistent_h |
| 7 | 7 |
| 8 #include "platform/heap/Heap.h" | 8 #include "platform/heap/Heap.h" |
| 9 #include "platform/heap/Member.h" | 9 #include "platform/heap/Member.h" |
| 10 #include "platform/heap/PersistentNode.h" | 10 #include "platform/heap/PersistentNode.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 CrossThreadPersistentConfiguration | 32 CrossThreadPersistentConfiguration |
| 33 }; | 33 }; |
| 34 | 34 |
| 35 template<typename T, WeaknessPersistentConfiguration weaknessConfiguration, Cros
sThreadnessPersistentConfiguration crossThreadnessConfiguration> | 35 template<typename T, WeaknessPersistentConfiguration weaknessConfiguration, Cros
sThreadnessPersistentConfiguration crossThreadnessConfiguration> |
| 36 class PersistentBase { | 36 class PersistentBase { |
| 37 USING_FAST_MALLOC(PersistentBase); | 37 USING_FAST_MALLOC(PersistentBase); |
| 38 IS_PERSISTENT_REFERENCE_TYPE(); | 38 IS_PERSISTENT_REFERENCE_TYPE(); |
| 39 public: | 39 public: |
| 40 PersistentBase() : m_raw(nullptr) | 40 PersistentBase() : m_raw(nullptr) |
| 41 { | 41 { |
| 42 saveCreationThreadHeap(); |
| 42 initialize(); | 43 initialize(); |
| 43 } | 44 } |
| 44 | 45 |
| 45 PersistentBase(std::nullptr_t) : m_raw(nullptr) | 46 PersistentBase(std::nullptr_t) : m_raw(nullptr) |
| 46 { | 47 { |
| 48 saveCreationThreadHeap(); |
| 47 initialize(); | 49 initialize(); |
| 48 } | 50 } |
| 49 | 51 |
| 50 PersistentBase(T* raw) : m_raw(raw) | 52 PersistentBase(T* raw) : m_raw(raw) |
| 51 { | 53 { |
| 54 saveCreationThreadHeap(); |
| 52 initialize(); | 55 initialize(); |
| 53 checkPointer(); | 56 checkPointer(); |
| 54 } | 57 } |
| 55 | 58 |
| 56 PersistentBase(T& raw) : m_raw(&raw) | 59 PersistentBase(T& raw) : m_raw(&raw) |
| 57 { | 60 { |
| 61 saveCreationThreadHeap(); |
| 58 initialize(); | 62 initialize(); |
| 59 checkPointer(); | 63 checkPointer(); |
| 60 } | 64 } |
| 61 | 65 |
| 62 PersistentBase(const PersistentBase& other) : m_raw(other) | 66 PersistentBase(const PersistentBase& other) : m_raw(other) |
| 63 { | 67 { |
| 68 saveCreationThreadHeap(); |
| 64 initialize(); | 69 initialize(); |
| 65 checkPointer(); | 70 checkPointer(); |
| 66 } | 71 } |
| 67 | 72 |
| 68 template<typename U> | 73 template<typename U> |
| 69 PersistentBase(const PersistentBase<U, weaknessConfiguration, crossThreadnes
sConfiguration>& other) : m_raw(other) | 74 PersistentBase(const PersistentBase<U, weaknessConfiguration, crossThreadnes
sConfiguration>& other) : m_raw(other) |
| 70 { | 75 { |
| 76 saveCreationThreadHeap(); |
| 71 initialize(); | 77 initialize(); |
| 72 checkPointer(); | 78 checkPointer(); |
| 73 } | 79 } |
| 74 | 80 |
| 75 template<typename U> | 81 template<typename U> |
| 76 PersistentBase(const Member<U>& other) : m_raw(other) | 82 PersistentBase(const Member<U>& other) : m_raw(other) |
| 77 { | 83 { |
| 84 saveCreationThreadHeap(); |
| 78 initialize(); | 85 initialize(); |
| 79 checkPointer(); | 86 checkPointer(); |
| 80 } | 87 } |
| 81 | 88 |
| 82 PersistentBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(
-1)) | 89 PersistentBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(
-1)) |
| 83 { | 90 { |
| 91 saveCreationThreadHeap(); |
| 84 initialize(); | 92 initialize(); |
| 85 checkPointer(); | 93 checkPointer(); |
| 86 } | 94 } |
| 87 | 95 |
| 88 ~PersistentBase() | 96 ~PersistentBase() |
| 89 { | 97 { |
| 90 uninitialize(); | 98 uninitialize(); |
| 91 m_raw = nullptr; | 99 m_raw = nullptr; |
| 92 } | 100 } |
| 93 | 101 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | 235 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 228 ASSERT(state->checkThread()); | 236 ASSERT(state->checkThread()); |
| 229 // Persistent handle must be created and destructed in the same thread. | 237 // Persistent handle must be created and destructed in the same thread. |
| 230 ASSERT(m_state == state); | 238 ASSERT(m_state == state); |
| 231 state->freePersistentNode(m_persistentNode); | 239 state->freePersistentNode(m_persistentNode); |
| 232 m_persistentNode = nullptr; | 240 m_persistentNode = nullptr; |
| 233 } | 241 } |
| 234 | 242 |
| 235 void checkPointer() | 243 void checkPointer() |
| 236 { | 244 { |
| 237 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) | 245 #if DCHECK_IS_ON() |
| 238 if (!m_raw || isHashTableDeletedValue()) | 246 if (!m_raw || isHashTableDeletedValue()) |
| 239 return; | 247 return; |
| 240 | 248 |
| 249 if (crossThreadnessConfiguration != CrossThreadPersistentConfiguration)
{ |
| 250 ThreadState* current = ThreadState::current(); |
| 251 DCHECK(current); |
| 252 // m_creationThreadState may be null when this is used in a heap |
| 253 // collection which initialized the Member with memset and the |
| 254 // constructor wasn't called. |
| 255 if (m_creationThreadState) { |
| 256 // Member should point to objects that belong in the same Thread
Heap. |
| 257 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &m_creationTh
readState->heap()); |
| 258 // Member should point to objects that belong in the same Thread
Heap. |
| 259 DCHECK_EQ(¤t->heap(), &m_creationThreadState->heap()); |
| 260 } |
| 261 } |
| 262 |
| 263 #if defined(ADDRESS_SANITIZER) |
| 241 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 264 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
| 242 // object. In other words, it checks that the pointer is either of: | 265 // object. In other words, it checks that the pointer is either of: |
| 243 // | 266 // |
| 244 // (a) a pointer to the head of an on-heap object. | 267 // (a) a pointer to the head of an on-heap object. |
| 245 // (b) a pointer to the head of an on-heap mixin object. | 268 // (b) a pointer to the head of an on-heap mixin object. |
| 246 // | 269 // |
| 247 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls | 270 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls |
| 248 // header->checkHeader(). | 271 // header->checkHeader(). |
| 249 ThreadHeap::isHeapObjectAlive(m_raw); | 272 ThreadHeap::isHeapObjectAlive(m_raw); |
| 250 #endif | 273 #endif |
| 274 #endif |
| 275 } |
| 276 |
| 277 void saveCreationThreadHeap() |
| 278 { |
| 279 #if DCHECK_IS_ON() |
| 280 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
| 281 m_creationThreadState = nullptr; |
| 282 } else { |
| 283 m_creationThreadState = ThreadState::current(); |
| 284 // Members should be created in an attached thread. But an empty |
| 285 // value Member may be created on an unattached thread by a heap |
| 286 // collection iterator. |
| 287 DCHECK(m_creationThreadState); |
| 288 } |
| 289 #endif |
| 251 } | 290 } |
| 252 | 291 |
| 253 static void handleWeakPersistent(Visitor* self, void* persistentPointer) | 292 static void handleWeakPersistent(Visitor* self, void* persistentPointer) |
| 254 { | 293 { |
| 255 using Base = PersistentBase<typename std::remove_const<T>::type, weaknes
sConfiguration, crossThreadnessConfiguration>; | 294 using Base = PersistentBase<typename std::remove_const<T>::type, weaknes
sConfiguration, crossThreadnessConfiguration>; |
| 256 Base* persistent = reinterpret_cast<Base*>(persistentPointer); | 295 Base* persistent = reinterpret_cast<Base*>(persistentPointer); |
| 257 T* object = persistent->get(); | 296 T* object = persistent->get(); |
| 258 if (object && !ObjectAliveTrait<T>::isHeapObjectAlive(object)) | 297 if (object && !ObjectAliveTrait<T>::isHeapObjectAlive(object)) |
| 259 persistent->clear(); | 298 persistent->clear(); |
| 260 } | 299 } |
| 261 | 300 |
| 262 // m_raw is accessed most, so put it at the first field. | 301 // m_raw is accessed most, so put it at the first field. |
| 263 T* m_raw; | 302 T* m_raw; |
| 264 PersistentNode* m_persistentNode = nullptr; | 303 PersistentNode* m_persistentNode = nullptr; |
| 265 #if ENABLE(ASSERT) | 304 #if ENABLE(ASSERT) |
| 266 ThreadState* m_state = nullptr; | 305 ThreadState* m_state = nullptr; |
| 267 #endif | 306 #endif |
| 307 #if DCHECK_IS_ON() |
| 308 const ThreadState* m_creationThreadState; |
| 309 #endif |
| 268 }; | 310 }; |
| 269 | 311 |
| 270 // Persistent is a way to create a strong pointer from an off-heap object | 312 // Persistent is a way to create a strong pointer from an off-heap object |
| 271 // to another on-heap object. As long as the Persistent handle is alive | 313 // to another on-heap object. As long as the Persistent handle is alive |
| 272 // the GC will keep the object pointed to alive. The Persistent handle is | 314 // the GC will keep the object pointed to alive. The Persistent handle is |
| 273 // always a GC root from the point of view of the GC. | 315 // always a GC root from the point of view of the GC. |
| 274 // | 316 // |
| 275 // We have to construct and destruct Persistent in the same thread. | 317 // We have to construct and destruct Persistent in the same thread. |
| 276 template<typename T> | 318 template<typename T> |
| 277 class Persistent : public PersistentBase<T, NonWeakPersistentConfiguration, Sing
leThreadPersistentConfiguration> { | 319 class Persistent : public PersistentBase<T, NonWeakPersistentConfiguration, Sing
leThreadPersistentConfiguration> { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 | 765 |
| 724 template <typename T> | 766 template <typename T> |
| 725 struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {}; | 767 struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {}; |
| 726 | 768 |
| 727 template <typename T> | 769 template <typename T> |
| 728 struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {}; | 770 struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {}; |
| 729 | 771 |
| 730 } | 772 } |
| 731 | 773 |
| 732 #endif // Persistent_h | 774 #endif // Persistent_h |
| OLD | NEW |