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

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

Issue 2602263002: Lend LSan a hand and clear out singleton static persistents first. (Closed)
Patch Set: experiment: disable LSan-GCing during shutdown.. Created 3 years, 11 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/heap/PersistentNode.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 15 matching lines...) Expand all
26 enum WeaknessPersistentConfiguration { 26 enum WeaknessPersistentConfiguration {
27 NonWeakPersistentConfiguration, 27 NonWeakPersistentConfiguration,
28 WeakPersistentConfiguration 28 WeakPersistentConfiguration
29 }; 29 };
30 30
31 enum CrossThreadnessPersistentConfiguration { 31 enum CrossThreadnessPersistentConfiguration {
32 SingleThreadPersistentConfiguration, 32 SingleThreadPersistentConfiguration,
33 CrossThreadPersistentConfiguration 33 CrossThreadPersistentConfiguration
34 }; 34 };
35 35
36 // Auxillary template, probing if |void T::clear()| exists and is accessible.
37 // Used to conditionally clear the contents of a static persistent.
38 template <typename T>
39 class CanClearPersistentReference {
40 typedef char YesType;
41 typedef struct NoType { char padding[8]; } NoType;
42
43 // Check if class T has public method "void clear()".
44 template <typename V>
45 static YesType checkHasClearMethod(
46 V* p,
47 typename std::enable_if<
48 std::is_same<decltype(p->clear()), void>::value>::type* = nullptr);
49 template <typename V>
50 static NoType checkHasClearMethod(...);
51
52 public:
53 static const bool value = sizeof(YesType) + sizeof(T) ==
54 sizeof(checkHasClearMethod<T>(nullptr)) + sizeof(T);
55 };
56
57 template <typename T, bool = CanClearPersistentReference<T>::value>
58 class ClearStaticPersistentReference {
59 public:
60 static void clear(T*) {}
61 };
62
63 template <typename T>
64 class ClearStaticPersistentReference<T, true> {
65 public:
66 static void clear(T* ptr) { ptr->clear(); }
67 };
68
36 template <typename T, 69 template <typename T,
37 WeaknessPersistentConfiguration weaknessConfiguration, 70 WeaknessPersistentConfiguration weaknessConfiguration,
38 CrossThreadnessPersistentConfiguration crossThreadnessConfiguration> 71 CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
39 class PersistentBase { 72 class PersistentBase {
40 USING_FAST_MALLOC(PersistentBase); 73 USING_FAST_MALLOC(PersistentBase);
41 IS_PERSISTENT_REFERENCE_TYPE(); 74 IS_PERSISTENT_REFERENCE_TYPE();
42 75
43 public: 76 public:
44 PersistentBase() : m_raw(nullptr) { 77 PersistentBase() : m_raw(nullptr) {
45 saveCreationThreadHeap(); 78 saveCreationThreadHeap();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // belonging to the current thread and a persistent that must 183 // belonging to the current thread and a persistent that must
151 // be cleared when the ThreadState itself is cleared out and 184 // be cleared when the ThreadState itself is cleared out and
152 // destructed. 185 // destructed.
153 // 186 //
154 // Static singletons arrange for this to happen, either to ensure 187 // Static singletons arrange for this to happen, either to ensure
155 // clean LSan leak reports or to register a thread-local persistent 188 // clean LSan leak reports or to register a thread-local persistent
156 // needing to be cleared out before the thread is terminated. 189 // needing to be cleared out before the thread is terminated.
157 PersistentBase* registerAsStaticReference() { 190 PersistentBase* registerAsStaticReference() {
158 if (m_persistentNode) { 191 if (m_persistentNode) {
159 ASSERT(ThreadState::current()); 192 ASSERT(ThreadState::current());
160 ThreadState::current()->registerStaticPersistentNode(m_persistentNode, 193 ThreadState::current()->registerStaticPersistentNode(
161 nullptr); 194 m_persistentNode, &PersistentBase::clearPersistentNode);
162 LEAK_SANITIZER_IGNORE_OBJECT(this); 195 LEAK_SANITIZER_IGNORE_OBJECT(this);
163 } 196 }
164 return this; 197 return this;
165 } 198 }
166 199
167 protected: 200 protected:
168 NO_SANITIZE_ADDRESS 201 NO_SANITIZE_ADDRESS
169 T* atomicGet() { 202 T* atomicGet() {
170 return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>( 203 return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>(
171 const_cast<typename std::remove_const<T>::type**>(&m_raw)))); 204 const_cast<typename std::remove_const<T>::type**>(&m_raw))));
(...skipping 12 matching lines...) Expand all
184 } 217 }
185 checkPointer(); 218 checkPointer();
186 if (m_raw) { 219 if (m_raw) {
187 if (!m_persistentNode) 220 if (!m_persistentNode)
188 initialize(); 221 initialize();
189 return; 222 return;
190 } 223 }
191 uninitialize(); 224 uninitialize();
192 } 225 }
193 226
227 // Used when the registered PersistentNode of this object is
228 // released during ThreadState shutdown, clearing the association.
229 static void clearPersistentNode(void* self,
230 ThreadState::ReleasePersistentMode mode) {
231 PersistentBase* persistent = reinterpret_cast<PersistentBase*>(self);
232 ClearStaticPersistentReference<T>::clear(persistent->get());
233 if (mode == ThreadState::ReleasePersistent)
234 persistent->uninitialize();
235 }
236
194 template <typename VisitorDispatcher> 237 template <typename VisitorDispatcher>
195 void tracePersistent(VisitorDispatcher visitor) { 238 void tracePersistent(VisitorDispatcher visitor) {
196 static_assert(sizeof(T), "T must be fully defined"); 239 static_assert(sizeof(T), "T must be fully defined");
197 static_assert(IsGarbageCollectedType<T>::value, 240 static_assert(IsGarbageCollectedType<T>::value,
198 "T needs to be a garbage collected object"); 241 "T needs to be a garbage collected object");
199 if (weaknessConfiguration == WeakPersistentConfiguration) { 242 if (weaknessConfiguration == WeakPersistentConfiguration) {
200 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) 243 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
201 visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this), 244 visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this),
202 handleWeakPersistent); 245 handleWeakPersistent);
203 else 246 else
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 636
594 private: 637 private:
595 template <typename VisitorDispatcher> 638 template <typename VisitorDispatcher>
596 void tracePersistent(VisitorDispatcher visitor) { 639 void tracePersistent(VisitorDispatcher visitor) {
597 static_assert(sizeof(Collection), "Collection must be fully defined"); 640 static_assert(sizeof(Collection), "Collection must be fully defined");
598 visitor->trace(*static_cast<Collection*>(this)); 641 visitor->trace(*static_cast<Collection*>(this));
599 } 642 }
600 643
601 // Used when the registered PersistentNode of this object is 644 // Used when the registered PersistentNode of this object is
602 // released during ThreadState shutdown, clearing the association. 645 // released during ThreadState shutdown, clearing the association.
603 static void clearPersistentNode(void* self) { 646 static void clearPersistentNode(void* self,
647 ThreadState::ReleasePersistentMode mode) {
604 PersistentHeapCollectionBase<Collection>* collection = 648 PersistentHeapCollectionBase<Collection>* collection =
605 (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self)); 649 reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self);
606 collection->uninitialize();
607 collection->clear(); 650 collection->clear();
651 if (mode == ThreadState::ReleasePersistent)
652 collection->uninitialize();
608 } 653 }
609 654
610 NO_SANITIZE_ADDRESS 655 NO_SANITIZE_ADDRESS
611 void initialize() { 656 void initialize() {
612 // FIXME: Derive affinity based on the collection. 657 // FIXME: Derive affinity based on the collection.
613 ThreadState* state = ThreadState::current(); 658 ThreadState* state = ThreadState::current();
614 ASSERT(state->checkThread()); 659 ASSERT(state->checkThread());
615 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( 660 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
616 this, 661 this,
617 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, 662 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>,
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 static blink::CrossThreadPersistent<T> Unwrap( 865 static blink::CrossThreadPersistent<T> Unwrap(
821 const blink::CrossThreadWeakPersistent<T>& wrapped) { 866 const blink::CrossThreadWeakPersistent<T>& wrapped) {
822 blink::CrossThreadPersistentRegion::LockScope persistentLock( 867 blink::CrossThreadPersistentRegion::LockScope persistentLock(
823 blink::ProcessHeap::crossThreadPersistentRegion()); 868 blink::ProcessHeap::crossThreadPersistentRegion());
824 return blink::CrossThreadPersistent<T>(wrapped.get()); 869 return blink::CrossThreadPersistent<T>(wrapped.get());
825 } 870 }
826 }; 871 };
827 } 872 }
828 873
829 #endif // Persistent_h 874 #endif // Persistent_h
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/heap/PersistentNode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698