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/Member.h" | 8 #include "platform/heap/Member.h" |
| 9 #include "platform/heap/PersistentNode.h" | 9 #include "platform/heap/PersistentNode.h" |
| 10 #include "wtf/Allocator.h" | 10 #include "wtf/Allocator.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 checkPointer(); | 70 checkPointer(); |
| 71 } | 71 } |
| 72 | 72 |
| 73 template<typename U> | 73 template<typename U> |
| 74 PersistentBase(const Member<U>& other) : m_raw(other) | 74 PersistentBase(const Member<U>& other) : m_raw(other) |
| 75 { | 75 { |
| 76 initialize(); | 76 initialize(); |
| 77 checkPointer(); | 77 checkPointer(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 PersistentBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>( -1)) | |
| 81 { | |
| 82 initialize(); | |
| 83 checkPointer(); | |
| 84 } | |
| 85 | |
| 80 ~PersistentBase() | 86 ~PersistentBase() |
| 81 { | 87 { |
| 82 uninitialize(); | 88 uninitialize(); |
| 83 m_raw = nullptr; | 89 m_raw = nullptr; |
| 84 } | 90 } |
| 85 | 91 |
| 92 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } | |
| 93 | |
| 86 template<typename VisitorDispatcher> | 94 template<typename VisitorDispatcher> |
| 87 void trace(VisitorDispatcher visitor) | 95 void trace(VisitorDispatcher visitor) |
| 88 { | 96 { |
| 89 static_assert(sizeof(T), "T must be fully defined"); | 97 static_assert(sizeof(T), "T must be fully defined"); |
| 90 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); | 98 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); |
| 91 if (weaknessConfiguration == WeakPersistentConfiguration) { | 99 if (weaknessConfiguration == WeakPersistentConfiguration) { |
| 92 visitor->registerWeakCell(&m_raw); | 100 visitor->registerWeakCell(&m_raw); |
| 93 } else { | 101 } else { |
| 94 visitor->mark(m_raw); | 102 visitor->mark(m_raw); |
| 95 } | 103 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 initialize(); | 185 initialize(); |
| 178 return; | 186 return; |
| 179 } | 187 } |
| 180 uninitialize(); | 188 uninitialize(); |
| 181 } | 189 } |
| 182 | 190 |
| 183 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 191 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
| 184 void initialize() | 192 void initialize() |
| 185 { | 193 { |
| 186 ASSERT(!m_persistentNode); | 194 ASSERT(!m_persistentNode); |
| 187 if (!m_raw) | 195 if (!m_raw || isHashTableDeletedValue()) |
| 188 return; | 196 return; |
| 189 | 197 |
| 190 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; | 198 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; |
| 191 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { | 199 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
| 192 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_ persistentNode, this, traceCallback); | 200 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_ persistentNode, this, traceCallback); |
| 193 return; | 201 return; |
| 194 } | 202 } |
| 195 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); | 203 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); |
| 196 ASSERT(state->checkThread()); | 204 ASSERT(state->checkThread()); |
| 197 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( this, traceCallback); | 205 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( this, traceCallback); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 214 ASSERT(state->checkThread()); | 222 ASSERT(state->checkThread()); |
| 215 // Persistent handle must be created and destructed in the same thread. | 223 // Persistent handle must be created and destructed in the same thread. |
| 216 ASSERT(m_state == state); | 224 ASSERT(m_state == state); |
| 217 state->freePersistentNode(m_persistentNode); | 225 state->freePersistentNode(m_persistentNode); |
| 218 m_persistentNode = nullptr; | 226 m_persistentNode = nullptr; |
| 219 } | 227 } |
| 220 | 228 |
| 221 void checkPointer() | 229 void checkPointer() |
| 222 { | 230 { |
| 223 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) | 231 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) |
| 224 if (!m_raw) | 232 if (!m_raw || isHashTableDeletedValue()) |
| 225 return; | 233 return; |
| 226 | 234 |
| 227 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 235 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
| 228 // object. In other words, it checks that the pointer is either of: | 236 // object. In other words, it checks that the pointer is either of: |
| 229 // | 237 // |
| 230 // (a) a pointer to the head of an on-heap object. | 238 // (a) a pointer to the head of an on-heap object. |
| 231 // (b) a pointer to the head of an on-heap mixin object. | 239 // (b) a pointer to the head of an on-heap mixin object. |
| 232 // | 240 // |
| 233 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls | 241 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls |
| 234 // header->checkHeader(). | 242 // header->checkHeader(). |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 public: | 373 public: |
| 366 CrossThreadPersistent() : Parent() { } | 374 CrossThreadPersistent() : Parent() { } |
| 367 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } | 375 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } |
| 368 CrossThreadPersistent(T* raw) : Parent(raw) { } | 376 CrossThreadPersistent(T* raw) : Parent(raw) { } |
| 369 CrossThreadPersistent(T& raw) : Parent(raw) { } | 377 CrossThreadPersistent(T& raw) : Parent(raw) { } |
| 370 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) { } | 378 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) { } |
| 371 template<typename U> | 379 template<typename U> |
| 372 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other) { } | 380 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other) { } |
| 373 template<typename U> | 381 template<typename U> |
| 374 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } | 382 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } |
| 383 CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) { } | |
|
sof
2016/05/26 09:41:44
Isn't this ctor needed for Persistent<> also?
| |
| 375 | 384 |
| 376 T* atomicGet() { return Parent::atomicGet(); } | 385 T* atomicGet() { return Parent::atomicGet(); } |
| 377 | 386 |
| 378 template<typename U> | 387 template<typename U> |
| 379 CrossThreadPersistent& operator=(U* other) | 388 CrossThreadPersistent& operator=(U* other) |
| 380 { | 389 { |
| 381 Parent::operator=(other); | 390 Parent::operator=(other); |
| 382 return *this; | 391 return *this; |
| 383 } | 392 } |
| 384 | 393 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 | 684 |
| 676 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons t Persistent<U>& b) { return a.get() == b.get(); } | 685 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons t Persistent<U>& b) { return a.get() == b.get(); } |
| 677 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons t Persistent<U>& b) { return a.get() != b.get(); } | 686 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons t Persistent<U>& b) { return a.get() != b.get(); } |
| 678 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); } | 687 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); } |
| 679 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } | 688 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } |
| 680 | 689 |
| 681 } // namespace blink | 690 } // namespace blink |
| 682 | 691 |
| 683 namespace WTF { | 692 namespace WTF { |
| 684 | 693 |
| 694 template <typename T> | |
| 695 struct CrossThreadPersistentHash : MemberHash<T> { | |
|
sof
2016/05/26 09:41:44
Add for Persistent<> also.
| |
| 696 STATIC_ONLY(CrossThreadPersistentHash); | |
| 697 }; | |
| 698 | |
| 699 template <typename T> | |
| 700 struct DefaultHash<blink::CrossThreadPersistent<T>> { | |
| 701 STATIC_ONLY(DefaultHash); | |
| 702 using Hash = CrossThreadPersistentHash<T>; | |
| 703 }; | |
| 704 | |
| 685 template<typename T> | 705 template<typename T> |
| 686 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { | 706 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { |
| 687 STATIC_ONLY(ParamStorageTraits); | 707 STATIC_ONLY(ParamStorageTraits); |
| 688 static_assert(sizeof(T), "T must be fully defined"); | 708 static_assert(sizeof(T), "T must be fully defined"); |
| 689 using StorageType = blink::WeakPersistent<T>; | 709 using StorageType = blink::WeakPersistent<T>; |
| 690 | 710 |
| 691 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) { return value.value(); } | 711 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) { return value.value(); } |
| 692 | 712 |
| 693 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 713 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
| 694 // into it. | 714 // into it. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 710 // into it. | 730 // into it. |
| 711 // | 731 // |
| 712 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty pe like | 732 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty pe like |
| 713 // CrossThreadWeakPersistent<>. | 733 // CrossThreadWeakPersistent<>. |
| 714 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR eference<T>::create(value.get())); } | 734 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR eference<T>::create(value.get())); } |
| 715 }; | 735 }; |
| 716 | 736 |
| 717 } // namespace WTF | 737 } // namespace WTF |
| 718 | 738 |
| 719 #endif // Persistent_h | 739 #endif // Persistent_h |
| OLD | NEW |