1 /* 2 * Copyright (C) 2014 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef Handle_h 32 #define Handle_h 33 34 #include "platform/heap/Heap.h" 35 #include "platform/heap/ThreadState.h" 36 #include "platform/heap/Visitor.h" 37 #include "wtf/Functional.h" 38 #include "wtf/HashFunctions.h" 39 #include "wtf/Locker.h" 40 #include "wtf/RawPtr.h" 41 #include "wtf/RefCounted.h" 42 #include "wtf/TypeTraits.h" 43 44 namespace WebCore { 45 46 template<typename T> class HeapTerminatedArray; 47 48 // Template to determine if a class is a GarbageCollectedMixin by checking if it 49 // has adjustAndMark and isAlive. We can't check directly if the class is a 50 // GarbageCollectedMixin because casting to it is potentially ambiguous. 51 template<typename T> 52 struct IsGarbageCollectedMixin { 53 typedef char TrueType; 54 struct FalseType { 55 char dummy[2]; 56 }; 57 58 #if COMPILER(MSVC) 59 template<typename U> static TrueType hasAdjustAndMark(char[&U::adjustAndMark != 0]); 60 template<typename U> static TrueType hasIsAlive(char[&U::isAlive != 0]); 61 #else 62 template<size_t> struct F; 63 template<typename U> static TrueType hasAdjustAndMark(F<sizeof(&U::adjustAndMark)>*); 64 template<typename U> static TrueType hasIsAlive(F<sizeof(&U::isAlive)>*); 65 #endif 66 template<typename U> static FalseType hasIsAlive(...); 67 template<typename U> static FalseType hasAdjustAndMark(...); 68 69 static bool const value = (sizeof(TrueType) == sizeof(hasAdjustAndMark<T>(0))) && (sizeof(TrueType) == sizeof(hasIsAlive<T>(0))); 70 }; 71 72 template <typename T> 73 struct IsGarbageCollectedType { 74 typedef typename WTF::RemoveConst<T>::Type NonConstType; 75 typedef WTF::IsSubclassOfTemplate<NonConstType, GarbageCollected> GarbageCollectedSubclass; 76 typedef IsGarbageCollectedMixin<NonConstType> GarbageCollectedMixinSubclass; 77 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashSet> HeapHashSetSubclass; 78 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass; 79 typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass; 80 typedef WTF::IsSubclassOfTemplate5<NonConstType, HeapHashMap> HeapHashMapSubclass; 81 typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass; 82 typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass; 83 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashCountedSet> HeapHashCountedSetSubclass; 84 typedef WTF::IsSubclassOfTemplate<NonConstType, HeapTerminatedArray> HeapTerminatedArraySubclass; 85 static const bool value = 86 GarbageCollectedSubclass::value 87 || GarbageCollectedMixinSubclass::value 88 || HeapHashSetSubclass::value 89 || HeapLinkedHashSetSubclass::value 90 || HeapListHashSetSubclass::value 91 || HeapHashMapSubclass::value 92 || HeapVectorSubclass::value 93 || HeapDequeSubclass::value 94 || HeapHashCountedSetSubclass::value 95 || HeapTerminatedArraySubclass::value; 96 }; 97 98 #define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \ 99 COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage) 100 101 template<typename T> class Member; 102 103 class PersistentNode { 104 public: 105 explicit PersistentNode(TraceCallback trace) 106 : m_trace(trace) 107 { 108 } 109 110 bool isAlive() { return m_trace; } 111 112 virtual ~PersistentNode() 113 { 114 ASSERT(isAlive()); 115 m_trace = 0; 116 } 117 118 // Ideally the trace method should be virtual and automatically dispatch 119 // to the most specific implementation. However having a virtual method 120 // on PersistentNode leads to too eager template instantiation with MSVC 121 // which leads to include cycles. 122 // Instead we call the constructor with a TraceCallback which knows the 123 // type of the most specific child and calls trace directly. See 124 // TraceMethodDelegate in Visitor.h for how this is done. 125 void trace(Visitor* visitor) 126 { 127 m_trace(visitor, this); 128 } 129 130 protected: 131 TraceCallback m_trace; 132 133 private: 134 PersistentNode* m_next; 135 PersistentNode* m_prev; 136 137 template<typename RootsAccessor, typename Owner> friend class PersistentBase; 138 friend class PersistentAnchor; 139 friend class ThreadState; 140 }; 141 142 // RootsAccessor for Persistent that provides access to thread-local list 143 // of persistent handles. Can only be used to create handles that 144 // are constructed and destructed on the same thread. 145 template<ThreadAffinity Affinity> 146 class ThreadLocalPersistents { 147 public: 148 static PersistentNode* roots() { return state()->roots(); } 149 150 // No locking required. Just check that we are at the right thread. 151 class Lock { 152 public: 153 Lock() { state()->checkThread(); } 154 }; 155 156 private: 157 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); } 158 }; 159 160 // RootsAccessor for Persistent that provides synchronized access to global 161 // list of persistent handles. Can be used for persistent handles that are 162 // passed between threads. 163 class GlobalPersistents { 164 public: 165 static PersistentNode* roots() { return ThreadState::globalRoots(); } 166 167 class Lock { 168 public: 169 Lock() : m_locker(ThreadState::globalRootsMutex()) { } 170 private: 171 MutexLocker m_locker; 172 }; 173 }; 174 175 // Base class for persistent handles. RootsAccessor specifies which list to 176 // link resulting handle into. Owner specifies the class containing trace 177 // method. 178 template<typename RootsAccessor, typename Owner> 179 class PersistentBase : public PersistentNode { 180 public: 181 ~PersistentBase() 182 { 183 typename RootsAccessor::Lock lock; 184 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list. 185 ASSERT(isAlive()); 186 ASSERT(m_next->isAlive()); 187 ASSERT(m_prev->isAlive()); 188 m_next->m_prev = m_prev; 189 m_prev->m_next = m_next; 190 } 191 192 protected: 193 inline PersistentBase() 194 : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline) 195 #ifndef NDEBUG 196 , m_roots(RootsAccessor::roots()) 197 #endif 198 { 199 typename RootsAccessor::Lock lock; 200 m_prev = RootsAccessor::roots(); 201 m_next = m_prev->m_next; 202 m_prev->m_next = this; 203 m_next->m_prev = this; 204 } 205 206 inline explicit PersistentBase(const PersistentBase& otherref) 207 : PersistentNode(otherref.m_trace) 208 #ifndef NDEBUG 209 , m_roots(RootsAccessor::roots()) 210 #endif 211 { 212 typename RootsAccessor::Lock lock; 213 ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list. 214 PersistentBase* other = const_cast<PersistentBase*>(&otherref); 215 m_prev = other; 216 m_next = other->m_next; 217 other->m_next = this; 218 m_next->m_prev = this; 219 } 220 221 inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; } 222 223 #ifndef NDEBUG 224 private: 225 PersistentNode* m_roots; 226 #endif 227 }; 228 229 // A dummy Persistent handle that ensures the list of persistents is never null. 230 // This removes a test from a hot path. 231 class PersistentAnchor : public PersistentNode { 232 public: 233 void trace(Visitor* visitor) 234 { 235 for (PersistentNode* current = m_next; current != this; current = current->m_next) 236 current->trace(visitor); 237 } 238 239 virtual ~PersistentAnchor() 240 { 241 // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a 242 // large number of objects leaked when we tear down the main thread. Since some of these might contain a 243 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at 244 // this point. 245 } 246 247 private: 248 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline) 249 { 250 m_next = this; 251 m_prev = this; 252 } 253 254 friend class ThreadState; 255 }; 256 257 #ifndef NDEBUG 258 // For global persistent handles we cannot check that the 259 // pointer is in the heap because that would involve 260 // inspecting the heap of running threads. 261 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \ 262 bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \ 263 ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer)) 264 #else 265 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) 266 #endif 267 268 template<typename T> 269 class CrossThreadPersistent; 270 271 // Persistent handles are used to store pointers into the 272 // managed heap. As long as the Persistent handle is alive 273 // the GC will keep the object pointed to alive. Persistent 274 // handles can be stored in objects and they are not scoped. 275 // Persistent handles must not be used to contain pointers 276 // between objects that are in the managed heap. They are only 277 // meant to point to managed heap objects from variables/members 278 // outside the managed heap. 279 // 280 // A Persistent is always a GC root from the point of view of 281 // the garbage collector. 282 // 283 // We have to construct and destruct Persistent with default RootsAccessor in 284 // the same thread. 285 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ > 286 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > { 287 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); 288 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); 289 public: 290 Persistent() : m_raw(0) { } 291 292 Persistent(std::nullptr_t) : m_raw(0) { } 293 294 Persistent(T* raw) : m_raw(raw) 295 { 296 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); 297 recordBacktrace(); 298 } 299 300 explicit Persistent(T& raw) : m_raw(&raw) 301 { 302 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); 303 recordBacktrace(); 304 } 305 306 Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); } 307 308 template<typename U> 309 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); } 310 311 template<typename U> 312 Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); } 313 314 template<typename U> 315 Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); } 316 317 template<typename U> 318 Persistent& operator=(U* other) 319 { 320 m_raw = other; 321 recordBacktrace(); 322 return *this; 323 } 324 325 Persistent& operator=(std::nullptr_t) 326 { 327 m_raw = 0; 328 return *this; 329 } 330 331 void clear() { m_raw = 0; } 332 333 virtual ~Persistent() 334 { 335 m_raw = 0; 336 } 337 338 template<typename U> 339 U* as() const 340 { 341 return static_cast<U*>(m_raw); 342 } 343 344 void trace(Visitor* visitor) 345 { 346 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent); 347 #if ENABLE(GC_TRACING) 348 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName); 349 #endif 350 visitor->mark(m_raw); 351 } 352 353 T* release() 354 { 355 T* result = m_raw; 356 m_raw = 0; 357 return result; 358 } 359 360 T& operator*() const { return *m_raw; } 361 362 bool operator!() const { return !m_raw; } 363 364 operator T*() const { return m_raw; } 365 operator RawPtr<T>() const { return m_raw; } 366 367 T* operator->() const { return *this; } 368 369 Persistent& operator=(const Persistent& other) 370 { 371 m_raw = other; 372 recordBacktrace(); 373 return *this; 374 } 375 376 template<typename U> 377 Persistent& operator=(const Persistent<U, RootsAccessor>& other) 378 { 379 m_raw = other; 380 recordBacktrace(); 381 return *this; 382 } 383 384 template<typename U> 385 Persistent& operator=(const Member<U>& other) 386 { 387 m_raw = other; 388 recordBacktrace(); 389 return *this; 390 } 391 392 template<typename U> 393 Persistent& operator=(const RawPtr<U>& other) 394 { 395 m_raw = other; 396 recordBacktrace(); 397 return *this; 398 } 399 400 T* get() const { return m_raw; } 401 402 private: 403 #if ENABLE(GC_TRACING) 404 void recordBacktrace() 405 { 406 if (m_raw) 407 m_tracingName = Heap::createBacktraceString(); 408 } 409 410 String m_tracingName; 411 #else 412 inline void recordBacktrace() const { } 413 #endif 414 T* m_raw; 415 416 friend class CrossThreadPersistent<T>; 417 }; 418 419 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 420 // different from the construction thread. 421 template<typename T> 422 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { 423 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); 424 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); 425 public: 426 CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { } 427 428 using Persistent<T, GlobalPersistents>::operator=; 429 }; 430 431 // FIXME: derive affinity based on the collection. 432 template<typename Collection, ThreadAffinity Affinity = AnyThread> 433 class PersistentHeapCollectionBase 434 : public Collection 435 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > { 436 // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent 437 // heap collections are always allocated off-heap. This allows persistent collections to be used in 438 // DEFINE_STATIC_LOCAL et. al. 439 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 440 public: 441 PersistentHeapCollectionBase() { } 442 443 template<typename OtherCollection> 444 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { } 445 446 void trace(Visitor* visitor) 447 { 448 #if ENABLE(GC_TRACING) 449 visitor->setHostInfo(this, "PersistentHeapCollectionBase"); 450 #endif 451 visitor->trace(*static_cast<Collection*>(this)); 452 } 453 }; 454 455 template< 456 typename KeyArg, 457 typename MappedArg, 458 typename HashArg = typename DefaultHash<KeyArg>::Hash, 459 typename KeyTraitsArg = HashTraits<KeyArg>, 460 typename MappedTraitsArg = HashTraits<MappedArg> > 461 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { }; 462 463 template< 464 typename ValueArg, 465 typename HashArg = typename DefaultHash<ValueArg>::Hash, 466 typename TraitsArg = HashTraits<ValueArg> > 467 class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { }; 468 469 template< 470 typename ValueArg, 471 typename HashArg = typename DefaultHash<ValueArg>::Hash, 472 typename TraitsArg = HashTraits<ValueArg> > 473 class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { }; 474 475 template< 476 typename ValueArg, 477 size_t inlineCapacity = 0, 478 typename HashArg = typename DefaultHash<ValueArg>::Hash> 479 class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { }; 480 481 template<typename T, typename U, typename V> 482 class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { }; 483 484 template<typename T, size_t inlineCapacity = 0> 485 class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > { 486 public: 487 PersistentHeapVector() { } 488 489 template<size_t otherCapacity> 490 PersistentHeapVector(const HeapVector<T, otherCapacity>& other) 491 : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other) 492 { 493 } 494 }; 495 496 template<typename T, size_t inlineCapacity = 0> 497 class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > { 498 public: 499 PersistentHeapDeque() { } 500 501 template<size_t otherCapacity> 502 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) 503 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other) 504 { 505 } 506 }; 507 508 // Members are used in classes to contain strong pointers to other oilpan heap 509 // allocated objects. 510 // All Member fields of a class must be traced in the class' trace method. 511 // During the mark phase of the GC all live objects are marked as live and 512 // all Member fields of a live object will be traced marked as live as well. 513 template<typename T> 514 class Member { 515 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member); 516 WTF_DISALLOW_ZERO_ASSIGNMENT(Member); 517 public: 518 Member() : m_raw(0) 519 { 520 } 521 522 Member(std::nullptr_t) : m_raw(0) 523 { 524 } 525 526 Member(T* raw) : m_raw(raw) 527 { 528 } 529 530 explicit Member(T& raw) : m_raw(&raw) 531 { 532 } 533 534 template<typename U> 535 Member(const RawPtr<U>& other) : m_raw(other.get()) 536 { 537 } 538 539 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) 540 { 541 } 542 543 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); } 544 545 template<typename U> 546 Member(const Persistent<U>& other) : m_raw(other) { } 547 548 Member(const Member& other) : m_raw(other) { } 549 550 template<typename U> 551 Member(const Member<U>& other) : m_raw(other) { } 552 553 T* release() 554 { 555 T* result = m_raw; 556 m_raw = 0; 557 return result; 558 } 559 560 template<typename U> 561 U* as() const 562 { 563 return static_cast<U*>(m_raw); 564 } 565 566 bool operator!() const { return !m_raw; } 567 568 operator T*() const { return m_raw; } 569 570 T* operator->() const { return m_raw; } 571 T& operator*() const { return *m_raw; } 572 template<typename U> 573 operator RawPtr<U>() const { return m_raw; } 574 575 template<typename U> 576 Member& operator=(const Persistent<U>& other) 577 { 578 m_raw = other; 579 return *this; 580 } 581 582 template<typename U> 583 Member& operator=(const Member<U>& other) 584 { 585 m_raw = other; 586 return *this; 587 } 588 589 template<typename U> 590 Member& operator=(U* other) 591 { 592 m_raw = other; 593 return *this; 594 } 595 596 template<typename U> 597 Member& operator=(RawPtr<U> other) 598 { 599 m_raw = other; 600 return *this; 601 } 602 603 Member& operator=(std::nullptr_t) 604 { 605 m_raw = 0; 606 return *this; 607 } 608 609 void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); } 610 611 T* get() const { return m_raw; } 612 613 void clear() { m_raw = 0; } 614 615 616 protected: 617 void verifyTypeIsGarbageCollected() const 618 { 619 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember); 620 } 621 622 T* m_raw; 623 624 template<bool x, WTF::WeakHandlingFlag y, ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; 625 friend class Visitor; 626 }; 627 628 template<typename T> 629 class TraceTrait<Member<T> > { 630 public: 631 static void trace(Visitor* visitor, void* self) 632 { 633 TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self)); 634 } 635 }; 636 637 // TraceTrait to allow compilation of trace method bodies when oilpan is disabled. 638 // This should never be called, but is needed to compile. 639 template<typename T> 640 class TraceTrait<RefPtr<T> > { 641 public: 642 static void trace(Visitor*, void*) 643 { 644 ASSERT_NOT_REACHED(); 645 } 646 }; 647 648 template<typename T> 649 class TraceTrait<OwnPtr<T> > { 650 public: 651 static void trace(Visitor* visitor, OwnPtr<T>* ptr) 652 { 653 TraceTrait<T>::trace(visitor, ptr->get()); 654 } 655 }; 656 657 template<bool needsTracing, typename T> 658 struct StdPairHelper; 659 660 template<typename T> 661 struct StdPairHelper<false, T> { 662 static void trace(Visitor*, T*) { } 663 }; 664 665 template<typename T> 666 struct StdPairHelper<true, T> { 667 static void trace(Visitor* visitor, T* t) 668 { 669 visitor->trace(*t); 670 } 671 }; 672 673 // This trace trait for std::pair will null weak members if their referent is 674 // collected. If you have a collection that contain weakness it does not remove 675 // entries from the collection that contain nulled weak members. 676 template<typename T, typename U> 677 class TraceTrait<std::pair<T, U> > { 678 public: 679 static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value; 680 static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value; 681 static void trace(Visitor* visitor, std::pair<T, U>* pair) 682 { 683 StdPairHelper<firstNeedsTracing, T>::trace(visitor, &pair->first); 684 StdPairHelper<secondNeedsTracing, U>::trace(visitor, &pair->second); 685 } 686 }; 687 688 // WeakMember is similar to Member in that it is used to point to other oilpan 689 // heap allocated objects. 690 // However instead of creating a strong pointer to the object, the WeakMember creates 691 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to 692 // to a heap allocated object are weak the object will be garbage collected. At the 693 // time of GC the weak pointers will automatically be set to null. 694 template<typename T> 695 class WeakMember : public Member<T> { 696 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember); 697 WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember); 698 public: 699 WeakMember() : Member<T>() { } 700 701 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } 702 703 WeakMember(T* raw) : Member<T>(raw) { } 704 705 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 706 707 template<typename U> 708 WeakMember(const Persistent<U>& other) : Member<T>(other) { } 709 710 template<typename U> 711 WeakMember(const Member<U>& other) : Member<T>(other) { } 712 713 template<typename U> 714 WeakMember& operator=(const Persistent<U>& other) 715 { 716 this->m_raw = other; 717 return *this; 718 } 719 720 template<typename U> 721 WeakMember& operator=(const Member<U>& other) 722 { 723 this->m_raw = other; 724 return *this; 725 } 726 727 template<typename U> 728 WeakMember& operator=(U* other) 729 { 730 this->m_raw = other; 731 return *this; 732 } 733 734 template<typename U> 735 WeakMember& operator=(const RawPtr<U>& other) 736 { 737 this->m_raw = other; 738 return *this; 739 } 740 741 WeakMember& operator=(std::nullptr_t) 742 { 743 this->m_raw = 0; 744 return *this; 745 } 746 747 private: 748 T** cell() const { return const_cast<T**>(&this->m_raw); } 749 750 friend class Visitor; 751 }; 752 753 // Comparison operators between (Weak)Members and Persistents 754 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); } 755 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); } 756 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 757 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } 758 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); } 759 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } 760 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 761 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } 762 763 // CPP-defined type names for the transition period where we want to 764 // support both reference counting and garbage collection based on a 765 // compile-time flag. 766 // 767 // C++11 template aliases were initially used (with clang only, not 768 // with GCC nor MSVC.) However, supporting both CPP defines and 769 // template aliases is problematic from outside a WebCore namespace 770 // when Oilpan is disabled: e.g., 771 // WebCore::RefCountedWillBeGarbageCollected as a template alias would 772 // uniquely resolve from within any namespace, but if it is backed by 773 // a CPP #define, it would expand to WebCore::RefCounted, and not the 774 // required WTF::RefCounted. 775 // 776 // Having the CPP expansion instead be fully namespace qualified, and the 777 // transition type be unqualified, would dually not work for template 778 // aliases. So, slightly unfortunately, fall back/down to the lowest 779 // commmon denominator of using CPP macros only. 780 #if ENABLE(OILPAN) 781 #define PassRefPtrWillBeRawPtr WTF::RawPtr 782 #define RefCountedWillBeGarbageCollected WebCore::GarbageCollected 783 #define RefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized 784 #define RefCountedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected 785 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized 786 #define ThreadSafeRefCountedWillBeGarbageCollected WebCore::GarbageCollected 787 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized 788 #define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WebCore::ThreadSafeRefCountedGarbageCollected 789 #define PersistentWillBeMember WebCore::Member 790 #define RefPtrWillBePersistent WebCore::Persistent 791 #define RefPtrWillBeRawPtr WTF::RawPtr 792 #define RefPtrWillBeMember WebCore::Member 793 #define RefPtrWillBeWeakMember WebCore::WeakMember 794 #define RefPtrWillBeCrossThreadPersistent WebCore::CrossThreadPersistent 795 #define RawPtrWillBeMember WebCore::Member 796 #define RawPtrWillBeWeakMember WebCore::WeakMember 797 #define OwnPtrWillBeMember WebCore::Member 798 #define OwnPtrWillBePersistent WebCore::Persistent 799 #define OwnPtrWillBeRawPtr WTF::RawPtr 800 #define PassOwnPtrWillBeRawPtr WTF::RawPtr 801 #define WeakPtrWillBeMember WebCore::Member 802 #define WeakPtrWillBeRawPtr WTF::RawPtr 803 #define WeakPtrWillBeWeakMember WebCore::WeakMember 804 #define NoBaseWillBeGarbageCollected WebCore::GarbageCollected 805 #define NoBaseWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized 806 #define NoBaseWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected 807 #define WillBeHeapHashMap WebCore::HeapHashMap 808 #define WillBePersistentHeapHashMap WebCore::PersistentHeapHashMap 809 #define WillBeHeapHashSet WebCore::HeapHashSet 810 #define WillBePersistentHeapHashSet WebCore::PersistentHeapHashSet 811 #define WillBeHeapLinkedHashSet WebCore::HeapLinkedHashSet 812 #define WillBePersistentHeapLinkedHashSet WebCore::PersistentHeapLinkedHashSet 813 #define WillBeHeapListHashSet WebCore::HeapListHashSet 814 #define WillBePersistentHeapListHashSet WebCore::PersistentHeapListHashSet 815 #define WillBeHeapVector WebCore::HeapVector 816 #define WillBePersistentHeapVector WebCore::PersistentHeapVector 817 #define WillBeHeapDeque WebCore::HeapDeque 818 #define WillBePersistentHeapDeque WebCore::PersistentHeapDeque 819 #define WillBeHeapHashCountedSet WebCore::HeapHashCountedSet 820 #define WillBePersistentHeapHashCountedSet WebCore::PersistentHeapHashCountedSet 821 #define WillBeGarbageCollectedMixin WebCore::GarbageCollectedMixin 822 #define WillBeHeapSupplement WebCore::HeapSupplement 823 #define WillBeHeapSupplementable WebCore::HeapSupplementable 824 #define WillBePersistentHeapSupplementable WebCore::PersistentHeapSupplementable 825 #define WillBeHeapTerminatedArray WebCore::HeapTerminatedArray 826 #define WillBeHeapTerminatedArrayBuilder WebCore::HeapTerminatedArrayBuilder 827 #define WillBeHeapLinkedStack WebCore::HeapLinkedStack 828 #define PersistentHeapHashSetWillBeHeapHashSet WebCore::HeapHashSet 829 830 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) 831 { 832 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 833 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 834 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 835 COMPILE_ASSERT(notRefCounted, youMustAdopt); 836 return PassRefPtrWillBeRawPtr<T>(ptr); 837 } 838 839 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) 840 { 841 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 842 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 843 return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr)); 844 } 845 846 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) 847 { 848 static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, ThreadSafeRefCountedGarbageCollected>::value; 849 COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop); 850 return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr)); 851 } 852 853 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) 854 { 855 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 856 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 857 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 858 COMPILE_ASSERT(notRefCounted, youMustAdopt); 859 return PassOwnPtrWillBeRawPtr<T>(ptr); 860 } 861 862 template<typename T> T* adoptPtrWillBeRefCountedGarbageCollected(T* ptr) 863 { 864 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 865 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 866 return adoptRefCountedGarbageCollected(ptr); 867 } 868 869 template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr) 870 { 871 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 872 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 873 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 874 COMPILE_ASSERT(notRefCounted, youMustAdopt); 875 return ptr; 876 } 877 878 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled. 879 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 880 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 881 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 882 883 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \ 884 DEFINE_STATIC_LOCAL(Persistent<type>, name, arguments) 885 886 #else // !ENABLE(OILPAN) 887 888 template<typename T> 889 class DummyBase { 890 public: 891 DummyBase() { } 892 ~DummyBase() { } 893 }; 894 895 // Export this instance to support WillBeGarbageCollectedMixin 896 // uses by code residing in non-webcore components. 897 template class PLATFORM_EXPORT DummyBase<void>; 898 899 #define PassRefPtrWillBeRawPtr WTF::PassRefPtr 900 #define RefCountedWillBeGarbageCollected WTF::RefCounted 901 #define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted 902 #define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted 903 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized WebCore::RefCountedGarbageCollected 904 #define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted 905 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted 906 #define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted 907 #define PersistentWillBeMember WebCore::Persistent 908 #define RefPtrWillBePersistent WTF::RefPtr 909 #define RefPtrWillBeRawPtr WTF::RefPtr 910 #define RefPtrWillBeMember WTF::RefPtr 911 #define RefPtrWillBeWeakMember WTF::RefPtr 912 #define RefPtrWillBeCrossThreadPersistent WTF::RefPtr 913 #define RawPtrWillBeMember WTF::RawPtr 914 #define RawPtrWillBeWeakMember WTF::RawPtr 915 #define OwnPtrWillBeMember WTF::OwnPtr 916 #define OwnPtrWillBePersistent WTF::OwnPtr 917 #define OwnPtrWillBeRawPtr WTF::OwnPtr 918 #define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr 919 #define WeakPtrWillBeMember WTF::WeakPtr 920 #define WeakPtrWillBeRawPtr WTF::WeakPtr 921 #define WeakPtrWillBeWeakMember WTF::WeakPtr 922 #define NoBaseWillBeGarbageCollected WebCore::DummyBase 923 #define NoBaseWillBeGarbageCollectedFinalized WebCore::DummyBase 924 #define NoBaseWillBeRefCountedGarbageCollected WebCore::DummyBase 925 #define WillBeHeapHashMap WTF::HashMap 926 #define WillBePersistentHeapHashMap WTF::HashMap 927 #define WillBeHeapHashSet WTF::HashSet 928 #define WillBePersistentHeapHashSet WTF::HashSet 929 #define WillBeHeapLinkedHashSet WTF::LinkedHashSet 930 #define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet 931 #define WillBeHeapListHashSet WTF::ListHashSet 932 #define WillBePersistentListHeapHashSet WTF::ListHashSet 933 #define WillBeHeapVector WTF::Vector 934 #define WillBePersistentHeapVector WTF::Vector 935 #define WillBeHeapDeque WTF::Deque 936 #define WillBePersistentHeapDeque WTF::Deque 937 #define WillBeHeapHeapCountedSet WTF::HeapCountedSet 938 #define WillBePersistentHeapHeapCountedSet WTF::HeapCountedSet 939 #define WillBeGarbageCollectedMixin WebCore::DummyBase<void> 940 #define WillBeHeapSupplement WebCore::Supplement 941 #define WillBeHeapSupplementable WebCore::Supplementable 942 #define WillBePersistentHeapSupplementable WebCore::Supplementable 943 #define WillBeHeapTerminatedArray WTF::TerminatedArray 944 #define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder 945 #define WillBeHeapLinkedStack WTF::LinkedStack 946 #define PersistentHeapHashSetWillBeHeapHashSet WebCore::PersistentHeapHashSet 947 948 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); } 949 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 950 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 951 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); } 952 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); } 953 954 template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr) 955 { 956 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 957 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 958 return adoptRefCountedGarbageCollected(ptr); 959 } 960 961 962 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED 963 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \ 964 public: \ 965 ~type(); \ 966 private: 967 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \ 968 public: \ 969 virtual ~type(); \ 970 private: 971 972 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \ 973 type::~type() { } 974 975 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \ 976 DEFINE_STATIC_REF(type, name, arguments) 977 978 #endif // ENABLE(OILPAN) 979 980 } // namespace WebCore 981 982 namespace WTF { 983 984 template <typename T> struct VectorTraits<WebCore::Member<T> > : VectorTraitsBase<WebCore::Member<T> > { 985 static const bool needsDestruction = false; 986 static const bool canInitializeWithMemset = true; 987 static const bool canMoveWithMemcpy = true; 988 }; 989 990 template <typename T> struct VectorTraits<WebCore::WeakMember<T> > : VectorTraitsBase<WebCore::WeakMember<T> > { 991 static const bool needsDestruction = false; 992 static const bool canInitializeWithMemset = true; 993 static const bool canMoveWithMemcpy = true; 994 }; 995 996 template <typename T> struct VectorTraits<WebCore::HeapVector<T, 0> > : VectorTraitsBase<WebCore::HeapVector<T, 0> > { 997 static const bool needsDestruction = false; 998 static const bool canInitializeWithMemset = true; 999 static const bool canMoveWithMemcpy = true; 1000 }; 1001 1002 template <typename T> struct VectorTraits<WebCore::HeapDeque<T, 0> > : VectorTraitsBase<WebCore::HeapDeque<T, 0> > { 1003 static const bool needsDestruction = false; 1004 static const bool canInitializeWithMemset = true; 1005 static const bool canMoveWithMemcpy = true; 1006 }; 1007 1008 template <typename T, size_t inlineCapacity> struct VectorTraits<WebCore::HeapVector<T, inlineCapacity> > : VectorTraitsBase<WebCore::HeapVector<T, inlineCapacity> > { 1009 static const bool needsDestruction = VectorTraits<T>::needsDestruction; 1010 static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset; 1011 static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy; 1012 }; 1013 1014 template <typename T, size_t inlineCapacity> struct VectorTraits<WebCore::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<WebCore::HeapDeque<T, inlineCapacity> > { 1015 static const bool needsDestruction = VectorTraits<T>::needsDestruction; 1016 static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset; 1017 static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy; 1018 }; 1019 1020 template<typename T> struct HashTraits<WebCore::Member<T> > : SimpleClassHashTraits<WebCore::Member<T> > { 1021 static const bool needsDestruction = false; 1022 // FIXME: The distinction between PeekInType and PassInType is there for 1023 // the sake of the reference counting handles. When they are gone the two 1024 // types can be merged into PassInType. 1025 // FIXME: Implement proper const'ness for iterator types. Requires support 1026 // in the marking Visitor. 1027 typedef RawPtr<T> PeekInType; 1028 typedef RawPtr<T> PassInType; 1029 typedef WebCore::Member<T>* IteratorGetType; 1030 typedef const WebCore::Member<T>* IteratorConstGetType; 1031 typedef WebCore::Member<T>& IteratorReferenceType; 1032 typedef T* const IteratorConstReferenceType; 1033 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; } 1034 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); } 1035 // FIXME: Similarly, there is no need for a distinction between PeekOutType 1036 // and PassOutType without reference counting. 1037 typedef T* PeekOutType; 1038 typedef T* PassOutType; 1039 1040 template<typename U> 1041 static void store(const U& value, WebCore::Member<T>& storage) { storage = value; } 1042 1043 static PeekOutType peek(const WebCore::Member<T>& value) { return value; } 1044 static PassOutType passOut(const WebCore::Member<T>& value) { return value; } 1045 }; 1046 1047 template<typename T> struct HashTraits<WebCore::WeakMember<T> > : SimpleClassHashTraits<WebCore::WeakMember<T> > { 1048 static const bool needsDestruction = false; 1049 // FIXME: The distinction between PeekInType and PassInType is there for 1050 // the sake of the reference counting handles. When they are gone the two 1051 // types can be merged into PassInType. 1052 // FIXME: Implement proper const'ness for iterator types. Requires support 1053 // in the marking Visitor. 1054 typedef RawPtr<T> PeekInType; 1055 typedef RawPtr<T> PassInType; 1056 typedef WebCore::WeakMember<T>* IteratorGetType; 1057 typedef const WebCore::WeakMember<T>* IteratorConstGetType; 1058 typedef WebCore::WeakMember<T>& IteratorReferenceType; 1059 typedef T* const IteratorConstReferenceType; 1060 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; } 1061 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); } 1062 // FIXME: Similarly, there is no need for a distinction between PeekOutType 1063 // and PassOutType without reference counting. 1064 typedef T* PeekOutType; 1065 typedef T* PassOutType; 1066 1067 template<typename U> 1068 static void store(const U& value, WebCore::WeakMember<T>& storage) { storage = value; } 1069 1070 static PeekOutType peek(const WebCore::WeakMember<T>& value) { return value; } 1071 static PassOutType passOut(const WebCore::WeakMember<T>& value) { return value; } 1072 static bool shouldRemoveFromCollection(WebCore::Visitor* visitor, WebCore::WeakMember<T>& value) { return !visitor->isAlive(value); } 1073 static void traceInCollection(WebCore::Visitor* visitor, WebCore::WeakMember<T>& weakMember, WebCore::ShouldWeakPointersBeMarkedStrongly strongify) 1074 { 1075 if (strongify == WebCore::WeakPointersActStrong) 1076 visitor->trace(reinterpret_cast<WebCore::Member<T>&>(weakMember)); // Strongified visit. 1077 } 1078 }; 1079 1080 template<typename T> struct PtrHash<WebCore::Member<T> > : PtrHash<T*> { 1081 template<typename U> 1082 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); } 1083 static bool equal(T* a, const WebCore::Member<T>& b) { return a == b; } 1084 static bool equal(const WebCore::Member<T>& a, T* b) { return a == b; } 1085 template<typename U, typename V> 1086 static bool equal(const U& a, const V& b) { return a == b; } 1087 }; 1088 1089 template<typename T> struct PtrHash<WebCore::WeakMember<T> > : PtrHash<WebCore::Member<T> > { 1090 }; 1091 1092 template<typename P> struct PtrHash<WebCore::Persistent<P> > : PtrHash<P*> { 1093 using PtrHash<P*>::hash; 1094 static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); } 1095 using PtrHash<P*>::equal; 1096 static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; } 1097 static bool equal(P* a, const RefPtr<P>& b) { return a == b; } 1098 static bool equal(const RefPtr<P>& a, P* b) { return a == b; } 1099 }; 1100 1101 // PtrHash is the default hash for hash tables with members. 1102 template<typename T> struct DefaultHash<WebCore::Member<T> > { 1103 typedef PtrHash<WebCore::Member<T> > Hash; 1104 }; 1105 1106 template<typename T> struct DefaultHash<WebCore::WeakMember<T> > { 1107 typedef PtrHash<WebCore::WeakMember<T> > Hash; 1108 }; 1109 1110 template<typename T> struct DefaultHash<WebCore::Persistent<T> > { 1111 typedef PtrHash<WebCore::Persistent<T> > Hash; 1112 }; 1113 1114 template<typename T> 1115 struct NeedsTracing<WebCore::Member<T> > { 1116 static const bool value = true; 1117 }; 1118 1119 template<typename T> 1120 struct IsWeak<WebCore::WeakMember<T> > { 1121 static const bool value = true; 1122 }; 1123 1124 template<typename T> inline T* getPtr(const WebCore::Member<T>& p) 1125 { 1126 return p.get(); 1127 } 1128 1129 template<typename T, typename U> 1130 struct NeedsTracing<std::pair<T, U> > { 1131 static const bool value = NeedsTracing<T>::value || NeedsTracing<U>::value || IsWeak<T>::value || IsWeak<U>::value; 1132 }; 1133 1134 template<typename T> 1135 struct NeedsTracing<OwnPtr<T> > { 1136 static const bool value = NeedsTracing<T>::value; 1137 }; 1138 1139 // We define specialization of the NeedsTracing trait for off heap collections 1140 // since we don't support tracing them. 1141 template<typename T, size_t N> 1142 struct NeedsTracing<Vector<T, N> > { 1143 static const bool value = false; 1144 }; 1145 1146 template<typename T, size_t N> 1147 struct NeedsTracing<Deque<T, N> > { 1148 static const bool value = false; 1149 }; 1150 1151 template<typename T, typename U, typename V> 1152 struct NeedsTracing<HashCountedSet<T, U, V> > { 1153 static const bool value = false; 1154 }; 1155 1156 template<typename T, typename U, typename V> 1157 struct NeedsTracing<HashSet<T, U, V> > { 1158 static const bool value = false; 1159 }; 1160 1161 template<typename T, size_t U, typename V> 1162 struct NeedsTracing<ListHashSet<T, U, V> > { 1163 static const bool value = false; 1164 }; 1165 1166 template<typename T, typename U, typename V> 1167 struct NeedsTracing<LinkedHashSet<T, U, V> > { 1168 static const bool value = false; 1169 }; 1170 1171 template<typename T, typename U, typename V, typename W, typename X> 1172 struct NeedsTracing<HashMap<T, U, V, W, X> > { 1173 static const bool value = false; 1174 }; 1175 1176 template<typename T, size_t inlineCapacity> 1177 struct NeedsTracing<ListHashSetNode<T, WebCore::HeapListHashSetAllocator<T, inlineCapacity> > *> { 1178 // All heap allocated node pointers need visiting to keep the nodes alive, 1179 // regardless of whether they contain pointers to other heap allocated 1180 // objects. 1181 static const bool value = true; 1182 }; 1183 1184 // For wtf/Functional.h 1185 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; 1186 1187 template<typename T> 1188 struct PointerParamStorageTraits<T*, false> { 1189 typedef T* StorageType; 1190 1191 static StorageType wrap(T* value) { return value; } 1192 static T* unwrap(const StorageType& value) { return value; } 1193 }; 1194 1195 template<typename T> 1196 struct PointerParamStorageTraits<T*, true> { 1197 typedef WebCore::CrossThreadPersistent<T> StorageType; 1198 1199 static StorageType wrap(T* value) { return value; } 1200 static T* unwrap(const StorageType& value) { return value.get(); } 1201 }; 1202 1203 template<typename T> 1204 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, WebCore::IsGarbageCollectedType<T>::value> { 1205 }; 1206 1207 template<typename T> 1208 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, WebCore::IsGarbageCollectedType<T>::value> { 1209 }; 1210 1211 } // namespace WTF 1212 1213 #endif 1214