Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: third_party/WebKit/Source/platform/heap/Persistent.h

Issue 2007283002: Allow CrossThreadPersistent in collections (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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);
198 #if ENABLE(ASSERT) 206 #if ENABLE(ASSERT)
199 m_state = state; 207 m_state = state;
200 #endif 208 #endif
201 } 209 }
202 210
203 void uninitialize() 211 void uninitialize()
204 { 212 {
213 if (!m_persistentNode)
sof 2016/05/25 13:11:42 Moving this up here (again) will lead to a race.
214 return;
215
205 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { 216 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
206 if (acquireLoad(reinterpret_cast<void* volatile*>(&m_persistentNode) )) 217 if (acquireLoad(reinterpret_cast<void* volatile*>(&m_persistentNode) ))
207 ProcessHeap::crossThreadPersistentRegion().freePersistentNode(m_ persistentNode); 218 ProcessHeap::crossThreadPersistentRegion().freePersistentNode(m_ persistentNode);
208 return; 219 return;
209 } 220 }
210 221
211 if (!m_persistentNode)
212 return;
213 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); 222 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
214 ASSERT(state->checkThread()); 223 ASSERT(state->checkThread());
215 // Persistent handle must be created and destructed in the same thread. 224 // Persistent handle must be created and destructed in the same thread.
216 ASSERT(m_state == state); 225 ASSERT(m_state == state);
217 state->freePersistentNode(m_persistentNode); 226 state->freePersistentNode(m_persistentNode);
218 m_persistentNode = nullptr; 227 m_persistentNode = nullptr;
219 } 228 }
220 229
221 void checkPointer() 230 void checkPointer()
222 { 231 {
223 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) 232 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER)
224 if (!m_raw) 233 if (!m_raw || isHashTableDeletedValue())
225 return; 234 return;
226 235
227 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 236 // ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
228 // object. In other words, it checks that the pointer is either of: 237 // object. In other words, it checks that the pointer is either of:
229 // 238 //
230 // (a) a pointer to the head of an on-heap object. 239 // (a) a pointer to the head of an on-heap object.
231 // (b) a pointer to the head of an on-heap mixin object. 240 // (b) a pointer to the head of an on-heap mixin object.
232 // 241 //
233 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls 242 // Otherwise, ThreadHeap::isHeapObjectAlive will crash when it calls
234 // header->checkHeader(). 243 // header->checkHeader().
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 public: 374 public:
366 CrossThreadPersistent() : Parent() { } 375 CrossThreadPersistent() : Parent() { }
367 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { } 376 CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) { }
368 CrossThreadPersistent(T* raw) : Parent(raw) { } 377 CrossThreadPersistent(T* raw) : Parent(raw) { }
369 CrossThreadPersistent(T& raw) : Parent(raw) { } 378 CrossThreadPersistent(T& raw) : Parent(raw) { }
370 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) { } 379 CrossThreadPersistent(const CrossThreadPersistent& other) : Parent(other) { }
371 template<typename U> 380 template<typename U>
372 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other) { } 381 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other) { }
373 template<typename U> 382 template<typename U>
374 CrossThreadPersistent(const Member<U>& other) : Parent(other) { } 383 CrossThreadPersistent(const Member<U>& other) : Parent(other) { }
384 CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) { }
375 385
376 T* atomicGet() { return Parent::atomicGet(); } 386 T* atomicGet() { return Parent::atomicGet(); }
377 387
378 template<typename U> 388 template<typename U>
379 CrossThreadPersistent& operator=(U* other) 389 CrossThreadPersistent& operator=(U* other)
380 { 390 {
381 Parent::operator=(other); 391 Parent::operator=(other);
382 return *this; 392 return *this;
383 } 393 }
384 394
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 685
676 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(); }
677 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(); }
678 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(); }
679 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(); }
680 690
681 } // namespace blink 691 } // namespace blink
682 692
683 namespace WTF { 693 namespace WTF {
684 694
695 template <typename T>
696 struct CrossThreadPersistentHash : MemberHash<T> {
697 STATIC_ONLY(CrossThreadPersistentHash);
698 };
699
700 template <typename T>
701 struct DefaultHash<blink::CrossThreadPersistent<T>> {
702 STATIC_ONLY(DefaultHash);
703 using Hash = CrossThreadPersistentHash<T>;
704 };
705
685 template<typename T> 706 template<typename T>
686 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { 707 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> {
687 STATIC_ONLY(ParamStorageTraits); 708 STATIC_ONLY(ParamStorageTraits);
688 static_assert(sizeof(T), "T must be fully defined"); 709 static_assert(sizeof(T), "T must be fully defined");
689 using StorageType = blink::WeakPersistent<T>; 710 using StorageType = blink::WeakPersistent<T>;
690 711
691 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) { return value.value(); } 712 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) { return value.value(); }
692 713
693 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent 714 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent
694 // into it. 715 // into it.
(...skipping 15 matching lines...) Expand all
710 // into it. 731 // into it.
711 // 732 //
712 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty pe like 733 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty pe like
713 // CrossThreadWeakPersistent<>. 734 // CrossThreadWeakPersistent<>.
714 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR eference<T>::create(value.get())); } 735 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR eference<T>::create(value.get())); }
715 }; 736 };
716 737
717 } // namespace WTF 738 } // namespace WTF
718 739
719 #endif // Persistent_h 740 #endif // Persistent_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698