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 | |
86 ~PersistentBase() | 80 ~PersistentBase() |
87 { | 81 { |
88 uninitialize(); | 82 uninitialize(); |
89 m_raw = nullptr; | 83 m_raw = nullptr; |
90 } | 84 } |
91 | 85 |
92 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(
-1); } | |
93 | |
94 template<typename VisitorDispatcher> | 86 template<typename VisitorDispatcher> |
95 void trace(VisitorDispatcher visitor) | 87 void trace(VisitorDispatcher visitor) |
96 { | 88 { |
97 static_assert(sizeof(T), "T must be fully defined"); | 89 static_assert(sizeof(T), "T must be fully defined"); |
98 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); | 90 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); |
99 if (weaknessConfiguration == WeakPersistentConfiguration) { | 91 if (weaknessConfiguration == WeakPersistentConfiguration) { |
100 visitor->registerWeakCell(&m_raw); | 92 visitor->registerWeakCell(&m_raw); |
101 } else { | 93 } else { |
102 visitor->mark(m_raw); | 94 visitor->mark(m_raw); |
103 } | 95 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 initialize(); | 177 initialize(); |
186 return; | 178 return; |
187 } | 179 } |
188 uninitialize(); | 180 uninitialize(); |
189 } | 181 } |
190 | 182 |
191 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 183 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
192 void initialize() | 184 void initialize() |
193 { | 185 { |
194 ASSERT(!m_persistentNode); | 186 ASSERT(!m_persistentNode); |
195 if (!m_raw || isHashTableDeletedValue()) | 187 if (!m_raw) |
196 return; | 188 return; |
197 | 189 |
198 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; | 190 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; |
199 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ | 191 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
200 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_
persistentNode, this, traceCallback); | 192 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_
persistentNode, this, traceCallback); |
201 return; | 193 return; |
202 } | 194 } |
203 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | 195 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
204 ASSERT(state->checkThread()); | 196 ASSERT(state->checkThread()); |
205 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, traceCallback); | 197 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, traceCallback); |
(...skipping 16 matching lines...) Expand all Loading... |
222 ASSERT(state->checkThread()); | 214 ASSERT(state->checkThread()); |
223 // Persistent handle must be created and destructed in the same thread. | 215 // Persistent handle must be created and destructed in the same thread. |
224 ASSERT(m_state == state); | 216 ASSERT(m_state == state); |
225 state->freePersistentNode(m_persistentNode); | 217 state->freePersistentNode(m_persistentNode); |
226 m_persistentNode = nullptr; | 218 m_persistentNode = nullptr; |
227 } | 219 } |
228 | 220 |
229 void checkPointer() | 221 void checkPointer() |
230 { | 222 { |
231 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) | 223 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) |
232 if (!m_raw || isHashTableDeletedValue()) | 224 if (!m_raw) |
233 return; | 225 return; |
234 | 226 |
235 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 227 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
236 // object. In other words, it checks that the pointer is either of: | 228 // object. In other words, it checks that the pointer is either of: |
237 // | 229 // |
238 // (a) a pointer to the head of an on-heap object. | 230 // (a) a pointer to the head of an on-heap object. |
239 // (b) a pointer to the head of an on-heap mixin object. | 231 // (b) a pointer to the head of an on-heap mixin object. |
240 // | 232 // |
241 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls | 233 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls |
242 // header->checkHeader(). | 234 // header->checkHeader(). |
(...skipping 21 matching lines...) Expand all Loading... |
264 public: | 256 public: |
265 Persistent() : Parent() { } | 257 Persistent() : Parent() { } |
266 Persistent(std::nullptr_t) : Parent(nullptr) { } | 258 Persistent(std::nullptr_t) : Parent(nullptr) { } |
267 Persistent(T* raw) : Parent(raw) { } | 259 Persistent(T* raw) : Parent(raw) { } |
268 Persistent(T& raw) : Parent(raw) { } | 260 Persistent(T& raw) : Parent(raw) { } |
269 Persistent(const Persistent& other) : Parent(other) { } | 261 Persistent(const Persistent& other) : Parent(other) { } |
270 template<typename U> | 262 template<typename U> |
271 Persistent(const Persistent<U>& other) : Parent(other) { } | 263 Persistent(const Persistent<U>& other) : Parent(other) { } |
272 template<typename U> | 264 template<typename U> |
273 Persistent(const Member<U>& other) : Parent(other) { } | 265 Persistent(const Member<U>& other) : Parent(other) { } |
274 Persistent(WTF::HashTableDeletedValueType x) : Parent(x) { } | |
275 | 266 |
276 template<typename U> | 267 template<typename U> |
277 Persistent& operator=(U* other) | 268 Persistent& operator=(U* other) |
278 { | 269 { |
279 Parent::operator=(other); | 270 Parent::operator=(other); |
280 return *this; | 271 return *this; |
281 } | 272 } |
282 | 273 |
283 Persistent& operator=(std::nullptr_t) | 274 Persistent& operator=(std::nullptr_t) |
284 { | 275 { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 public: | 365 public: |
375 CrossThreadPersistent() : Parent() { } | 366 CrossThreadPersistent() : Parent() { } |
376 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } | 367 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } |
377 CrossThreadPersistent(T* raw) : Parent(raw) { } | 368 CrossThreadPersistent(T* raw) : Parent(raw) { } |
378 CrossThreadPersistent(T& raw) : Parent(raw) { } | 369 CrossThreadPersistent(T& raw) : Parent(raw) { } |
379 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) {
} | 370 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) {
} |
380 template<typename U> | 371 template<typename U> |
381 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other)
{ } | 372 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other)
{ } |
382 template<typename U> | 373 template<typename U> |
383 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } | 374 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } |
384 CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) { } | |
385 | 375 |
386 T* atomicGet() { return Parent::atomicGet(); } | 376 T* atomicGet() { return Parent::atomicGet(); } |
387 | 377 |
388 template<typename U> | 378 template<typename U> |
389 CrossThreadPersistent& operator=(U* other) | 379 CrossThreadPersistent& operator=(U* other) |
390 { | 380 { |
391 Parent::operator=(other); | 381 Parent::operator=(other); |
392 return *this; | 382 return *this; |
393 } | 383 } |
394 | 384 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 | 675 |
686 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } | 676 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } |
687 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(); } |
688 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<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(); } |
689 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(); } |
690 | 680 |
691 } // namespace blink | 681 } // namespace blink |
692 | 682 |
693 namespace WTF { | 683 namespace WTF { |
694 | 684 |
695 template <typename T> | |
696 struct PersistentHash : MemberHash<T> { | |
697 STATIC_ONLY(PersistentHash); | |
698 }; | |
699 | |
700 template <typename T> | |
701 struct CrossThreadPersistentHash : MemberHash<T> { | |
702 STATIC_ONLY(CrossThreadPersistentHash); | |
703 }; | |
704 | |
705 template <typename T> | |
706 struct DefaultHash<blink::Persistent<T>> { | |
707 STATIC_ONLY(DefaultHash); | |
708 using Hash = PersistentHash<T>; | |
709 }; | |
710 | |
711 template <typename T> | |
712 struct DefaultHash<blink::CrossThreadPersistent<T>> { | |
713 STATIC_ONLY(DefaultHash); | |
714 using Hash = CrossThreadPersistentHash<T>; | |
715 }; | |
716 | |
717 template<typename T> | 685 template<typename T> |
718 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { | 686 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { |
719 STATIC_ONLY(ParamStorageTraits); | 687 STATIC_ONLY(ParamStorageTraits); |
720 static_assert(sizeof(T), "T must be fully defined"); | 688 static_assert(sizeof(T), "T must be fully defined"); |
721 using StorageType = blink::WeakPersistent<T>; | 689 using StorageType = blink::WeakPersistent<T>; |
722 | 690 |
723 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } | 691 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } |
724 | 692 |
725 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 693 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
726 // into it. | 694 // into it. |
(...skipping 15 matching lines...) Expand all Loading... |
742 // into it. | 710 // into it. |
743 // | 711 // |
744 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like | 712 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like |
745 // CrossThreadWeakPersistent<>. | 713 // CrossThreadWeakPersistent<>. |
746 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } | 714 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } |
747 }; | 715 }; |
748 | 716 |
749 } // namespace WTF | 717 } // namespace WTF |
750 | 718 |
751 #endif // Persistent_h | 719 #endif // Persistent_h |
OLD | NEW |