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

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 saveCreationThreadHeap();
27 } 28 }
28 29
29 Member(std::nullptr_t) : m_raw(nullptr) 30 MemberBase(std::nullptr_t) : m_raw(nullptr)
30 { 31 {
32 saveCreationThreadHeap();
31 } 33 }
32 34
33 Member(T* raw) : m_raw(raw) 35 MemberBase(T* raw) : m_raw(raw)
34 { 36 {
37 saveCreationThreadHeap();
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 saveCreationThreadHeap();
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 saveCreationThreadHeap();
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 saveCreationThreadHeap();
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 saveCreationThreadHeap();
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 saveCreationThreadHeap();
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();
haraken 2016/08/17 11:40:41 Add DCHECK(current).
keishi 2016/08/17 12:23:20 Done.
145 if (m_creationThreadState) {
146 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &m_creationTh readState->heap());
haraken 2016/08/17 11:40:41 Add a developer-friendly comment to help them unde
keishi 2016/08/17 12:23:20 Done.
147 DCHECK_EQ(&current->heap(), &m_creationThreadState->heap());
148 } else {
149 DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &current->hea p());
150 }
151 }
152
153 #if defined(ADDRESS_SANITIZER)
135 // TODO(haraken): What we really want to check here is that the pointer 154 // 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: 155 // is a traceable object. In other words, the pointer is either of:
137 // 156 //
138 // (a) a pointer to the head of an on-heap object. 157 // (a) a pointer to the head of an on-heap object.
139 // (b) a pointer to the head of an on-heap mixin object. 158 // (b) a pointer to the head of an on-heap mixin object.
140 // 159 //
141 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw), 160 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw),
142 // but we cannot call it here because it requires to include T.h. 161 // 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 162 // So we currently only try to implement the check for (a), but do
144 // not insist that T's definition is in scope. 163 // not insist that T's definition is in scope.
145 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) 164 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
146 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); 165 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
147 #endif 166 #endif
167 #endif
168 }
169
170 void saveCreationThreadHeap()
171 {
172 #if DCHECK_IS_ON()
173 if (tracenessConfiguration == TracenessMemberConfiguration::Untraced)
174 m_creationThreadState = nullptr;
175 else
176 m_creationThreadState = ThreadState::current();
haraken 2016/08/17 11:40:41 Add DCHECK(ThreadState::current()).
keishi 2016/08/17 12:23:20 Done.
177 #endif
148 } 178 }
149 179
150 T* m_raw; 180 T* m_raw;
181 #if DCHECK_IS_ON()
182 const ThreadState* m_creationThreadState;
183 #endif
151 184
152 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; 185 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
153 friend class Visitor; 186 friend class Visitor;
154 187
155 }; 188 };
156 189
190 // Members are used in classes to contain strong pointers to other oilpan heap
191 // allocated objects.
192 // All Member fields of a class must be traced in the class' trace method.
193 // During the mark phase of the GC all live objects are marked as live and
194 // all Member fields of a live object will be traced marked as live as well.
195 template<typename T>
196 class Member : public MemberBase<T, TracenessMemberConfiguration::Traced> {
197 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
198 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
199 public:
200 Member() : Parent() { }
201 Member(std::nullptr_t) : Parent(nullptr) { }
202 Member(T* raw) : Parent(raw) { }
203 Member(T& raw) : Parent(raw) { }
204 Member(WTF::HashTableDeletedValueType x) : Parent(x) { }
205
206 Member(const Member& other) : Parent(other) { }
207 template<typename U>
208 Member(const Member<U>& other) : Parent(other) { }
209 template<typename U>
210 Member(const Persistent<U>& other) : Parent(other) { }
211
212 template<typename U>
213 Member& operator=(const Persistent<U>& other)
214 {
215 Parent::operator=(other);
216 return *this;
217 }
218
219 template<typename U>
220 Member& operator=(const Member<U>& other)
221 {
222 Parent::operator=(other);
223 return *this;
224 }
225
226 template<typename U>
227 Member& operator=(const WeakMember<U>& other)
228 {
229 Parent::operator=(other);
230 return *this;
231 }
232
233 template<typename U>
234 Member& operator=(U* other)
235 {
236 Parent::operator=(other);
237 return *this;
238 }
239
240 Member& operator=(std::nullptr_t)
241 {
242 Parent::operator=(nullptr);
243 return *this;
244 }
245
246 protected:
247 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
248 friend class Visitor;
249 };
250
157 // WeakMember is similar to Member in that it is used to point to other oilpan 251 // WeakMember is similar to Member in that it is used to point to other oilpan
158 // heap allocated objects. 252 // heap allocated objects.
159 // However instead of creating a strong pointer to the object, the WeakMember cr eates 253 // 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 254 // 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 255 // 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. 256 // time of GC the weak pointers will automatically be set to null.
163 template<typename T> 257 template<typename T>
164 class WeakMember : public Member<T> { 258 class WeakMember : public MemberBase<T, TracenessMemberConfiguration::Traced> {
259 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
165 public: 260 public:
166 WeakMember() : Member<T>() { } 261 WeakMember() : Parent() { }
167 262
168 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } 263 WeakMember(std::nullptr_t) : Parent(nullptr) { }
169 264
170 WeakMember(T* raw) : Member<T>(raw) { } 265 WeakMember(T* raw) : Parent(raw) { }
171 266
172 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 267 WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
173 268
174 template<typename U> 269 template<typename U>
175 WeakMember(const Persistent<U>& other) : Member<T>(other) { } 270 WeakMember(const Persistent<U>& other) : Parent(other) { }
176 271
177 template<typename U> 272 template<typename U>
178 WeakMember(const Member<U>& other) : Member<T>(other) { } 273 WeakMember(const Member<U>& other) : Parent(other) { }
179 274
180 template<typename U> 275 template<typename U>
181 WeakMember& operator=(const Persistent<U>& other) 276 WeakMember& operator=(const Persistent<U>& other)
182 { 277 {
183 this->m_raw = other; 278 this->m_raw = other;
184 this->checkPointer(); 279 this->checkPointer();
185 return *this; 280 return *this;
186 } 281 }
187 282
188 template<typename U> 283 template<typename U>
(...skipping 26 matching lines...) Expand all
215 310
216 // UntracedMember is a pointer to an on-heap object that is not traced for some 311 // 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. 312 // 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 313 // 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 314 // 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 315 // 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 316 // 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 317 // course, it must be guaranteed that the pointing on-heap object is kept alive
223 // while the raw pointer is pointing to the object. 318 // while the raw pointer is pointing to the object.
224 template<typename T> 319 template<typename T>
225 class UntracedMember final : public Member<T> { 320 class UntracedMember final : public MemberBase<T, TracenessMemberConfiguration:: Untraced> {
321 typedef MemberBase<T, TracenessMemberConfiguration::Untraced> Parent;
226 public: 322 public:
227 UntracedMember() : Member<T>() { } 323 UntracedMember() : Parent() { }
228 324
229 UntracedMember(std::nullptr_t) : Member<T>(nullptr) { } 325 UntracedMember(std::nullptr_t) : Parent(nullptr) { }
230 326
231 UntracedMember(T* raw) : Member<T>(raw) { } 327 UntracedMember(T* raw) : Parent(raw) { }
232 328
233 template<typename U> 329 template<typename U>
234 UntracedMember(const Persistent<U>& other) : Member<T>(other) { } 330 UntracedMember(const Persistent<U>& other) : Parent(other) { }
235 331
236 template<typename U> 332 template<typename U>
237 UntracedMember(const Member<U>& other) : Member<T>(other) { } 333 UntracedMember(const Member<U>& other) : Parent(other) { }
238 334
239 UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 335 UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
240 336
241 template<typename U> 337 template<typename U>
242 UntracedMember& operator=(const Persistent<U>& other) 338 UntracedMember& operator=(const Persistent<U>& other)
243 { 339 {
244 this->m_raw = other; 340 this->m_raw = other;
245 this->checkPointer(); 341 this->checkPointer();
246 return *this; 342 return *this;
247 } 343 }
248 344
249 template<typename U> 345 template<typename U>
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 411
316 template<typename T> 412 template<typename T>
317 struct IsTraceable<blink::WeakMember<T>> { 413 struct IsTraceable<blink::WeakMember<T>> {
318 STATIC_ONLY(IsTraceable); 414 STATIC_ONLY(IsTraceable);
319 static const bool value = true; 415 static const bool value = true;
320 }; 416 };
321 417
322 } // namespace WTF 418 } // namespace WTF
323 419
324 #endif // Member_h 420 #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