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 blink { 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 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 112 template<typename T> class Member; 113 114 class PersistentNode { 115 public: 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 141 protected: 142 TraceCallback m_trace; 143 144 private: 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 154 const int wrapperPersistentsPerRegion = 256; 155 const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3); 156 const size_t wrapperPersistentLiveBitMask = 1; 157 158 class WrapperPersistentNode { 159 ALLOW_ONLY_INLINE_ALLOCATION(); 160 WTF_MAKE_NONCOPYABLE(WrapperPersistentNode); 161 public: 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 174 protected: 175 WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { } 176 WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_regionOffset(regionOffset) { } 177 178 private: 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 202 protected: 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 215 template<typename T> 216 class WrapperPersistent FINAL : public WrapperPersistentNode { 217 ALLOW_ONLY_INLINE_ALLOCATION(); 218 public: 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 227 private: 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 238 class PLATFORM_EXPORT WrapperPersistentRegion { 239 WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion); 240 public: 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 293 private: 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 320 template<typename T> 321 WrapperPersistent<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 340 void 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. 349 template<ThreadAffinity Affinity> 350 class ThreadLocalPersistents { 351 public: 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 360 private: 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. 367 class GlobalPersistents { 368 public: 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. 382 template<typename RootsAccessor, typename Owner> 383 class PersistentBase : public PersistentNode { 384 public: 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 396 protected: 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) 431 private: 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. 438 class PersistentAnchor : public PersistentNode { 439 public: 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 462 private: 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 483 template<typename T> 484 class 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. 500 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ > 501 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > { 502 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); 503 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); 504 public: 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 617 private: 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. 636 template<typename T> 637 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { 638 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); 639 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); 640 public: 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. 647 template<typename Collection, ThreadAffinity Affinity = AnyThread> 648 class 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); 655 public: 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 670 template< 671 typename KeyArg, 672 typename MappedArg, 673 typename HashArg = typename DefaultHash<KeyArg>::Hash, 674 typename KeyTraitsArg = HashTraits<KeyArg>, 675 typename MappedTraitsArg = HashTraits<MappedArg> > 676 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { }; 677 678 template< 679 typename ValueArg, 680 typename HashArg = typename DefaultHash<ValueArg>::Hash, 681 typename TraitsArg = HashTraits<ValueArg> > 682 class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { }; 683 684 template< 685 typename ValueArg, 686 typename HashArg = typename DefaultHash<ValueArg>::Hash, 687 typename TraitsArg = HashTraits<ValueArg> > 688 class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { }; 689 690 template< 691 typename ValueArg, 692 size_t inlineCapacity = 0, 693 typename HashArg = typename DefaultHash<ValueArg>::Hash> 694 class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { }; 695 696 template<typename T, typename U, typename V> 697 class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { }; 698 699 template<typename T, size_t inlineCapacity = 0> 700 class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > { 701 public: 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 711 template<typename T, size_t inlineCapacity = 0> 712 class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > { 713 public: 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. 728 template<typename T> 729 class Member { 730 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Member); 731 WTF_DISALLOW_ZERO_ASSIGNMENT(Member); 732 public: 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 831 protected: 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 843 template<typename T> 844 class TraceTrait<Member<T> > { 845 public: 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. 854 template<typename T> 855 class TraceTrait<RefPtr<T> > { 856 public: 857 static void trace(Visitor*, void*) 858 { 859 ASSERT_NOT_REACHED(); 860 } 861 }; 862 863 template<typename T> 864 class TraceTrait<OwnPtr<T> > { 865 public: 866 static void trace(Visitor* visitor, OwnPtr<T>* ptr) 867 { 868 ASSERT_NOT_REACHED(); 869 } 870 }; 871 872 template<typename T, bool needsTracing> 873 struct TraceIfEnabled; 874 875 template<typename T> 876 struct TraceIfEnabled<T, false> { 877 static void trace(Visitor*, T*) { } 878 }; 879 880 template<typename T> 881 struct TraceIfEnabled<T, true> { 882 static void trace(Visitor* visitor, T* t) 883 { 884 visitor->trace(*t); 885 } 886 }; 887 888 template <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. 896 template<typename T> 897 struct 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. 902 template<typename T, typename U> 903 class TraceTrait<std::pair<T, U> > { 904 public: 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. 920 template<typename T> 921 class WeakMember : public Member<T> { 922 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(WeakMember); 923 WTF_DISALLOW_ZERO_ASSIGNMENT(WeakMember); 924 public: 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 973 private: 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 980 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); } 981 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); } 982 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 983 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } 984 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); } 985 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } 986 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); } 987 template<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 1060 template<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 1069 template<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 1076 template<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 1083 template<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 1092 template<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 1099 template<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 1118 template<typename T> 1119 class DummyBase { 1120 public: 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 1178 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); } 1179 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 1180 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } 1181 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); } 1182 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeRefCountedGarbageCollected(T* ptr) { return adoptPtr(ptr); } 1183 1184 template<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 1212 namespace WTF { 1213 1214 template <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 1220 template <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 1226 template <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 1232 template <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 1238 template <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 1244 template <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 1250 template<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 1277 template<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 1312 template<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 1321 template<typename T> struct PtrHash<blink::WeakMember<T> > : PtrHash<blink::Member<T> > { 1322 }; 1323 1324 template<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. 1334 template<typename T> struct DefaultHash<blink::Member<T> > { 1335 typedef PtrHash<blink::Member<T> > Hash; 1336 }; 1337 1338 template<typename T> struct DefaultHash<blink::WeakMember<T> > { 1339 typedef PtrHash<blink::WeakMember<T> > Hash; 1340 }; 1341 1342 template<typename T> struct DefaultHash<blink::Persistent<T> > { 1343 typedef PtrHash<blink::Persistent<T> > Hash; 1344 }; 1345 1346 template<typename T> 1347 struct NeedsTracing<blink::Member<T> > { 1348 static const bool value = true; 1349 }; 1350 1351 template<typename T> 1352 struct IsWeak<blink::WeakMember<T> > { 1353 static const bool value = true; 1354 }; 1355 1356 template<typename T> inline T* getPtr(const blink::Member<T>& p) 1357 { 1358 return p.get(); 1359 } 1360 1361 template<typename T> inline T* getPtr(const blink::Persistent<T>& p) 1362 { 1363 return p.get(); 1364 } 1365 1366 template<typename T, size_t inlineCapacity> 1367 struct 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 1375 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; 1376 1377 template<typename T> 1378 struct 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 1385 template<typename T> 1386 struct 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 1393 template<typename T> 1394 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> { 1395 }; 1396 1397 template<typename T> 1398 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> { 1399 }; 1400 1401 } // namespace WTF 1402 1403 #endif 1404