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 44namespace blink { 45 46template<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. 51template<typename T> 52struct 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 72template <typename T> 73struct IsGarbageCollectedType { 74 typedef char TrueType; 75 struct FalseType { 76 char dummy[2]; 77 }; 78 79 typedef typename WTF::RemoveConst<T>::Type NonConstType; 80 typedef WTF::IsSubclassOfTemplate<NonConstType, GarbageCollected> GarbageCollectedSubclass; 81 typedef IsGarbageCollectedMixin<NonConstType> GarbageCollectedMixinSubclass; 82 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashSet> HeapHashSetSubclass; 83 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass; 84 typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass; 85 typedef WTF::IsSubclassOfTemplate5<NonConstType, HeapHashMap> HeapHashMapSubclass; 86 typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass; 87 typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass; 88 typedef WTF::IsSubclassOfTemplate3<NonConstType, HeapHashCountedSet> HeapHashCountedSetSubclass; 89 typedef WTF::IsSubclassOfTemplate<NonConstType, HeapTerminatedArray> HeapTerminatedArraySubclass; 90 91 template<typename U, size_t inlineCapacity> static TrueType listHashSetNodeIsHeapAllocated(WTF::ListHashSetNode<U, HeapListHashSetAllocator<U, inlineCapacity> >*); 92 static FalseType listHashSetNodeIsHeapAllocated(...); 93 static const bool isHeapAllocatedListHashSetNode = sizeof(TrueType) == sizeof(listHashSetNodeIsHeapAllocated(reinterpret_cast<NonConstType*>(0))); 94 95 static const bool value = 96 GarbageCollectedSubclass::value 97 || GarbageCollectedMixinSubclass::value 98 || HeapHashSetSubclass::value 99 || HeapLinkedHashSetSubclass::value 100 || HeapListHashSetSubclass::value 101 || HeapHashMapSubclass::value 102 || HeapVectorSubclass::value 103 || HeapDequeSubclass::value 104 || HeapHashCountedSetSubclass::value 105 || HeapTerminatedArraySubclass::value 106 || isHeapAllocatedListHashSetNode; 107}; 108 109#define COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, ErrorMessage) \ 110 COMPILE_ASSERT(IsGarbageCollectedType<T>::value, ErrorMessage) 111 112template<typename T> class Member; 113 114class PersistentNode { 115public: 116 explicit PersistentNode(TraceCallback trace) 117 : m_trace(trace) 118 { 119 } 120 121 bool isAlive() { return m_trace; } 122 123 virtual ~PersistentNode() 124 { 125 ASSERT(isAlive()); 126 m_trace = 0; 127 } 128 129 // Ideally the trace method should be virtual and automatically dispatch 130 // to the most specific implementation. However having a virtual method 131 // on PersistentNode leads to too eager template instantiation with MSVC 132 // which leads to include cycles. 133 // Instead we call the constructor with a TraceCallback which knows the 134 // type of the most specific child and calls trace directly. See 135 // TraceMethodDelegate in Visitor.h for how this is done. 136 void trace(Visitor* visitor) 137 { 138 m_trace(visitor, this); 139 } 140 141protected: 142 TraceCallback m_trace; 143 144private: 145 PersistentNode* m_next; 146 PersistentNode* m_prev; 147 148 template<typename RootsAccessor, typename Owner> friend class PersistentBase; 149 friend class PersistentAnchor; 150 friend class ThreadState; 151}; 152 153 154const int wrapperPersistentsPerRegion = 256; 155const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3); 156const size_t wrapperPersistentLiveBitMask = 1; 157 158class WrapperPersistentNode { 159 ALLOW_ONLY_INLINE_ALLOCATION(); 160 WTF_MAKE_NONCOPYABLE(WrapperPersistentNode); 161public: 162 bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; } 163 164 WrapperPersistentRegion* region() 165 { 166 return reinterpret_cast<WrapperPersistentRegion*>( 167 reinterpret_cast<Address>(this) - regionOffset()); 168 } 169 170 virtual void trace(Visitor* visitor) { } 171 172 static inline void destroy(const WrapperPersistentNode*); 173 174protected: 175 WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { } 176 WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_regionOffset(regionOffset) { } 177 178private: 179 size_t regionOffset() { return m_regionOffset & wrapperPersistentOffsetMask; } 180 181 WrapperPersistentNode* takeSlot() 182 { 183 // The slot should not be alive at the point where it is allocated. 184 ASSERT(!isAlive()); 185 WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode*>(m_raw); 186 m_raw = 0; 187 return nextFree; 188 } 189 190 WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree) 191 { 192 m_regionOffset &= ~wrapperPersistentLiveBitMask; 193 m_raw = nextFree; 194 return this; 195 } 196 197 // Don't allow delete being called on wrapper persistent nodes. We 198 // do use placement new to initialize the slot with the right vtable. See 199 // WrapperPersistent<T> below. 200 void operator delete(void*); 201 202protected: 203 // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive 204 // and to point to the next free wrapperPersistentNode in the region when the node is 205 // unused/dead. 206 void* m_raw; 207 208 // The m_regionOffset field encodes liveness of the slot as well as being an 209 // offset from this node to the base of the containing WrapperPersistentRegion. 210 size_t m_regionOffset; 211 212 friend class WrapperPersistentRegion; 213}; 214 215template<typename T> 216class WrapperPersistent FINAL : public WrapperPersistentNode { 217 ALLOW_ONLY_INLINE_ALLOCATION(); 218public: 219 static WrapperPersistent<T>* create(T* raw); 220 221 virtual void trace(Visitor* visitor) OVERRIDE 222 { 223 ASSERT(isAlive()); 224 visitor->mark(static_cast<T*>(m_raw)); 225 } 226 227private: 228 WrapperPersistent() { } 229 230 // We need to use a constructor to initialize the allocated slot since it 231 // has a vtable which must be set to the WrapperPersistent<T> type. 232 WrapperPersistent(T* raw, size_t regionOffset) : WrapperPersistentNode(raw, regionOffset) { } 233 234 // Don't allow delete being called on wrapper persistents. 235 void operator delete(void*); 236}; 237 238class PLATFORM_EXPORT WrapperPersistentRegion { 239 WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion); 240public: 241 WrapperPersistentRegion() 242 { 243 WrapperPersistentNode* nextFree = 0; 244 for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) { 245 size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - reinterpret_cast<Address>(this); 246 // Setup the free slot with an offset to the containing region's base and a pointer to the next 247 // free slot in the region. 248 ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask)); 249 new (&m_entries[i]) WrapperPersistentNode(nextFree, regionOffset); 250 nextFree = &m_entries[i]; 251 } 252 m_prev = 0; 253 m_next = 0; 254 m_freeHead = nextFree; 255 m_count = 0; 256 } 257 258 Address allocate() 259 { 260 if (!m_freeHead) { 261 ASSERT(m_count == wrapperPersistentsPerRegion); 262 return 0; 263 } 264 // We have a free persistent slot in this region. 265 WrapperPersistentNode* freeSlot = m_freeHead; 266 // Take the slot and advance m_freeHead to the next free slot. 267 m_freeHead = freeSlot->takeSlot(); 268 ASSERT(m_count < wrapperPersistentsPerRegion); 269 m_count++; 270 return reinterpret_cast<Address>(freeSlot); 271 } 272 273 void free(WrapperPersistentNode* object) 274 { 275 ASSERT(object); 276 m_freeHead = object->freeSlot(m_freeHead); 277 ASSERT(m_count > 0); 278 m_count--; 279 if (!m_count) 280 ThreadState::current()->freeWrapperPersistentRegion(this); 281 } 282 283 bool removeIfNotLast(WrapperPersistentRegion** headPtr); 284 static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentRegion* newHead); 285 static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr); 286 static Address outOfLineAllocate(ThreadState*, WrapperPersistentRegion**); 287 static void trace(WrapperPersistentRegion* head, Visitor* visitor) 288 { 289 for (WrapperPersistentRegion* current = head; current; current = current->m_next) 290 current->traceRegion(visitor); 291 } 292 293private: 294 void traceRegion(Visitor* visitor) 295 { 296 size_t live = 0; 297 298#ifdef NDEBUG 299 for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) { 300#else 301 // In DEBUG mode we scan all entries to validate we only have m_count 302 // live entries. 303 for (int i = 0; i < wrapperPersistentsPerRegion; ++i) { 304#endif 305 if (m_entries[i].isAlive()) { 306 m_entries[i].trace(visitor); 307 live++; 308 } 309 } 310 ASSERT(live == m_count); 311 } 312 313 WrapperPersistentRegion* m_prev; 314 WrapperPersistentRegion* m_next; 315 WrapperPersistentNode* m_freeHead; 316 size_t m_count; 317 WrapperPersistentNode m_entries[wrapperPersistentsPerRegion]; 318}; 319 320template<typename T> 321WrapperPersistent<T>* WrapperPersistent<T>::create(T* raw) 322{ 323 ThreadState* state = ThreadState::current(); 324 WrapperPersistentRegion* region = state->wrapperRoots(); 325 ASSERT(region); 326 Address persistentSlot = region->allocate(); 327 if (!persistentSlot) 328 persistentSlot = WrapperPersistentRegion::outOfLineAllocate(state, ®ion); 329 ASSERT(persistentSlot); 330 ASSERT(!reinterpret_cast<WrapperPersistentNode*>(persistentSlot)->isAlive()); 331 332 size_t regionOffset = persistentSlot - reinterpret_cast<Address>(region); 333 regionOffset |= wrapperPersistentLiveBitMask; 334 335 // We use placement new to call the constructor to ensure that we setup the 336 // vtable correctly. 337 return new (persistentSlot) WrapperPersistent<T>(raw, regionOffset); 338} 339 340void WrapperPersistentNode::destroy(const WrapperPersistentNode* node) 341{ 342 WrapperPersistentNode* persistent = const_cast<WrapperPersistentNode*>(node); 343 persistent->region()->free(persistent); 344} 345 346// RootsAccessor for Persistent that provides access to thread-local list 347// of persistent handles. Can only be used to create handles that 348// are constructed and destructed on the same thread. 349template<ThreadAffinity Affinity> 350class ThreadLocalPersistents { 351public: 352 static PersistentNode* roots() { return state()->roots(); } 353 354 // No locking required. Just check that we are at the right thread. 355 class Lock { 356 public: 357 Lock() { state()->checkThread(); } 358 }; 359 360private: 361 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); } 362}; 363 364// RootsAccessor for Persistent that provides synchronized access to global 365// list of persistent handles. Can be used for persistent handles that are 366// passed between threads. 367class GlobalPersistents { 368public: 369 static PersistentNode* roots() { return ThreadState::globalRoots(); } 370 371 class Lock { 372 public: 373 Lock() : m_locker(ThreadState::globalRootsMutex()) { } 374 private: 375 MutexLocker m_locker; 376 }; 377}; 378 379// Base class for persistent handles. RootsAccessor specifies which list to 380// link resulting handle into. Owner specifies the class containing trace 381// method. 382template<typename RootsAccessor, typename Owner> 383class PersistentBase : public PersistentNode { 384public: 385 ~PersistentBase() 386 { 387 typename RootsAccessor::Lock lock; 388 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list. 389 ASSERT(isAlive()); 390 ASSERT(m_next->isAlive()); 391 ASSERT(m_prev->isAlive()); 392 m_next->m_prev = m_prev; 393 m_prev->m_next = m_next; 394 } 395 396protected: 397 inline PersistentBase() 398 : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline) 399#if ENABLE(ASSERT) 400 , m_roots(RootsAccessor::roots()) 401#endif 402 { 403 typename RootsAccessor::Lock lock; 404 m_prev = RootsAccessor::roots(); 405 m_next = m_prev->m_next; 406 m_prev->m_next = this; 407 m_next->m_prev = this; 408 } 409 410 inline explicit PersistentBase(const PersistentBase& otherref) 411 : PersistentNode(otherref.m_trace) 412#if ENABLE(ASSERT) 413 , m_roots(RootsAccessor::roots()) 414#endif 415 { 416 // We don't support allocation of thread local Persistents while doing 417 // thread shutdown/cleanup. 418 ASSERT(!ThreadState::current()->isTerminating()); 419 typename RootsAccessor::Lock lock; 420 ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list. 421 PersistentBase* other = const_cast<PersistentBase*>(&otherref); 422 m_prev = other; 423 m_next = other->m_next; 424 other->m_next = this; 425 m_next->m_prev = this; 426 } 427 428 inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; } 429 430#if ENABLE(ASSERT) 431private: 432 PersistentNode* m_roots; 433#endif 434}; 435 436// A dummy Persistent handle that ensures the list of persistents is never null. 437// This removes a test from a hot path. 438class PersistentAnchor : public PersistentNode { 439public: 440 void trace(Visitor* visitor) 441 { 442 for (PersistentNode* current = m_next; current != this; current = current->m_next) 443 current->trace(visitor); 444 } 445 446 int numberOfPersistents() 447 { 448 int numberOfPersistents = 0; 449 for (PersistentNode* current = m_next; current != this; current = current->m_next) 450 ++numberOfPersistents; 451 return numberOfPersistents; 452 } 453 454 virtual ~PersistentAnchor() 455 { 456 // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a 457 // large number of objects leaked when we tear down the main thread. Since some of these might contain a 458 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at 459 // this point. 460 } 461 462private: 463 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline) 464 { 465 m_next = this; 466 m_prev = this; 467 } 468 469 friend class ThreadState; 470}; 471 472#if ENABLE(ASSERT) 473 // For global persistent handles we cannot check that the 474 // pointer is in the heap because that would involve 475 // inspecting the heap of running threads. 476#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \ 477 bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \ 478 ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer)) 479#else 480#define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) 481#endif 482 483template<typename T> 484class CrossThreadPersistent; 485 486// Persistent handles are used to store pointers into the 487// managed heap. As long as the Persistent handle is alive 488// the GC will keep the object pointed to alive. Persistent 489// handles can be stored in objects and they are not scoped. 490// Persistent handles must not be used to contain pointers 491// between objects that are in the managed heap. They are only 492// meant to point to managed heap objects from variables/members 493// outside the managed heap. 494// 495// A Persistent is always a GC root from the point of view of 496// the garbage collector. 497// 498// We have to construct and destruct Persistent with default RootsAccessor in 499// the same thread. 500template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ > 501class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > { 502 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); 503 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); 504public: 505 Persistent() : m_raw(0) { } 506 507 Persistent(std::nullptr_t) : m_raw(0) { } 508 509 Persistent(T* raw) : m_raw(raw) 510 { 511 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); 512 recordBacktrace(); 513 } 514 515 explicit Persistent(T& raw) : m_raw(&raw) 516 { 517 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); 518 recordBacktrace(); 519 } 520 521 Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); } 522 523 template<typename U> 524 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); } 525 526 template<typename U> 527 Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); } 528 529 template<typename U> 530 Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); } 531 532 template<typename U> 533 Persistent& operator=(U* other) 534 { 535 m_raw = other; 536 recordBacktrace(); 537 return *this; 538 } 539 540 Persistent& operator=(std::nullptr_t) 541 { 542 m_raw = 0; 543 return *this; 544 } 545 546 void clear() { m_raw = 0; } 547 548 virtual ~Persistent() 549 { 550 m_raw = 0; 551 } 552 553 template<typename U> 554 U* as() const 555 { 556 return static_cast<U*>(m_raw); 557 } 558 559 void trace(Visitor* visitor) 560 { 561 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent); 562#if ENABLE(GC_PROFILE_MARKING) 563 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName); 564#endif 565 visitor->mark(m_raw); 566 } 567 568 RawPtr<T> release() 569 { 570 RawPtr<T> result = m_raw; 571 m_raw = 0; 572 return result; 573 } 574 575 T& operator*() const { return *m_raw; } 576 577 bool operator!() const { return !m_raw; } 578 579 operator T*() const { return m_raw; } 580 operator RawPtr<T>() const { return m_raw; } 581 582 T* operator->() const { return *this; } 583 584 Persistent& operator=(const Persistent& other) 585 { 586 m_raw = other; 587 recordBacktrace(); 588 return *this; 589 } 590 591 template<typename U> 592 Persistent& operator=(const Persistent<U, RootsAccessor>& other) 593 { 594 m_raw = other; 595 recordBacktrace(); 596 return *this; 597 } 598 599 template<typename U> 600 Persistent& operator=(const Member<U>& other) 601 { 602 m_raw = other; 603 recordBacktrace(); 604 return *this; 605 } 606 607 template<typename U> 608 Persistent& operator=(const RawPtr<U>& other) 609 { 610 m_raw = other; 611 recordBacktrace(); 612 return *this; 613 } 614 615 T* get() const { return m_raw; } 616 617private: 618#if ENABLE(GC_PROFILE_MARKING) 619 void recordBacktrace() 620 { 621 if (m_raw) 622 m_tracingName = Heap::createBacktraceString(); 623 } 624 625 String m_tracingName; 626#else 627 inline void recordBacktrace() const { } 628#endif 629 T* m_raw; 630 631 friend class CrossThreadPersistent<T>; 632}; 633 634// Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 635// different from the construction thread. 636template<typename T> 637class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { 638 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); 639 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); 640public: 641 CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { } 642 643 using Persistent<T, GlobalPersistents>::operator=; 644}; 645 646// FIXME: derive affinity based on the collection. 647template<typename Collection, ThreadAffinity Affinity = AnyThread> 648class PersistentHeapCollectionBase 649 : public Collection 650 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > { 651 // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent 652 // heap collections are always allocated off-heap. This allows persistent collections to be used in 653 // DEFINE_STATIC_LOCAL et. al. 654 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 655public: 656 PersistentHeapCollectionBase() { } 657 658 template<typename OtherCollection> 659 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { } 660 661 void trace(Visitor* visitor) 662 { 663#if ENABLE(GC_PROFILE_MARKING) 664 visitor->setHostInfo(this, "PersistentHeapCollectionBase"); 665#endif 666 visitor->trace(*static_cast<Collection*>(this)); 667 } 668}; 669 670template< 671 typename KeyArg, 672 typename MappedArg, 673 typename HashArg = typename DefaultHash<KeyArg>::Hash, 674 typename KeyTraitsArg = HashTraits<KeyArg>, 675 typename MappedTraitsArg = HashTraits<MappedArg> > 676class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { }; 677 678template< 679 typename ValueArg, 680 typename HashArg = typename DefaultHash<ValueArg>::Hash, 681 typename TraitsArg = HashTraits<ValueArg> > 682class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { }; 683 684template< 685 typename ValueArg, 686 typename HashArg = typename DefaultHash<ValueArg>::Hash, 687 typename TraitsArg = HashTraits<ValueArg> > 688class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { }; 689 690template< 691 typename ValueArg, 692 size_t inlineCapacity = 0, 693 typename HashArg = typename DefaultHash<ValueArg>::Hash> 694class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { }; 695 696template<typename T, typename U, typename V> 697class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { }; 698 699template<typename T, size_t inlineCapacity = 0> 700class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > { 701public: 702 PersistentHeapVector() { } 703 704 template<size_t otherCapacity> 705 PersistentHeapVector(const HeapVector<T, otherCapacity>& other) 706 : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other) 707 { 708 } 709}; 710 711template<typename T, size_t inlineCapacity = 0> 712class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > { 713public: 714 PersistentHeapDeque() { } 715 716 template<size_t otherCapacity> 717 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) 718 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other) 719 { 720 } 721}; 722 723// Members are used in classes to contain strong pointers to other oilpan heap 724// allocated objects. 725// All Member fields of a class must be traced in the class' trace method. 726// During the mark phase of the GC all live objects are marked as live and 727// all Member fields of a live object will be traced marked as live as well. 728template<typename T> 729class Member { 730 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member); 731 WTF_DISALLOW_ZERO_ASSIGNMENT(Member); 732public: 733 Member() : m_raw(0) 734 { 735 } 736 737 Member(std::nullptr_t) : m_raw(0) 738 { 739 } 740 741 Member(T* raw) : m_raw(raw) 742 { 743 } 744 745 explicit Member(T& raw) : m_raw(&raw) 746 { 747 } 748 749 template<typename U> 750 Member(const RawPtr<U>& other) : m_raw(other.get()) 751 { 752 } 753 754 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) 755 { 756 } 757 758 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); } 759 760 template<typename U> 761 Member(const Persistent<U>& other) : m_raw(other) { } 762 763 Member(const Member& other) : m_raw(other) { } 764 765 template<typename U> 766 Member(const Member<U>& other) : m_raw(other) { } 767 768 T* release() 769 { 770 T* result = m_raw; 771 m_raw = 0; 772 return result; 773 } 774 775 template<typename U> 776 U* as() const 777 { 778 return static_cast<U*>(m_raw); 779 } 780 781 bool operator!() const { return !m_raw; } 782 783 operator T*() const { return m_raw; } 784 785 T* operator->() const { return m_raw; } 786 T& operator*() const { return *m_raw; } 787 template<typename U> 788 operator RawPtr<U>() const { return m_raw; } 789 790 template<typename U> 791 Member& operator=(const Persistent<U>& other) 792 { 793 m_raw = other; 794 return *this; 795 } 796 797 template<typename U> 798 Member& operator=(const Member<U>& other) 799 { 800 m_raw = other; 801 return *this; 802 } 803 804 template<typename U> 805 Member& operator=(U* other) 806 { 807 m_raw = other; 808 return *this; 809 } 810 811 template<typename U> 812 Member& operator=(RawPtr<U> other) 813 { 814 m_raw = other; 815 return *this; 816 } 817 818 Member& operator=(std::nullptr_t) 819 { 820 m_raw = 0; 821 return *this; 822 } 823 824 void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); } 825 826 T* get() const { return m_raw; } 827 828 void clear() { m_raw = 0; } 829 830 831protected: 832 void verifyTypeIsGarbageCollected() const 833 { 834 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember); 835 } 836 837 T* m_raw; 838 839 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; 840 friend class Visitor; 841}; 842 843template<typename T> 844class TraceTrait<Member<T> > { 845public: 846 static void trace(Visitor* visitor, void* self) 847 { 848 TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self)); 849 } 850}; 851 852// TraceTrait to allow compilation of trace method bodies when oilpan is disabled. 853// This should never be called, but is needed to compile. 854template<typename T> 855class TraceTrait<RefPtr<T> > { 856public: 857 static void trace(Visitor*, void*) 858 { 859 ASSERT_NOT_REACHED(); 860 } 861}; 862 863template<typename T> 864class TraceTrait<OwnPtr<T> > { 865public: 866 static void trace(Visitor* visitor, OwnPtr<T>* ptr) 867 { 868 ASSERT_NOT_REACHED(); 869 } 870}; 871 872template<typename T, bool needsTracing> 873struct TraceIfEnabled; 874 875template<typename T> 876struct TraceIfEnabled<T, false> { 877 static void trace(Visitor*, T*) { } 878}; 879 880template<typename T> 881struct TraceIfEnabled<T, true> { 882 static void trace(Visitor* visitor, T* t) 883 { 884 visitor->trace(*t); 885 } 886}; 887 888template <typename T> struct RemoveHeapPointerWrapperTypes { 889 typedef typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<T, Member>::Type, WeakMember>::Type, RawPtr>::Type Type; 890}; 891 892// FIXME: Oilpan: TraceIfNeeded should be implemented ala: 893// NeedsTracing<T>::value || IsWeakMember<T>::value. It should not need to test 894// raw pointer types. To remove these tests, we may need support for 895// instantiating a template with a RawPtrOrMember'ish template. 896template<typename T> 897struct TraceIfNeeded : public TraceIfEnabled<T, WTF::NeedsTracing<T>::value || blink::IsGarbageCollectedType<typename RemoveHeapPointerWrapperTypes<typename WTF::RemovePointer<T>::Type>::Type>::value> { }; 898 899// This trace trait for std::pair will null weak members if their referent is 900// collected. If you have a collection that contain weakness it does not remove 901// entries from the collection that contain nulled weak members. 902template<typename T, typename U> 903class TraceTrait<std::pair<T, U> > { 904public: 905 static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value; 906 static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value; 907 static void trace(Visitor* visitor, std::pair<T, U>* pair) 908 { 909 TraceIfEnabled<T, firstNeedsTracing>::trace(visitor, &pair->first); 910 TraceIfEnabled<U, secondNeedsTracing>::trace(visitor, &pair->second); 911 } 912}; 913 914// WeakMember is similar to Member in that it is used to point to other oilpan 915// heap allocated objects. 916// However instead of creating a strong pointer to the object, the WeakMember creates 917// a weak pointer, which does not keep the pointee alive. Hence if all pointers to 918// to a heap allocated object are weak the object will be garbage collected. At the 919// time of GC the weak pointers will automatically be set to null. 920template<typename T> 921class WeakMember : public Member<T> { 922 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember); 923 WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember); 924public: 925 WeakMember() : Member<T>() { } 926 927 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } 928 929 WeakMember(T* raw) : Member<T>(raw) { } 930 931 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } 932 933 template<typename U> 934 WeakMember(const Persistent<U>& other) : Member<T>(other) { } 935 936 template<typename U> 937 WeakMember(const Member<U>& other) : Member<T>(other) { } 938 939 template<typename U> 940 WeakMember& operator=(const Persistent<U>& other) 941 { 942 this->m_raw = other; 943 return *this; 944 } 945 946 template<typename U> 947 WeakMember& operator=(const Member<U>& other) 948 { 949 this->m_raw = other; 950 return *this; 951 } 952 953 template<typename U> 954 WeakMember& operator=(U* other) 955 { 956 this->m_raw = other; 957 return *this; 958 } 959 960 template<typename U> 961 WeakMember& operator=(const RawPtr<U>& other) 962 { 963 this->m_raw = other; 964 return *this; 965 } 966 967 WeakMember& operator=(std::nullptr_t) 968 { 969 this->m_raw = 0; 970 return *this; 971 } 972 973private: 974 T** cell() const { return const_cast<T**>(&this->m_raw); } 975 976 friend class Visitor; 977}; 978 979// Comparison operators between (Weak)Members and Persistents 980template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); } 981template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); } 982template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 983template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } 984template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); } 985template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } 986template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 987template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } 988 989// CPP-defined type names for the transition period where we want to 990// support both reference counting and garbage collection based on a 991// compile-time flag. 992// 993// C++11 template aliases were initially used (with clang only, not 994// with GCC nor MSVC.) However, supporting both CPP defines and 995// template aliases is problematic from outside a WebCore namespace 996// when Oilpan is disabled: e.g., 997// blink::RefCountedWillBeGarbageCollected as a template alias would 998// uniquely resolve from within any namespace, but if it is backed by 999// a CPP #define, it would expand to blink::RefCounted, and not the 1000// required WTF::RefCounted. 1001// 1002// Having the CPP expansion instead be fully namespace qualified, and the 1003// transition type be unqualified, would dually not work for template 1004// aliases. So, slightly unfortunately, fall back/down to the lowest 1005// commmon denominator of using CPP macros only. 1006#if ENABLE(OILPAN) 1007#define PassRefPtrWillBeRawPtr WTF::RawPtr 1008#define RefCountedWillBeGarbageCollected blink::GarbageCollected 1009#define RefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized 1010#define RefCountedWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected 1011#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized 1012#define ThreadSafeRefCountedWillBeGarbageCollected blink::GarbageCollected 1013#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized 1014#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected blink::ThreadSafeRefCountedGarbageCollected 1015#define PersistentWillBeMember blink::Member 1016#define CrossThreadPersistentWillBeMember blink::Member 1017#define RefPtrWillBePersistent blink::Persistent 1018#define RefPtrWillBeRawPtr WTF::RawPtr 1019#define RefPtrWillBeMember blink::Member 1020#define RefPtrWillBeWeakMember blink::WeakMember 1021#define RefPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent 1022#define RawPtrWillBeMember blink::Member 1023#define RawPtrWillBePersistent blink::Persistent 1024#define RawPtrWillBeWeakMember blink::WeakMember 1025#define OwnPtrWillBeMember blink::Member 1026#define OwnPtrWillBePersistent blink::Persistent 1027#define OwnPtrWillBeRawPtr WTF::RawPtr 1028#define PassOwnPtrWillBeRawPtr WTF::RawPtr 1029#define WeakPtrWillBeMember blink::Member 1030#define WeakPtrWillBeRawPtr WTF::RawPtr 1031#define WeakPtrWillBeMember blink::Member 1032#define WeakPtrWillBeWeakMember blink::WeakMember 1033#define NoBaseWillBeGarbageCollected blink::GarbageCollected 1034#define NoBaseWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized 1035#define NoBaseWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected 1036#define WillBeHeapHashMap blink::HeapHashMap 1037#define WillBePersistentHeapHashMap blink::PersistentHeapHashMap 1038#define WillBeHeapHashSet blink::HeapHashSet 1039#define WillBePersistentHeapHashSet blink::PersistentHeapHashSet 1040#define WillBeHeapLinkedHashSet blink::HeapLinkedHashSet 1041#define WillBePersistentHeapLinkedHashSet blink::PersistentHeapLinkedHashSet 1042#define WillBeHeapListHashSet blink::HeapListHashSet 1043#define WillBePersistentHeapListHashSet blink::PersistentHeapListHashSet 1044#define WillBeHeapVector blink::HeapVector 1045#define WillBePersistentHeapVector blink::PersistentHeapVector 1046#define WillBeHeapDeque blink::HeapDeque 1047#define WillBePersistentHeapDeque blink::PersistentHeapDeque 1048#define WillBeHeapHashCountedSet blink::HeapHashCountedSet 1049#define WillBePersistentHeapHashCountedSet blink::PersistentHeapHashCountedSet 1050#define WillBeGarbageCollectedMixin blink::GarbageCollectedMixin 1051#define WillBeHeapSupplement blink::HeapSupplement 1052#define WillBeHeapSupplementable blink::HeapSupplementable 1053#define WillBeHeapTerminatedArray blink::HeapTerminatedArray 1054#define WillBeHeapTerminatedArrayBuilder blink::HeapTerminatedArrayBuilder 1055#define WillBeHeapLinkedStack blink::HeapLinkedStack 1056#define PersistentHeapHashSetWillBeHeapHashSet blink::HeapHashSet 1057#define PersistentHeapDequeWillBeHeapDeque blink::HeapDeque 1058#define PersistentHeapVectorWillBeHeapVector blink::HeapVector 1059 1060template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) 1061{ 1062 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1063 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 1064 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 1065 COMPILE_ASSERT(notRefCounted, youMustAdopt); 1066 return PassRefPtrWillBeRawPtr<T>(ptr); 1067} 1068 1069template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) 1070{ 1071 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1072 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 1073 return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr)); 1074} 1075 1076template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) 1077{ 1078 static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, ThreadSafeRefCountedGarbageCollected>::value; 1079 COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop); 1080 return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr)); 1081} 1082 1083template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) 1084{ 1085 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1086 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 1087 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 1088 COMPILE_ASSERT(notRefCounted, youMustAdopt); 1089 return PassOwnPtrWillBeRawPtr<T>(ptr); 1090} 1091 1092template<typename T> T* adoptPtrWillBeRefCountedGarbageCollected(T* ptr) 1093{ 1094 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1095 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 1096 return adoptRefCountedGarbageCollected(ptr); 1097} 1098 1099template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr) 1100{ 1101 static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1102 static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value; 1103 COMPILE_ASSERT(notRefCountedGarbageCollected, useAdoptRefCountedWillBeRefCountedGarbageCollected); 1104 COMPILE_ASSERT(notRefCounted, youMustAdopt); 1105 return ptr; 1106} 1107 1108#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled. 1109#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 1110#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 1111#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing 1112 1113#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \ 1114 static type* name = (new Persistent<type>(arguments))->get(); 1115 1116#else // !ENABLE(OILPAN) 1117 1118template<typename T> 1119class DummyBase { 1120public: 1121 DummyBase() { } 1122 ~DummyBase() { } 1123}; 1124 1125#define PassRefPtrWillBeRawPtr WTF::PassRefPtr 1126#define RefCountedWillBeGarbageCollected WTF::RefCounted 1127#define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted 1128#define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted 1129#define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::RefCountedGarbageCollected 1130#define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted 1131#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted 1132#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted 1133#define PersistentWillBeMember blink::Persistent 1134#define CrossThreadPersistentWillBeMember blink::CrossThreadPersistent 1135#define RefPtrWillBePersistent WTF::RefPtr 1136#define RefPtrWillBeRawPtr WTF::RefPtr 1137#define RefPtrWillBeMember WTF::RefPtr 1138#define RefPtrWillBeWeakMember WTF::RefPtr 1139#define RefPtrWillBeCrossThreadPersistent WTF::RefPtr 1140#define RawPtrWillBeMember WTF::RawPtr 1141#define RawPtrWillBePersistent WTF::RawPtr 1142#define RawPtrWillBeWeakMember WTF::RawPtr 1143#define OwnPtrWillBeMember WTF::OwnPtr 1144#define OwnPtrWillBePersistent WTF::OwnPtr 1145#define OwnPtrWillBeRawPtr WTF::OwnPtr 1146#define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr 1147#define WeakPtrWillBeMember WTF::WeakPtr 1148#define WeakPtrWillBeRawPtr WTF::WeakPtr 1149#define WeakPtrWillBeMember WTF::WeakPtr 1150#define WeakPtrWillBeWeakMember WTF::WeakPtr 1151#define NoBaseWillBeGarbageCollected blink::DummyBase 1152#define NoBaseWillBeGarbageCollectedFinalized blink::DummyBase 1153#define NoBaseWillBeRefCountedGarbageCollected blink::DummyBase 1154#define WillBeHeapHashMap WTF::HashMap 1155#define WillBePersistentHeapHashMap WTF::HashMap 1156#define WillBeHeapHashSet WTF::HashSet 1157#define WillBePersistentHeapHashSet WTF::HashSet 1158#define WillBeHeapLinkedHashSet WTF::LinkedHashSet 1159#define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet 1160#define WillBeHeapListHashSet WTF::ListHashSet 1161#define WillBePersistentListHeapHashSet WTF::ListHashSet 1162#define WillBeHeapVector WTF::Vector 1163#define WillBePersistentHeapVector WTF::Vector 1164#define WillBeHeapDeque WTF::Deque 1165#define WillBePersistentHeapDeque WTF::Deque 1166#define WillBeHeapHashCountedSet WTF::HashCountedSet 1167#define WillBePersistentHeapHashCountedSet WTF::HashCountedSet 1168#define WillBeGarbageCollectedMixin blink::DummyBase<void> 1169#define WillBeHeapSupplement blink::Supplement 1170#define WillBeHeapSupplementable blink::Supplementable 1171#define WillBeHeapTerminatedArray WTF::TerminatedArray 1172#define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder 1173#define WillBeHeapLinkedStack WTF::LinkedStack 1174#define PersistentHeapHashSetWillBeHeapHashSet blink::PersistentHeapHashSet 1175#define PersistentHeapDequeWillBeHeapDeque blink::PersistentHeapDeque 1176#define PersistentHeapVectorWillBeHeapVector blink::PersistentHeapVector 1177 1178template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); } 1179template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 1180template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 1181template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); } 1182template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); } 1183 1184template<typename T> T* adoptRefCountedGarbageCollectedWillBeNoop(T* ptr) 1185{ 1186 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCountedGarbageCollected>::value; 1187 COMPILE_ASSERT(isRefCountedGarbageCollected, useAdoptRefWillBeNoop); 1188 return adoptRefCountedGarbageCollected(ptr); 1189} 1190 1191 1192#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED 1193#define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \ 1194 public: \ 1195 ~type(); \ 1196 private: 1197#define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \ 1198 public: \ 1199 virtual ~type(); \ 1200 private: 1201 1202#define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \ 1203 type::~type() { } 1204 1205#define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \ 1206 DEFINE_STATIC_REF(type, name, arguments) 1207 1208#endif // ENABLE(OILPAN) 1209 1210} // namespace blink 1211 1212namespace WTF { 1213 1214template <typename T> struct VectorTraits<blink::Member<T> > : VectorTraitsBase<blink::Member<T> > { 1215 static const bool needsDestruction = false; 1216 static const bool canInitializeWithMemset = true; 1217 static const bool canMoveWithMemcpy = true; 1218}; 1219 1220template <typename T> struct VectorTraits<blink::WeakMember<T> > : VectorTraitsBase<blink::WeakMember<T> > { 1221 static const bool needsDestruction = false; 1222 static const bool canInitializeWithMemset = true; 1223 static const bool canMoveWithMemcpy = true; 1224}; 1225 1226template <typename T> struct VectorTraits<blink::HeapVector<T, 0> > : VectorTraitsBase<blink::HeapVector<T, 0> > { 1227 static const bool needsDestruction = false; 1228 static const bool canInitializeWithMemset = true; 1229 static const bool canMoveWithMemcpy = true; 1230}; 1231 1232template <typename T> struct VectorTraits<blink::HeapDeque<T, 0> > : VectorTraitsBase<blink::HeapDeque<T, 0> > { 1233 static const bool needsDestruction = false; 1234 static const bool canInitializeWithMemset = true; 1235 static const bool canMoveWithMemcpy = true; 1236}; 1237 1238template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapVector<T, inlineCapacity> > : VectorTraitsBase<blink::HeapVector<T, inlineCapacity> > { 1239 static const bool needsDestruction = VectorTraits<T>::needsDestruction; 1240 static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset; 1241 static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy; 1242}; 1243 1244template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<blink::HeapDeque<T, inlineCapacity> > { 1245 static const bool needsDestruction = VectorTraits<T>::needsDestruction; 1246 static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset; 1247 static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy; 1248}; 1249 1250template<typename T> struct HashTraits<blink::Member<T> > : SimpleClassHashTraits<blink::Member<T> > { 1251 static const bool needsDestruction = false; 1252 // FIXME: The distinction between PeekInType and PassInType is there for 1253 // the sake of the reference counting handles. When they are gone the two 1254 // types can be merged into PassInType. 1255 // FIXME: Implement proper const'ness for iterator types. Requires support 1256 // in the marking Visitor. 1257 typedef RawPtr<T> PeekInType; 1258 typedef RawPtr<T> PassInType; 1259 typedef blink::Member<T>* IteratorGetType; 1260 typedef const blink::Member<T>* IteratorConstGetType; 1261 typedef blink::Member<T>& IteratorReferenceType; 1262 typedef T* const IteratorConstReferenceType; 1263 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; } 1264 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); } 1265 // FIXME: Similarly, there is no need for a distinction between PeekOutType 1266 // and PassOutType without reference counting. 1267 typedef T* PeekOutType; 1268 typedef T* PassOutType; 1269 1270 template<typename U> 1271 static void store(const U& value, blink::Member<T>& storage) { storage = value; } 1272 1273 static PeekOutType peek(const blink::Member<T>& value) { return value; } 1274 static PassOutType passOut(const blink::Member<T>& value) { return value; } 1275}; 1276 1277template<typename T> struct HashTraits<blink::WeakMember<T> > : SimpleClassHashTraits<blink::WeakMember<T> > { 1278 static const bool needsDestruction = false; 1279 // FIXME: The distinction between PeekInType and PassInType is there for 1280 // the sake of the reference counting handles. When they are gone the two 1281 // types can be merged into PassInType. 1282 // FIXME: Implement proper const'ness for iterator types. Requires support 1283 // in the marking Visitor. 1284 typedef RawPtr<T> PeekInType; 1285 typedef RawPtr<T> PassInType; 1286 typedef blink::WeakMember<T>* IteratorGetType; 1287 typedef const blink::WeakMember<T>* IteratorConstGetType; 1288 typedef blink::WeakMember<T>& IteratorReferenceType; 1289 typedef T* const IteratorConstReferenceType; 1290 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; } 1291 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); } 1292 // FIXME: Similarly, there is no need for a distinction between PeekOutType 1293 // and PassOutType without reference counting. 1294 typedef T* PeekOutType; 1295 typedef T* PassOutType; 1296 1297 template<typename U> 1298 static void store(const U& value, blink::WeakMember<T>& storage) { storage = value; } 1299 1300 static PeekOutType peek(const blink::WeakMember<T>& value) { return value; } 1301 static PassOutType passOut(const blink::WeakMember<T>& value) { return value; } 1302 static bool traceInCollection(blink::Visitor* visitor, blink::WeakMember<T>& weakMember, ShouldWeakPointersBeMarkedStrongly strongify) 1303 { 1304 if (strongify == WeakPointersActStrong) { 1305 visitor->trace(reinterpret_cast<blink::Member<T>&>(weakMember)); // Strongified visit. 1306 return false; 1307 } 1308 return !visitor->isAlive(weakMember); 1309 } 1310}; 1311 1312template<typename T> struct PtrHash<blink::Member<T> > : PtrHash<T*> { 1313 template<typename U> 1314 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); } 1315 static bool equal(T* a, const blink::Member<T>& b) { return a == b; } 1316 static bool equal(const blink::Member<T>& a, T* b) { return a == b; } 1317 template<typename U, typename V> 1318 static bool equal(const U& a, const V& b) { return a == b; } 1319}; 1320 1321template<typename T> struct PtrHash<blink::WeakMember<T> > : PtrHash<blink::Member<T> > { 1322}; 1323 1324template<typename P> struct PtrHash<blink::Persistent<P> > : PtrHash<P*> { 1325 using PtrHash<P*>::hash; 1326 static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); } 1327 using PtrHash<P*>::equal; 1328 static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; } 1329 static bool equal(P* a, const RefPtr<P>& b) { return a == b; } 1330 static bool equal(const RefPtr<P>& a, P* b) { return a == b; } 1331}; 1332 1333// PtrHash is the default hash for hash tables with members. 1334template<typename T> struct DefaultHash<blink::Member<T> > { 1335 typedef PtrHash<blink::Member<T> > Hash; 1336}; 1337 1338template<typename T> struct DefaultHash<blink::WeakMember<T> > { 1339 typedef PtrHash<blink::WeakMember<T> > Hash; 1340}; 1341 1342template<typename T> struct DefaultHash<blink::Persistent<T> > { 1343 typedef PtrHash<blink::Persistent<T> > Hash; 1344}; 1345 1346template<typename T> 1347struct NeedsTracing<blink::Member<T> > { 1348 static const bool value = true; 1349}; 1350 1351template<typename T> 1352struct IsWeak<blink::WeakMember<T> > { 1353 static const bool value = true; 1354}; 1355 1356template<typename T> inline T* getPtr(const blink::Member<T>& p) 1357{ 1358 return p.get(); 1359} 1360 1361template<typename T> inline T* getPtr(const blink::Persistent<T>& p) 1362{ 1363 return p.get(); 1364} 1365 1366template<typename T, size_t inlineCapacity> 1367struct NeedsTracing<ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity> > *> { 1368 // All heap allocated node pointers need visiting to keep the nodes alive, 1369 // regardless of whether they contain pointers to other heap allocated 1370 // objects. 1371 static const bool value = true; 1372}; 1373 1374// For wtf/Functional.h 1375template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; 1376 1377template<typename T> 1378struct PointerParamStorageTraits<T*, false> { 1379 typedef T* StorageType; 1380 1381 static StorageType wrap(T* value) { return value; } 1382 static T* unwrap(const StorageType& value) { return value; } 1383}; 1384 1385template<typename T> 1386struct PointerParamStorageTraits<T*, true> { 1387 typedef blink::CrossThreadPersistent<T> StorageType; 1388 1389 static StorageType wrap(T* value) { return value; } 1390 static T* unwrap(const StorageType& value) { return value.get(); } 1391}; 1392 1393template<typename T> 1394struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> { 1395}; 1396 1397template<typename T> 1398struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> { 1399}; 1400 1401} // namespace WTF 1402 1403#endif 1404