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

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: 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
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 =
54 sizeof(YesType) + sizeof(T) ==
55 sizeof(checkHasClearMethod<T>(nullptr)) + sizeof(T);
56 };
57
58 template <typename T, bool = CanClearPersistentReference<T>::value>
59 class ClearStaticPersistentReference {
60 public:
61 static void clear(T*) {}
62 };
63
64 template <typename T>
65 class ClearStaticPersistentReference<T, true> {
66 public:
67 static void clear(T* ptr) { ptr->clear(); }
68 };
69
36 template <typename T, 70 template <typename T,
37 WeaknessPersistentConfiguration weaknessConfiguration, 71 WeaknessPersistentConfiguration weaknessConfiguration,
38 CrossThreadnessPersistentConfiguration crossThreadnessConfiguration> 72 CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
39 class PersistentBase { 73 class PersistentBase {
40 USING_FAST_MALLOC(PersistentBase); 74 USING_FAST_MALLOC(PersistentBase);
41 IS_PERSISTENT_REFERENCE_TYPE(); 75 IS_PERSISTENT_REFERENCE_TYPE();
42 76
43 public: 77 public:
44 PersistentBase() : m_raw(nullptr) { 78 PersistentBase() : m_raw(nullptr) {
45 saveCreationThreadHeap(); 79 saveCreationThreadHeap();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // belonging to the current thread and a persistent that must 184 // belonging to the current thread and a persistent that must
151 // be cleared when the ThreadState itself is cleared out and 185 // be cleared when the ThreadState itself is cleared out and
152 // destructed. 186 // destructed.
153 // 187 //
154 // Static singletons arrange for this to happen, either to ensure 188 // Static singletons arrange for this to happen, either to ensure
155 // clean LSan leak reports or to register a thread-local persistent 189 // clean LSan leak reports or to register a thread-local persistent
156 // needing to be cleared out before the thread is terminated. 190 // needing to be cleared out before the thread is terminated.
157 PersistentBase* registerAsStaticReference() { 191 PersistentBase* registerAsStaticReference() {
158 if (m_persistentNode) { 192 if (m_persistentNode) {
159 ASSERT(ThreadState::current()); 193 ASSERT(ThreadState::current());
160 ThreadState::current()->registerStaticPersistentNode(m_persistentNode, 194 ThreadState::current()->registerStaticPersistentNode(
161 nullptr); 195 m_persistentNode, &PersistentBase::clearPersistentNode);
162 LEAK_SANITIZER_IGNORE_OBJECT(this); 196 LEAK_SANITIZER_IGNORE_OBJECT(this);
163 } 197 }
164 return this; 198 return this;
165 } 199 }
166 200
167 protected: 201 protected:
168 NO_SANITIZE_ADDRESS 202 NO_SANITIZE_ADDRESS
169 T* atomicGet() { 203 T* atomicGet() {
170 return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>( 204 return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>(
171 const_cast<typename std::remove_const<T>::type**>(&m_raw)))); 205 const_cast<typename std::remove_const<T>::type**>(&m_raw))));
(...skipping 12 matching lines...) Expand all
184 } 218 }
185 checkPointer(); 219 checkPointer();
186 if (m_raw) { 220 if (m_raw) {
187 if (!m_persistentNode) 221 if (!m_persistentNode)
188 initialize(); 222 initialize();
189 return; 223 return;
190 } 224 }
191 uninitialize(); 225 uninitialize();
192 } 226 }
193 227
228 // Used when the registered PersistentNode of this object is
229 // released during ThreadState shutdown, clearing the association.
230 static void clearPersistentNode(void* self,
231 ThreadState::ReleasePersistentMode mode) {
232 PersistentBase* persistent =
233 (reinterpret_cast<PersistentBase*>(self));
234 ClearStaticPersistentReference<T>::clear(persistent->get());
235 if (mode == ThreadState::ReleasePersistent)
236 persistent->uninitialize();
237 }
238
194 template <typename VisitorDispatcher> 239 template <typename VisitorDispatcher>
195 void tracePersistent(VisitorDispatcher visitor) { 240 void tracePersistent(VisitorDispatcher visitor) {
196 static_assert(sizeof(T), "T must be fully defined"); 241 static_assert(sizeof(T), "T must be fully defined");
197 static_assert(IsGarbageCollectedType<T>::value, 242 static_assert(IsGarbageCollectedType<T>::value,
198 "T needs to be a garbage collected object"); 243 "T needs to be a garbage collected object");
199 if (weaknessConfiguration == WeakPersistentConfiguration) { 244 if (weaknessConfiguration == WeakPersistentConfiguration) {
200 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) 245 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
201 visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this), 246 visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this),
202 handleWeakPersistent); 247 handleWeakPersistent);
203 else 248 else
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 638
594 private: 639 private:
595 template <typename VisitorDispatcher> 640 template <typename VisitorDispatcher>
596 void tracePersistent(VisitorDispatcher visitor) { 641 void tracePersistent(VisitorDispatcher visitor) {
597 static_assert(sizeof(Collection), "Collection must be fully defined"); 642 static_assert(sizeof(Collection), "Collection must be fully defined");
598 visitor->trace(*static_cast<Collection*>(this)); 643 visitor->trace(*static_cast<Collection*>(this));
599 } 644 }
600 645
601 // Used when the registered PersistentNode of this object is 646 // Used when the registered PersistentNode of this object is
602 // released during ThreadState shutdown, clearing the association. 647 // released during ThreadState shutdown, clearing the association.
603 static void clearPersistentNode(void* self) { 648 static void clearPersistentNode(void* self,
649 ThreadState::ReleasePersistentMode mode) {
604 PersistentHeapCollectionBase<Collection>* collection = 650 PersistentHeapCollectionBase<Collection>* collection =
605 (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self)); 651 (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self));
606 collection->uninitialize();
607 collection->clear(); 652 collection->clear();
653 if (mode == ThreadState::ReleasePersistent)
654 collection->uninitialize();
608 } 655 }
609 656
610 NO_SANITIZE_ADDRESS 657 NO_SANITIZE_ADDRESS
611 void initialize() { 658 void initialize() {
612 // FIXME: Derive affinity based on the collection. 659 // FIXME: Derive affinity based on the collection.
613 ThreadState* state = ThreadState::current(); 660 ThreadState* state = ThreadState::current();
614 ASSERT(state->checkThread()); 661 ASSERT(state->checkThread());
615 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( 662 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
616 this, 663 this,
617 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, 664 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>,
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 static blink::CrossThreadPersistent<T> Unwrap( 867 static blink::CrossThreadPersistent<T> Unwrap(
821 const blink::CrossThreadWeakPersistent<T>& wrapped) { 868 const blink::CrossThreadWeakPersistent<T>& wrapped) {
822 blink::CrossThreadPersistentRegion::LockScope persistentLock( 869 blink::CrossThreadPersistentRegion::LockScope persistentLock(
823 blink::ProcessHeap::crossThreadPersistentRegion()); 870 blink::ProcessHeap::crossThreadPersistentRegion());
824 return blink::CrossThreadPersistent<T>(wrapped.get()); 871 return blink::CrossThreadPersistent<T>(wrapped.get());
825 } 872 }
826 }; 873 };
827 } 874 }
828 875
829 #endif // Persistent_h 876 #endif // Persistent_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698