OLD | NEW |
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" |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 protected: | 245 protected: |
246 template <bool x, | 246 template <bool x, |
247 WTF::WeakHandlingFlag y, | 247 WTF::WeakHandlingFlag y, |
248 WTF::ShouldWeakPointersBeMarkedStrongly z, | 248 WTF::ShouldWeakPointersBeMarkedStrongly z, |
249 typename U, | 249 typename U, |
250 typename V> | 250 typename V> |
251 friend struct CollectionBackingTraceTrait; | 251 friend struct CollectionBackingTraceTrait; |
252 friend class Visitor; | 252 friend class Visitor; |
253 }; | 253 }; |
254 | 254 |
| 255 // A checked version of Member<>, verifying that only same-thread references |
| 256 // are kept in the smart pointer. Intended to be used to diagnose unclean |
| 257 // thread reference usage in release builds. It simply exposes the debug-only |
| 258 // MemberBase<> checking we already have in place for select usage to diagnose |
| 259 // per-thread issues. Only intended used temporarily while diagnosing suspected |
| 260 // problems with cross-thread references. |
| 261 template <typename T> |
| 262 class SameThreadCheckedMember : public Member<T> { |
| 263 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| 264 typedef Member<T> Parent; |
| 265 |
| 266 public: |
| 267 SameThreadCheckedMember() : Parent() { saveCreationThreadState(); } |
| 268 SameThreadCheckedMember(std::nullptr_t) : Parent(nullptr) { |
| 269 saveCreationThreadState(); |
| 270 } |
| 271 |
| 272 SameThreadCheckedMember(T* raw) : Parent(raw) { |
| 273 saveCreationThreadState(); |
| 274 checkPointer(); |
| 275 } |
| 276 |
| 277 SameThreadCheckedMember(T& raw) : Parent(raw) { |
| 278 saveCreationThreadState(); |
| 279 checkPointer(); |
| 280 } |
| 281 |
| 282 SameThreadCheckedMember(WTF::HashTableDeletedValueType x) : Parent(x) { |
| 283 saveCreationThreadState(); |
| 284 checkPointer(); |
| 285 } |
| 286 |
| 287 SameThreadCheckedMember(const SameThreadCheckedMember& other) |
| 288 : Parent(other) { |
| 289 saveCreationThreadState(); |
| 290 } |
| 291 template <typename U> |
| 292 SameThreadCheckedMember(const SameThreadCheckedMember<U>& other) |
| 293 : Parent(other) { |
| 294 saveCreationThreadState(); |
| 295 checkPointer(); |
| 296 } |
| 297 |
| 298 template <typename U> |
| 299 SameThreadCheckedMember(const Persistent<U>& other) : Parent(other) { |
| 300 saveCreationThreadState(); |
| 301 checkPointer(); |
| 302 } |
| 303 |
| 304 template <typename U> |
| 305 SameThreadCheckedMember& operator=(const Persistent<U>& other) { |
| 306 Parent::operator=(other); |
| 307 checkPointer(); |
| 308 return *this; |
| 309 } |
| 310 |
| 311 template <typename U> |
| 312 SameThreadCheckedMember& operator=(const SameThreadCheckedMember<U>& other) { |
| 313 Parent::operator=(other); |
| 314 checkPointer(); |
| 315 return *this; |
| 316 } |
| 317 |
| 318 template <typename U> |
| 319 SameThreadCheckedMember& operator=(const WeakMember<U>& other) { |
| 320 Parent::operator=(other); |
| 321 checkPointer(); |
| 322 return *this; |
| 323 } |
| 324 |
| 325 template <typename U> |
| 326 SameThreadCheckedMember& operator=(U* other) { |
| 327 Parent::operator=(other); |
| 328 checkPointer(); |
| 329 return *this; |
| 330 } |
| 331 |
| 332 SameThreadCheckedMember& operator=(std::nullptr_t) { |
| 333 Parent::operator=(nullptr); |
| 334 return *this; |
| 335 } |
| 336 |
| 337 protected: |
| 338 template <bool x, |
| 339 WTF::WeakHandlingFlag y, |
| 340 WTF::ShouldWeakPointersBeMarkedStrongly z, |
| 341 typename U, |
| 342 typename V> |
| 343 friend struct CollectionBackingTraceTrait; |
| 344 friend class Visitor; |
| 345 |
| 346 private: |
| 347 void checkPointer() { |
| 348 if (!this->m_raw) |
| 349 return; |
| 350 // HashTable can store a special value (which is not aligned to the |
| 351 // allocation granularity) to Member<> to represent a deleted entry. |
| 352 // Thus we treat a pointer that is not aligned to the granularity |
| 353 // as a valid pointer. |
| 354 if (reinterpret_cast<intptr_t>(this->m_raw) % allocationGranularity) |
| 355 return; |
| 356 |
| 357 ThreadState* current = ThreadState::current(); |
| 358 DCHECK(current); |
| 359 // m_creationThreadState may be null when this is used in a heap |
| 360 // collection which initialized the Member with memset and the |
| 361 // constructor wasn't called. |
| 362 if (m_creationThreadState) { |
| 363 // Member should point to objects that belong in the same ThreadHeap. |
| 364 CHECK_EQ(&ThreadState::fromObject(this->m_raw)->heap(), |
| 365 &m_creationThreadState->heap()); |
| 366 // Member should point to objects that belong in the same ThreadHeap. |
| 367 CHECK_EQ(¤t->heap(), &m_creationThreadState->heap()); |
| 368 } else { |
| 369 CHECK_EQ(&ThreadState::fromObject(this->m_raw)->heap(), ¤t->heap()); |
| 370 } |
| 371 } |
| 372 |
| 373 void saveCreationThreadState() { |
| 374 m_creationThreadState = ThreadState::current(); |
| 375 // All Members should be created in an attached thread, but an empty |
| 376 // value Member may be created on an unattached thread by a heap |
| 377 // collection iterator. |
| 378 CHECK(this->m_creationThreadState || !this->m_raw); |
| 379 } |
| 380 |
| 381 const ThreadState* m_creationThreadState; |
| 382 }; |
| 383 |
255 // WeakMember is similar to Member in that it is used to point to other oilpan | 384 // WeakMember is similar to Member in that it is used to point to other oilpan |
256 // heap allocated objects. | 385 // heap allocated objects. |
257 // However instead of creating a strong pointer to the object, the WeakMember | 386 // However instead of creating a strong pointer to the object, the WeakMember |
258 // creates a weak pointer, which does not keep the pointee alive. Hence if all | 387 // creates a weak pointer, which does not keep the pointee alive. Hence if all |
259 // pointers to to a heap allocated object are weak the object will be garbage | 388 // pointers to to a heap allocated object are weak the object will be garbage |
260 // collected. At the time of GC the weak pointers will automatically be set to | 389 // collected. At the time of GC the weak pointers will automatically be set to |
261 // null. | 390 // null. |
262 template <typename T> | 391 template <typename T> |
263 class WeakMember : public MemberBase<T, TracenessMemberConfiguration::Traced> { | 392 class WeakMember : public MemberBase<T, TracenessMemberConfiguration::Traced> { |
264 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent; | 393 typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 using Hash = MemberHash<T>; | 525 using Hash = MemberHash<T>; |
397 }; | 526 }; |
398 | 527 |
399 template <typename T> | 528 template <typename T> |
400 struct DefaultHash<blink::UntracedMember<T>> { | 529 struct DefaultHash<blink::UntracedMember<T>> { |
401 STATIC_ONLY(DefaultHash); | 530 STATIC_ONLY(DefaultHash); |
402 using Hash = MemberHash<T>; | 531 using Hash = MemberHash<T>; |
403 }; | 532 }; |
404 | 533 |
405 template <typename T> | 534 template <typename T> |
| 535 struct DefaultHash<blink::SameThreadCheckedMember<T>> { |
| 536 STATIC_ONLY(DefaultHash); |
| 537 using Hash = MemberHash<T>; |
| 538 }; |
| 539 |
| 540 template <typename T> |
406 struct DefaultHash<blink::TraceWrapperMember<T>> { | 541 struct DefaultHash<blink::TraceWrapperMember<T>> { |
407 STATIC_ONLY(DefaultHash); | 542 STATIC_ONLY(DefaultHash); |
408 using Hash = MemberHash<T>; | 543 using Hash = MemberHash<T>; |
409 }; | 544 }; |
410 | 545 |
411 template <typename T> | 546 template <typename T> |
412 struct IsTraceable<blink::Member<T>> { | 547 struct IsTraceable<blink::Member<T>> { |
413 STATIC_ONLY(IsTraceable); | 548 STATIC_ONLY(IsTraceable); |
414 static const bool value = true; | 549 static const bool value = true; |
415 }; | 550 }; |
416 | 551 |
417 template <typename T> | 552 template <typename T> |
418 struct IsWeak<blink::WeakMember<T>> { | 553 struct IsWeak<blink::WeakMember<T>> { |
419 STATIC_ONLY(IsWeak); | 554 STATIC_ONLY(IsWeak); |
420 static const bool value = true; | 555 static const bool value = true; |
421 }; | 556 }; |
422 | 557 |
423 template <typename T> | 558 template <typename T> |
424 struct IsTraceable<blink::WeakMember<T>> { | 559 struct IsTraceable<blink::WeakMember<T>> { |
425 STATIC_ONLY(IsTraceable); | 560 STATIC_ONLY(IsTraceable); |
426 static const bool value = true; | 561 static const bool value = true; |
427 }; | 562 }; |
428 | 563 |
429 template <typename T> | 564 template <typename T> |
| 565 struct IsTraceable<blink::SameThreadCheckedMember<T>> { |
| 566 STATIC_ONLY(IsTraceable); |
| 567 static const bool value = true; |
| 568 }; |
| 569 |
| 570 template <typename T> |
430 struct IsTraceable<blink::TraceWrapperMember<T>> { | 571 struct IsTraceable<blink::TraceWrapperMember<T>> { |
431 STATIC_ONLY(IsTraceable); | 572 STATIC_ONLY(IsTraceable); |
432 static const bool value = true; | 573 static const bool value = true; |
433 }; | 574 }; |
434 | 575 |
435 } // namespace WTF | 576 } // namespace WTF |
436 | 577 |
437 #endif // Member_h | 578 #endif // Member_h |
OLD | NEW |