Chromium Code Reviews| 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 & & m_creationThreadHeap) { | |
|
haraken
2016/08/16 13:35:48
I'm wondering if it's valid that m_creationThread
| |
| 250 ThreadState* current = ThreadState::current(); | |
| 251 if (current && current->perThreadHeapEnabled()) { | |
|
haraken
2016/08/16 13:35:48
What we really want to check is m_creationThreadHe
keishi
2016/08/17 09:48:57
Mistake. Done.
| |
| 252 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), m_creationThr eadHeap); | |
| 253 DCHECK_EQ(¤t->heap(), m_creationThreadHeap); | |
| 254 } | |
| 255 } | |
| 256 | |
| 257 #if defined(ADDRESS_SANITIZER) | |
| 241 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 258 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
| 242 // object. In other words, it checks that the pointer is either of: | 259 // object. In other words, it checks that the pointer is either of: |
| 243 // | 260 // |
| 244 // (a) a pointer to the head of an on-heap object. | 261 // (a) a pointer to the head of an on-heap object. |
| 245 // (b) a pointer to the head of an on-heap mixin object. | 262 // (b) a pointer to the head of an on-heap mixin object. |
| 246 // | 263 // |
| 247 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls | 264 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls |
| 248 // header->checkHeader(). | 265 // header->checkHeader(). |
| 249 ThreadHeap::isHeapObjectAlive(m_raw); | 266 ThreadHeap::isHeapObjectAlive(m_raw); |
| 250 #endif | 267 #endif |
| 268 #endif | |
| 269 } | |
| 270 | |
| 271 void saveCreationThreadHeap() | |
| 272 { | |
| 273 #if DCHECK_IS_ON() | |
| 274 if (ThreadState::current()) | |
|
haraken
2016/08/16 13:35:48
Is it possible that ThreadState::current() is null
keishi
2016/08/17 09:48:57
We were creating Persistent(null) before ThreadSta
| |
| 275 m_creationThreadHeap = &ThreadState::current()->heap(); | |
| 276 else | |
| 277 m_creationThreadHeap = nullptr; | |
| 278 #endif | |
| 251 } | 279 } |
| 252 | 280 |
| 253 static void handleWeakPersistent(Visitor* self, void* persistentPointer) | 281 static void handleWeakPersistent(Visitor* self, void* persistentPointer) |
| 254 { | 282 { |
| 255 using Base = PersistentBase<typename std::remove_const<T>::type, weaknes sConfiguration, crossThreadnessConfiguration>; | 283 using Base = PersistentBase<typename std::remove_const<T>::type, weaknes sConfiguration, crossThreadnessConfiguration>; |
| 256 Base* persistent = reinterpret_cast<Base*>(persistentPointer); | 284 Base* persistent = reinterpret_cast<Base*>(persistentPointer); |
| 257 T* object = persistent->get(); | 285 T* object = persistent->get(); |
| 258 if (object && !ObjectAliveTrait<T>::isHeapObjectAlive(object)) | 286 if (object && !ObjectAliveTrait<T>::isHeapObjectAlive(object)) |
| 259 persistent->clear(); | 287 persistent->clear(); |
| 260 } | 288 } |
| 261 | 289 |
| 262 // m_raw is accessed most, so put it at the first field. | 290 // m_raw is accessed most, so put it at the first field. |
| 263 T* m_raw; | 291 T* m_raw; |
| 264 PersistentNode* m_persistentNode = nullptr; | 292 PersistentNode* m_persistentNode = nullptr; |
| 265 #if ENABLE(ASSERT) | 293 #if ENABLE(ASSERT) |
| 266 ThreadState* m_state = nullptr; | 294 ThreadState* m_state = nullptr; |
| 267 #endif | 295 #endif |
| 296 #if DCHECK_IS_ON() | |
| 297 const ThreadHeap* m_creationThreadHeap; | |
| 298 #endif | |
| 268 }; | 299 }; |
| 269 | 300 |
| 270 // Persistent is a way to create a strong pointer from an off-heap object | 301 // 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 | 302 // 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 | 303 // 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. | 304 // always a GC root from the point of view of the GC. |
| 274 // | 305 // |
| 275 // We have to construct and destruct Persistent in the same thread. | 306 // We have to construct and destruct Persistent in the same thread. |
| 276 template<typename T> | 307 template<typename T> |
| 277 class Persistent : public PersistentBase<T, NonWeakPersistentConfiguration, Sing leThreadPersistentConfiguration> { | 308 class Persistent : public PersistentBase<T, NonWeakPersistentConfiguration, Sing leThreadPersistentConfiguration> { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 | 754 |
| 724 template <typename T> | 755 template <typename T> |
| 725 struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {}; | 756 struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {}; |
| 726 | 757 |
| 727 template <typename T> | 758 template <typename T> |
| 728 struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {}; | 759 struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {}; |
| 729 | 760 |
| 730 } | 761 } |
| 731 | 762 |
| 732 #endif // Persistent_h | 763 #endif // Persistent_h |
| OLD | NEW |