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

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 enum TracenessMemberConfiguration {
haraken 2016/08/16 13:27:13 Shall we use an enum class? enum class TracedMemb
keishi 2016/08/17 11:18:29 Done.
17 TracedMemberConfiguration,
18 UntracedMemberConfiguration
19 };
20
16 // Members are used in classes to contain strong pointers to other oilpan heap 21 // Members are used in classes to contain strong pointers to other oilpan heap
17 // allocated objects. 22 // allocated objects.
18 // All Member fields of a class must be traced in the class' trace method. 23 // All Member fields of a class must be traced in the class' trace method.
19 // During the mark phase of the GC all live objects are marked as live and 24 // During the mark phase of the GC all live objects are marked as live and
20 // all Member fields of a live object will be traced marked as live as well. 25 // all Member fields of a live object will be traced marked as live as well.
haraken 2016/08/16 13:27:13 Remove this comment.
keishi 2016/08/17 11:18:28 Done.
21 template<typename T> 26 template<typename T, TracenessMemberConfiguration tracenessConfiguration = Trace dMemberConfiguration>
22 class Member { 27 class MemberBase {
23 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); 28 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
24 public: 29 public:
25 Member() : m_raw(nullptr) 30 MemberBase() : m_raw(nullptr)
26 { 31 {
32 saveCreationThreadHeap();
27 } 33 }
28 34
29 Member(std::nullptr_t) : m_raw(nullptr) 35 MemberBase(std::nullptr_t) : m_raw(nullptr)
30 { 36 {
37 saveCreationThreadHeap();
31 } 38 }
32 39
33 Member(T* raw) : m_raw(raw) 40 MemberBase(T* raw) : m_raw(raw)
34 { 41 {
42 saveCreationThreadHeap();
35 checkPointer(); 43 checkPointer();
36 } 44 }
37 45
38 explicit Member(T& raw) : m_raw(&raw) 46 explicit MemberBase(T& raw) : m_raw(&raw)
39 { 47 {
48 saveCreationThreadHeap();
40 checkPointer(); 49 checkPointer();
41 } 50 }
42 51
43 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) 52 MemberBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
44 { 53 {
54 saveCreationThreadHeap();
45 } 55 }
46 56
47 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } 57 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); }
48 58
49 Member(const Member& other) : m_raw(other) 59 MemberBase(const MemberBase& other) : m_raw(other)
50 { 60 {
61 saveCreationThreadHeap();
51 checkPointer(); 62 checkPointer();
52 } 63 }
53 64
54 template<typename U> 65 template<typename U>
55 Member(const Persistent<U>& other) 66 MemberBase(const Persistent<U>& other)
56 { 67 {
68 saveCreationThreadHeap();
57 m_raw = other; 69 m_raw = other;
58 checkPointer(); 70 checkPointer();
59 } 71 }
60 72
61 template<typename U> 73 template<typename U>
62 Member(const Member<U>& other) : m_raw(other) 74 MemberBase(const MemberBase<U>& other) : m_raw(other)
63 { 75 {
76 saveCreationThreadHeap();
64 checkPointer(); 77 checkPointer();
65 } 78 }
66 79
67 T* release() 80 T* release()
68 { 81 {
69 T* result = m_raw; 82 T* result = m_raw;
70 m_raw = nullptr; 83 m_raw = nullptr;
71 return result; 84 return result;
72 } 85 }
73 86
74 explicit operator bool() const { return m_raw; } 87 explicit operator bool() const { return m_raw; }
75 88
76 operator T*() const { return m_raw; } 89 operator T*() const { return m_raw; }
77 90
78 T* operator->() const { return m_raw; } 91 T* operator->() const { return m_raw; }
79 T& operator*() const { return *m_raw; } 92 T& operator*() const { return *m_raw; }
80 93
81 template<typename U> 94 template<typename U>
82 Member& operator=(const Persistent<U>& other) 95 MemberBase& operator=(const Persistent<U>& other)
83 { 96 {
84 m_raw = other; 97 m_raw = other;
85 checkPointer(); 98 checkPointer();
86 return *this; 99 return *this;
87 } 100 }
88 101
89 template<typename U> 102 template<typename U>
90 Member& operator=(const Member<U>& other) 103 MemberBase& operator=(const MemberBase<U>& other)
91 { 104 {
92 m_raw = other; 105 m_raw = other;
93 checkPointer(); 106 checkPointer();
94 return *this; 107 return *this;
95 } 108 }
96 109
97 template<typename U> 110 template<typename U>
98 Member& operator=(U* other) 111 MemberBase& operator=(U* other)
99 { 112 {
100 m_raw = other; 113 m_raw = other;
101 checkPointer(); 114 checkPointer();
102 return *this; 115 return *this;
103 } 116 }
104 117
105 Member& operator=(std::nullptr_t) 118 MemberBase& operator=(std::nullptr_t)
106 { 119 {
107 m_raw = nullptr; 120 m_raw = nullptr;
108 return *this; 121 return *this;
109 } 122 }
110 123
111 void swap(Member<T>& other) 124 void swap(MemberBase<T>& other)
112 { 125 {
113 std::swap(m_raw, other.m_raw); 126 std::swap(m_raw, other.m_raw);
114 checkPointer(); 127 checkPointer();
115 } 128 }
116 129
117 T* get() const { return m_raw; } 130 T* get() const { return m_raw; }
118 131
119 void clear() { m_raw = nullptr; } 132 void clear() { m_raw = nullptr; }
120 133
121 134
122 protected: 135 protected:
123 void checkPointer() 136 void checkPointer()
124 { 137 {
125 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) 138 #if DCHECK_IS_ON()
126 if (!m_raw) 139 if (!m_raw)
127 return; 140 return;
128 // HashTable can store a special value (which is not aligned to the 141 // HashTable can store a special value (which is not aligned to the
129 // allocation granularity) to Member<> to represent a deleted entry. 142 // allocation granularity) to Member<> to represent a deleted entry.
130 // Thus we treat a pointer that is not aligned to the granularity 143 // Thus we treat a pointer that is not aligned to the granularity
131 // as a valid pointer. 144 // as a valid pointer.
132 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) 145 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity)
133 return; 146 return;
134 147
148 ThreadState* current = ThreadState::current();
149 if (tracenessConfiguration != UntracedMemberConfiguration && current) {
keishi 2016/08/16 13:05:49 Ignoring UntracedMember because in LayoutTests, Gr
haraken 2016/08/16 13:27:13 'tracenessConfiguration != UntracedMemberConfigura
keishi 2016/08/17 11:18:29 Done.
150 if (m_creationThreadHeap) {
haraken 2016/08/16 13:27:13 How is it possible that m_creationThreadHeap is nu
keishi 2016/08/17 11:18:28 I think heap collections use memset to initialize
haraken 2016/08/17 11:40:41 OK, let's add a comment about it.
keishi 2016/08/17 12:23:20 Done.
151 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), m_creationThr eadHeap);
152 DCHECK_EQ(&current->heap(), m_creationThreadHeap);
153 } else {
154 DCHECK(&ThreadState::fromObject(m_raw)->heap() == &current->heap ());
haraken 2016/08/16 13:27:13 Use DCHECK_EQ.
keishi 2016/08/17 11:18:29 Done.
155 }
156 }
157
158 #if defined(ADDRESS_SANITIZER)
135 // TODO(haraken): What we really want to check here is that the pointer 159 // 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: 160 // is a traceable object. In other words, the pointer is either of:
137 // 161 //
138 // (a) a pointer to the head of an on-heap object. 162 // (a) a pointer to the head of an on-heap object.
139 // (b) a pointer to the head of an on-heap mixin object. 163 // (b) a pointer to the head of an on-heap mixin object.
140 // 164 //
141 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw), 165 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw),
142 // but we cannot call it here because it requires to include T.h. 166 // 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 167 // So we currently only try to implement the check for (a), but do
144 // not insist that T's definition is in scope. 168 // not insist that T's definition is in scope.
145 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) 169 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
146 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); 170 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
147 #endif 171 #endif
172 #endif
173 }
174
175 void saveCreationThreadHeap()
keishi 2016/08/16 13:05:50 |this| may be on the stack, and if it is we can't
176 {
177 #if DCHECK_IS_ON()
178 if (ThreadState::current() && tracenessConfiguration != UntracedMemberCo nfiguration)
haraken 2016/08/16 13:27:13 Do we really need to check ThreadState::current()?
keishi 2016/08/17 11:18:28 Done.
179 m_creationThreadHeap = &ThreadState::current()->heap();
180 else
181 m_creationThreadHeap = nullptr;
182 #endif
148 } 183 }
149 184
150 T* m_raw; 185 T* m_raw;
186 #if DCHECK_IS_ON()
187 const ThreadHeap* m_creationThreadHeap;
188 #endif
151 189
152 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; 190 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
153 friend class Visitor; 191 friend class Visitor;
154 192
155 }; 193 };
156 194
195 // Members are used in classes to contain strong pointers to other oilpan heap
196 // allocated objects.
197 // All Member fields of a class must be traced in the class' trace method.
198 // During the mark phase of the GC all live objects are marked as live and
199 // all Member fields of a live object will be traced marked as live as well.
200 template<typename T>
201 class Member : public MemberBase<T, TracedMemberConfiguration> {
202 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
203 typedef MemberBase<T, TracedMemberConfiguration> Parent;
204 public:
205 Member() : Parent() { }
206 Member(std::nullptr_t) : Parent(nullptr) { }
207 Member(T* raw) : Parent(raw) { }
208 Member(T& raw) : Parent(raw) { }
209 Member(WTF::HashTableDeletedValueType x) : Parent(x) { }
210
211 Member(const Member& other) : Parent(other) { }
212 template<typename U>
213 Member(const Member<U>& other) : Parent(other) { }
214 template<typename U>
215 Member(const Persistent<U>& other) : Parent(other) { }
216
217 template<typename U>
218 Member& operator=(const Persistent<U>& other)
219 {
220 Parent::operator=(other);
221 return *this;
222 }
223
224 template<typename U>
225 Member& operator=(const Member<U>& other)
226 {
227 Parent::operator=(other);
228 return *this;
229 }
230
231 template<typename U>
232 Member& operator=(const WeakMember<U>& other)
233 {
234 Parent::operator=(other);
235 return *this;
236 }
237
238 template<typename U>
239 Member& operator=(U* other)
240 {
241 Parent::operator=(other);
242 return *this;
243 }
244
245 Member& operator=(std::nullptr_t)
246 {
247 Parent::operator=(nullptr);
248 return *this;
249 }
250
251 protected:
252 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
253 friend class Visitor;
254 };
255
157 // WeakMember is similar to Member in that it is used to point to other oilpan 256 // WeakMember is similar to Member in that it is used to point to other oilpan
158 // heap allocated objects. 257 // heap allocated objects.
159 // However instead of creating a strong pointer to the object, the WeakMember cr eates 258 // 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 259 // 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 260 // 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. 261 // time of GC the weak pointers will automatically be set to null.
163 template<typename T> 262 template<typename T>
164 class WeakMember : public Member<T> { 263 class WeakMember : public MemberBase<T, TracedMemberConfiguration> {
264 typedef MemberBase<T, TracedMemberConfiguration> Parent;
165 public: 265 public:
166 WeakMember() : Member<T>() { } 266 WeakMember() : Parent() { }
167 267
168 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } 268 WeakMember(std::nullptr_t) : Parent(nullptr) { }
169 269
170 WeakMember(T* raw) : Member<T>(raw) { } 270 WeakMember(T* raw) : Parent(raw) { }
171 271
172 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 272 WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
173 273
174 template<typename U> 274 template<typename U>
175 WeakMember(const Persistent<U>& other) : Member<T>(other) { } 275 WeakMember(const Persistent<U>& other) : Parent(other) { }
176 276
177 template<typename U> 277 template<typename U>
178 WeakMember(const Member<U>& other) : Member<T>(other) { } 278 WeakMember(const Member<U>& other) : Parent(other) { }
179 279
180 template<typename U> 280 template<typename U>
181 WeakMember& operator=(const Persistent<U>& other) 281 WeakMember& operator=(const Persistent<U>& other)
182 { 282 {
183 this->m_raw = other; 283 this->m_raw = other;
184 this->checkPointer(); 284 this->checkPointer();
185 return *this; 285 return *this;
186 } 286 }
187 287
188 template<typename U> 288 template<typename U>
(...skipping 26 matching lines...) Expand all
215 315
216 // UntracedMember is a pointer to an on-heap object that is not traced for some 316 // 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. 317 // 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 318 // 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 319 // 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 320 // 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 321 // 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 322 // course, it must be guaranteed that the pointing on-heap object is kept alive
223 // while the raw pointer is pointing to the object. 323 // while the raw pointer is pointing to the object.
224 template<typename T> 324 template<typename T>
225 class UntracedMember final : public Member<T> { 325 class UntracedMember final : public MemberBase<T, UntracedMemberConfiguration> {
326 typedef MemberBase<T, UntracedMemberConfiguration> Parent;
226 public: 327 public:
227 UntracedMember() : Member<T>() { } 328 UntracedMember() : Parent() { }
228 329
229 UntracedMember(std::nullptr_t) : Member<T>(nullptr) { } 330 UntracedMember(std::nullptr_t) : Parent(nullptr) { }
230 331
231 UntracedMember(T* raw) : Member<T>(raw) { } 332 UntracedMember(T* raw) : Parent(raw) { }
232 333
233 template<typename U> 334 template<typename U>
234 UntracedMember(const Persistent<U>& other) : Member<T>(other) { } 335 UntracedMember(const Persistent<U>& other) : Parent(other) { }
235 336
236 template<typename U> 337 template<typename U>
237 UntracedMember(const Member<U>& other) : Member<T>(other) { } 338 UntracedMember(const Member<U>& other) : Parent(other) { }
238 339
239 UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 340 UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
240 341
241 template<typename U> 342 template<typename U>
242 UntracedMember& operator=(const Persistent<U>& other) 343 UntracedMember& operator=(const Persistent<U>& other)
243 { 344 {
244 this->m_raw = other; 345 this->m_raw = other;
245 this->checkPointer(); 346 this->checkPointer();
246 return *this; 347 return *this;
247 } 348 }
248 349
249 template<typename U> 350 template<typename U>
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 416
316 template<typename T> 417 template<typename T>
317 struct IsTraceable<blink::WeakMember<T>> { 418 struct IsTraceable<blink::WeakMember<T>> {
318 STATIC_ONLY(IsTraceable); 419 STATIC_ONLY(IsTraceable);
319 static const bool value = true; 420 static const bool value = true;
320 }; 421 };
321 422
322 } // namespace WTF 423 } // namespace WTF
323 424
324 #endif // Member_h 425 #endif // Member_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698