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

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

Issue 2050463003: Check if Member owner thread matches pointer thread and current thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 4 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 Member_h 5 #ifndef Member_h
6 #define Member_h 6 #define Member_h
7 7
8 #include "wtf/Allocator.h" 8 #include "wtf/Allocator.h"
9 #include "wtf/HashFunctions.h" 9 #include "wtf/HashFunctions.h"
10 #include "wtf/HashTraits.h" 10 #include "wtf/HashTraits.h"
11 11
12 namespace blink { 12 namespace blink {
13 13
14 template<typename T> class Persistent; 14 template<typename T> class Persistent;
15 15
16 // Members are used in classes to contain strong pointers to other oilpan heap 16 enum class TracenessMemberConfiguration {
17 // allocated objects. 17 Traced,
18 // All Member fields of a class must be traced in the class' trace method. 18 Untraced,
19 // During the mark phase of the GC all live objects are marked as live and 19 };
20 // all Member fields of a live object will be traced marked as live as well. 20
21 template<typename T> 21 template<typename T, TracenessMemberConfiguration tracenessConfiguration = Trace nessMemberConfiguration::Traced>
22 class Member { 22 class MemberBase {
23 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); 23 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
24 public: 24 public:
25 Member() : m_raw(nullptr) 25 MemberBase() : m_raw(nullptr)
26 { 26 {
27 saveCreationThreadState();
27 } 28 }
28 29
29 Member(std::nullptr_t) : m_raw(nullptr) 30 MemberBase(std::nullptr_t) : m_raw(nullptr)
30 { 31 {
32 saveCreationThreadState();
31 } 33 }
32 34
33 Member(T* raw) : m_raw(raw) 35 MemberBase(T* raw) : m_raw(raw)
34 { 36 {
37 saveCreationThreadState();
35 checkPointer(); 38 checkPointer();
36 } 39 }
37 40
38 explicit Member(T& raw) : m_raw(&raw) 41 explicit MemberBase(T& raw) : m_raw(&raw)
39 { 42 {
43 saveCreationThreadState();
40 checkPointer(); 44 checkPointer();
41 } 45 }
42 46
43 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) 47 MemberBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
44 { 48 {
49 saveCreationThreadState();
45 } 50 }
46 51
47 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } 52 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); }
48 53
49 Member(const Member& other) : m_raw(other) 54 MemberBase(const MemberBase& other) : m_raw(other)
50 { 55 {
56 saveCreationThreadState();
51 checkPointer(); 57 checkPointer();
52 } 58 }
53 59
54 template<typename U> 60 template<typename U>
55 Member(const Persistent<U>& other) 61 MemberBase(const Persistent<U>& other)
56 { 62 {
63 saveCreationThreadState();
57 m_raw = other; 64 m_raw = other;
58 checkPointer(); 65 checkPointer();
59 } 66 }
60 67
61 template<typename U> 68 template<typename U>
62 Member(const Member<U>& other) : m_raw(other) 69 MemberBase(const MemberBase<U>& other) : m_raw(other)
63 { 70 {
71 saveCreationThreadState();
64 checkPointer(); 72 checkPointer();
65 } 73 }
66 74
67 T* release() 75 T* release()
68 { 76 {
69 T* result = m_raw; 77 T* result = m_raw;
70 m_raw = nullptr; 78 m_raw = nullptr;
71 return result; 79 return result;
72 } 80 }
73 81
74 explicit operator bool() const { return m_raw; } 82 explicit operator bool() const { return m_raw; }
75 83
76 operator T*() const { return m_raw; } 84 operator T*() const { return m_raw; }
77 85
78 T* operator->() const { return m_raw; } 86 T* operator->() const { return m_raw; }
79 T& operator*() const { return *m_raw; } 87 T& operator*() const { return *m_raw; }
80 88
81 template<typename U> 89 template<typename U>
82 Member& operator=(const Persistent<U>& other) 90 MemberBase& operator=(const Persistent<U>& other)
83 { 91 {
84 m_raw = other; 92 m_raw = other;
85 checkPointer(); 93 checkPointer();
86 return *this; 94 return *this;
87 } 95 }
88 96
89 template<typename U> 97 template<typename U>
90 Member& operator=(const Member<U>& other) 98 MemberBase& operator=(const MemberBase<U>& other)
91 { 99 {
92 m_raw = other; 100 m_raw = other;
93 checkPointer(); 101 checkPointer();
94 return *this; 102 return *this;
95 } 103 }
96 104
97 template<typename U> 105 template<typename U>
98 Member& operator=(U* other) 106 MemberBase& operator=(U* other)
99 { 107 {
100 m_raw = other; 108 m_raw = other;
101 checkPointer(); 109 checkPointer();
102 return *this; 110 return *this;
103 } 111 }
104 112
105 Member& operator=(std::nullptr_t) 113 MemberBase& operator=(std::nullptr_t)
106 { 114 {
107 m_raw = nullptr; 115 m_raw = nullptr;
108 return *this; 116 return *this;
109 } 117 }
110 118
111 void swap(Member<T>& other) 119 void swap(MemberBase<T>& other)
112 { 120 {
113 std::swap(m_raw, other.m_raw); 121 std::swap(m_raw, other.m_raw);
114 checkPointer(); 122 checkPointer();
115 } 123 }
116 124
117 T* get() const { return m_raw; } 125 T* get() const { return m_raw; }
118 126
119 void clear() { m_raw = nullptr; } 127 void clear() { m_raw = nullptr; }
120 128
121 129
122 protected: 130 protected:
123 void checkPointer() 131 void checkPointer()
124 { 132 {
125 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) 133 #if DCHECK_IS_ON()
126 if (!m_raw) 134 if (!m_raw)
127 return; 135 return;
128 // HashTable can store a special value (which is not aligned to the 136 // HashTable can store a special value (which is not aligned to the
129 // allocation granularity) to Member<> to represent a deleted entry. 137 // allocation granularity) to Member<> to represent a deleted entry.
130 // Thus we treat a pointer that is not aligned to the granularity 138 // Thus we treat a pointer that is not aligned to the granularity
131 // as a valid pointer. 139 // as a valid pointer.
132 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) 140 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity)
133 return; 141 return;
134 142
143 if (tracenessConfiguration != TracenessMemberConfiguration::Untraced) {
144 ThreadState* current = ThreadState::current();
145 DCHECK(current);
146 // m_creationThreadState may be null when this is used in a heap
147 // collection which initialized the Member with memset and the
148 // constructor wasn't called.
149 if (m_creationThreadState) {
150 // Member should point to objects that belong in the same Thread Heap.
151 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &m_creationTh readState->heap());
152 // Member should point to objects that belong in the same Thread Heap.
153 DCHECK_EQ(&current->heap(), &m_creationThreadState->heap());
154 } else {
155 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &current->hea p());
156 }
157 }
158
159 #if defined(ADDRESS_SANITIZER)
135 // TODO(haraken): What we really want to check here is that the pointer 160 // TODO(haraken): What we really want to check here is that the pointer
136 // is a traceable object. In other words, the pointer is either of: 161 // is a traceable object. In other words, the pointer is either of:
137 // 162 //
138 // (a) a pointer to the head of an on-heap object. 163 // (a) a pointer to the head of an on-heap object.
139 // (b) a pointer to the head of an on-heap mixin object. 164 // (b) a pointer to the head of an on-heap mixin object.
140 // 165 //
141 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw), 166 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw),
142 // but we cannot call it here because it requires to include T.h. 167 // but we cannot call it here because it requires to include T.h.
143 // So we currently only try to implement the check for (a), but do 168 // So we currently only try to implement the check for (a), but do
144 // not insist that T's definition is in scope. 169 // not insist that T's definition is in scope.
145 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) 170 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
146 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); 171 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
147 #endif 172 #endif
173 #endif
174 }
175
176 void saveCreationThreadState()
177 {
178 #if DCHECK_IS_ON()
179 if (tracenessConfiguration == TracenessMemberConfiguration::Untraced) {
180 m_creationThreadState = nullptr;
181 } else {
182 m_creationThreadState = ThreadState::current();
183 // Members should be created in an attached thread. But an empty
184 // value Member may be created on an unattached thread by a heap
185 // collection iterator.
186 DCHECK(m_creationThreadState || !m_raw);
187 }
188 #endif
148 } 189 }
149 190
150 T* m_raw; 191 T* m_raw;
192 #if DCHECK_IS_ON()
193 const ThreadState* m_creationThreadState;
194 #endif
151 195
152 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; 196 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
153 friend class Visitor; 197 friend class Visitor;
154 198
155 }; 199 };
156 200
201 // Members are used in classes to contain strong pointers to other oilpan heap
202 // allocated objects.
203 // All Member fields of a class must be traced in the class' trace method.
204 // During the mark phase of the GC all live objects are marked as live and
205 // all Member fields of a live object will be traced marked as live as well.
206 template<typename T>
207 class Member : public MemberBase<T, TracenessMemberConfiguration::Traced> {
208 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
209 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
210 public:
211 Member() : Parent() { }
212 Member(std::nullptr_t) : Parent(nullptr) { }
213 Member(T* raw) : Parent(raw) { }
214 Member(T& raw) : Parent(raw) { }
215 Member(WTF::HashTableDeletedValueType x) : Parent(x) { }
216
217 Member(const Member& other) : Parent(other) { }
218 template<typename U>
219 Member(const Member<U>& other) : Parent(other) { }
220 template<typename U>
221 Member(const Persistent<U>& other) : Parent(other) { }
222
223 template<typename U>
224 Member& operator=(const Persistent<U>& other)
225 {
226 Parent::operator=(other);
227 return *this;
228 }
229
230 template<typename U>
231 Member& operator=(const Member<U>& other)
232 {
233 Parent::operator=(other);
234 return *this;
235 }
236
237 template<typename U>
238 Member& operator=(const WeakMember<U>& other)
239 {
240 Parent::operator=(other);
241 return *this;
242 }
243
244 template<typename U>
245 Member& operator=(U* other)
246 {
247 Parent::operator=(other);
248 return *this;
249 }
250
251 Member& operator=(std::nullptr_t)
252 {
253 Parent::operator=(nullptr);
254 return *this;
255 }
256
257 protected:
258 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
259 friend class Visitor;
260 };
261
157 // WeakMember is similar to Member in that it is used to point to other oilpan 262 // WeakMember is similar to Member in that it is used to point to other oilpan
158 // heap allocated objects. 263 // heap allocated objects.
159 // However instead of creating a strong pointer to the object, the WeakMember cr eates 264 // However instead of creating a strong pointer to the object, the WeakMember cr eates
160 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to 265 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to
161 // to a heap allocated object are weak the object will be garbage collected. At the 266 // to a heap allocated object are weak the object will be garbage collected. At the
162 // time of GC the weak pointers will automatically be set to null. 267 // time of GC the weak pointers will automatically be set to null.
163 template<typename T> 268 template<typename T>
164 class WeakMember : public Member<T> { 269 class WeakMember : public MemberBase<T, TracenessMemberConfiguration::Traced> {
270 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
165 public: 271 public:
166 WeakMember() : Member<T>() { } 272 WeakMember() : Parent() { }
167 273
168 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } 274 WeakMember(std::nullptr_t) : Parent(nullptr) { }
169 275
170 WeakMember(T* raw) : Member<T>(raw) { } 276 WeakMember(T* raw) : Parent(raw) { }
171 277
172 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 278 WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
173 279
174 template<typename U> 280 template<typename U>
175 WeakMember(const Persistent<U>& other) : Member<T>(other) { } 281 WeakMember(const Persistent<U>& other) : Parent(other) { }
176 282
177 template<typename U> 283 template<typename U>
178 WeakMember(const Member<U>& other) : Member<T>(other) { } 284 WeakMember(const Member<U>& other) : Parent(other) { }
179 285
180 template<typename U> 286 template<typename U>
181 WeakMember& operator=(const Persistent<U>& other) 287 WeakMember& operator=(const Persistent<U>& other)
182 { 288 {
183 this->m_raw = other; 289 this->m_raw = other;
184 this->checkPointer(); 290 this->checkPointer();
185 return *this; 291 return *this;
186 } 292 }
187 293
188 template<typename U> 294 template<typename U>
(...skipping 26 matching lines...) Expand all
215 321
216 // UntracedMember is a pointer to an on-heap object that is not traced for some 322 // UntracedMember is a pointer to an on-heap object that is not traced for some
217 // reason. Please don't use this unless you understand what you're doing. 323 // reason. Please don't use this unless you understand what you're doing.
218 // Basically, all pointers to on-heap objects must be stored in either of 324 // Basically, all pointers to on-heap objects must be stored in either of
219 // Persistent, Member or WeakMember. It is not allowed to leave raw pointers to 325 // Persistent, Member or WeakMember. It is not allowed to leave raw pointers to
220 // on-heap objects. However, there can be scenarios where you have to use raw 326 // on-heap objects. However, there can be scenarios where you have to use raw
221 // pointers for some reason, and in that case you can use UntracedMember. Of 327 // pointers for some reason, and in that case you can use UntracedMember. Of
222 // course, it must be guaranteed that the pointing on-heap object is kept alive 328 // course, it must be guaranteed that the pointing on-heap object is kept alive
223 // while the raw pointer is pointing to the object. 329 // while the raw pointer is pointing to the object.
224 template<typename T> 330 template<typename T>
225 class UntracedMember final : public Member<T> { 331 class UntracedMember final : public MemberBase<T, TracenessMemberConfiguration:: Untraced> {
332 typedef MemberBase<T, TracenessMemberConfiguration::Untraced> Parent;
226 public: 333 public:
227 UntracedMember() : Member<T>() { } 334 UntracedMember() : Parent() { }
228 335
229 UntracedMember(std::nullptr_t) : Member<T>(nullptr) { } 336 UntracedMember(std::nullptr_t) : Parent(nullptr) { }
230 337
231 UntracedMember(T* raw) : Member<T>(raw) { } 338 UntracedMember(T* raw) : Parent(raw) { }
232 339
233 template<typename U> 340 template<typename U>
234 UntracedMember(const Persistent<U>& other) : Member<T>(other) { } 341 UntracedMember(const Persistent<U>& other) : Parent(other) { }
235 342
236 template<typename U> 343 template<typename U>
237 UntracedMember(const Member<U>& other) : Member<T>(other) { } 344 UntracedMember(const Member<U>& other) : Parent(other) { }
238 345
239 UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 346 UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
240 347
241 template<typename U> 348 template<typename U>
242 UntracedMember& operator=(const Persistent<U>& other) 349 UntracedMember& operator=(const Persistent<U>& other)
243 { 350 {
244 this->m_raw = other; 351 this->m_raw = other;
245 this->checkPointer(); 352 this->checkPointer();
246 return *this; 353 return *this;
247 } 354 }
248 355
249 template<typename U> 356 template<typename U>
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 422
316 template<typename T> 423 template<typename T>
317 struct IsTraceable<blink::WeakMember<T>> { 424 struct IsTraceable<blink::WeakMember<T>> {
318 STATIC_ONLY(IsTraceable); 425 STATIC_ONLY(IsTraceable);
319 static const bool value = true; 426 static const bool value = true;
320 }; 427 };
321 428
322 } // namespace WTF 429 } // namespace WTF
323 430
324 #endif // Member_h 431 #endif // Member_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/HeapTest.cpp ('k') | third_party/WebKit/Source/platform/heap/ThreadState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698