2 * Copyright (C) 2014 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
34 #include "heap/Heap.h"
35 #include "heap/ThreadState.h"
36 #include "heap/Visitor.h"
39 #include "wtf/RefCounted.h"
43 template<typename T> class Member;
45 class PersistentNode {
47 explicit PersistentNode(TraceCallback trace) : m_trace(trace) { }
49 virtual ~PersistentNode() { }
51 // Ideally the trace method should be virtual and automatically dispatch
52 // to the most specific implementation. However having a virtual method
53 // on PersistentNode leads to too eager template instantiation with MSVC
54 // which leads to include cycles.
55 // Instead we call the constructor with a TraceCallback which knows the
56 // type of the most specific child and calls trace directly. See
57 // TraceMethodDelegate in Visitor.h for how this is done.
58 void trace(Visitor* visitor)
60 m_trace(visitor, this);
64 TraceCallback m_trace;
67 PersistentNode* m_next;
68 PersistentNode* m_prev;
70 template<ThreadAffinity affinity, typename Owner> friend class PersistentBase;
71 friend class PersistentAnchor;
72 friend class ThreadState;
75 template<ThreadAffinity Affinity, typename Owner>
76 class PersistentBase : public PersistentNode {
81 m_threadState->checkThread();
83 m_next->m_prev = m_prev;
84 m_prev->m_next = m_next;
88 inline PersistentBase()
89 : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
91 , m_threadState(state())
95 m_threadState->checkThread();
97 ThreadState* threadState = state();
98 m_prev = threadState->roots();
99 m_next = threadState->roots()->m_next;
100 threadState->roots()->m_next = this;
101 m_next->m_prev = this;
104 inline explicit PersistentBase(const PersistentBase& otherref)
105 : PersistentNode(otherref.m_trace)
107 , m_threadState(state())
111 m_threadState->checkThread();
113 ASSERT(otherref.m_threadState == m_threadState);
114 PersistentBase* other = const_cast<PersistentBase*>(&otherref);
116 m_next = other->m_next;
117 other->m_next = this;
118 m_next->m_prev = this;
121 inline PersistentBase& operator=(const PersistentBase& otherref)
126 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
130 ThreadState* m_threadState;
134 // A dummy Persistent handle that ensures the list of persistents is never null.
135 // This removes a test from a hot path.
136 class PersistentAnchor : public PersistentNode {
138 void trace(Visitor*) { }
141 virtual ~PersistentAnchor() { }
142 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
148 friend class ThreadState;
151 // Persistent handles are used to store pointers into the
152 // managed heap. As long as the Persistent handle is alive
153 // the GC will keep the object pointed to alive. Persistent
154 // handles can be stored in objects and they are not scoped.
155 // Persistent handles must not be used to contain pointers
156 // between objects that are in the managed heap. They are only
157 // meant to point to managed heap objects from variables/members
158 // outside the managed heap.
160 // A Persistent is always a GC root from the point of view of
161 // the garbage collector.
163 class Persistent : public PersistentBase<ThreadingTrait<T>::Affinity, Persistent<T> > {
165 Persistent() : m_raw(0) { }
167 Persistent(T* raw) : m_raw(raw) { }
169 Persistent(std::nullptr_t) : m_raw(0) { }
171 Persistent(const Persistent& other) : m_raw(other) { }
174 Persistent(const Persistent<U>& other) : m_raw(other) { }
177 Persistent(const Member<U>& other) : m_raw(other) { }
180 Persistent(const Ptr<U>& other) : m_raw(other.get()) { }
183 Persistent& operator=(U* other)
189 virtual ~Persistent()
197 return static_cast<U*>(m_raw);
200 void trace(Visitor* visitor) { visitor->mark(m_raw); }
209 T& operator*() const { return *m_raw; }
211 bool operator!() const { return !m_raw; }
213 operator T*() const { return m_raw; }
214 operator Ptr<T>() const { return m_raw; }
216 T* operator->() const { return *this; }
218 Persistent& operator=(std::nullptr_t)
224 Persistent& operator=(const Persistent& other)
231 Persistent& operator=(const Persistent<U>& other)
238 Persistent& operator=(const Member<U>& other)
244 T* get() const { return m_raw; }
250 // Members are used in classes to contain strong pointers to other oilpan heap
251 // allocated objects.
252 // All Member fields of a class must be traced in the class' trace method.
253 // During the mark phase of the GC all live objects are marked as live and
254 // all Member fields of a live object will be traced marked as live as well.
258 Member() : m_raw(0) { }
260 Member(T* raw) : m_raw(raw) { }
262 Member(std::nullptr_t) : m_raw(0) { }
264 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) { }
266 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
269 Member(const Persistent<U>& other) : m_raw(other) { }
271 Member(const Member& other) : m_raw(other) { }
274 Member(const Member<U>& other) : m_raw(other) { }
286 return static_cast<U*>(m_raw);
289 bool operator!() const { return !m_raw; }
291 operator T*() const { return m_raw; }
293 T* operator->() const { return m_raw; }
294 T& operator*() const { return *m_raw; }
296 Member& operator=(std::nullptr_t)
303 Member& operator=(const Persistent<U>& other)
309 Member& operator=(const Member& other)
316 Member& operator=(const Member<U>& other)
323 Member& operator=(U* other)
329 void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
331 T* get() const { return m_raw; }
336 template<bool x, bool y, bool z, typename U, typename V> friend struct CollectionBackingTraceTrait;
340 class TraceTrait<Member<T> > {
342 static void trace(Visitor* visitor, void* self)
344 TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
348 // WeakMember is similar to Member in that it is used to point to other oilpan
349 // heap allocated objects.
350 // However instead of creating a strong pointer to the object, the WeakMember creates
351 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to
352 // to a heap allocated object are weak the object will be garbage collected. At the
353 // time of GC the weak pointers will automatically be set to null.
355 class WeakMember : public Member<T> {
357 WeakMember() : Member<T>() { }
359 WeakMember(T* raw) : Member<T>(raw) { }
361 WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
363 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
366 WeakMember(const Persistent<U>& other) : Member<T>(other) { }
369 WeakMember(const Member<U>& other) : Member<T>(other) { }
371 WeakMember& operator=(std::nullptr_t)
378 WeakMember& operator=(const Persistent<U>& other)
385 WeakMember& operator=(const Member<U>& other)
392 WeakMember& operator=(U* other)
399 T** cell() const { return const_cast<T**>(&this->m_raw); }
401 friend class Visitor;
404 // Comparison operators between (Weak)Members and Persistents
405 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
406 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
407 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
408 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
409 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
410 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
411 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
412 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
414 // Template aliases for the transition period where we want to support
415 // both reference counting and garbage collection based on a
416 // compile-time flag.
418 // With clang we can use c++11 template aliases which is really what
419 // we want. For GCC and MSVC we simulate the template aliases with
420 // stylized macros until we can use template aliases.
424 template<typename T> using PassRefPtrWillBePtr = Ptr<T>;
425 template<typename T> using RefCountedWillBeGarbageCollected = GarbageCollected<T>;
426 template<typename T> using RefCountedWillBeGarbageCollectedFinalized = GarbageCollectedFinalized<T>;
427 template<typename T> using RefPtrWillBePersistent = Persistent<T>;
428 template<typename T> using RefPtrWillBePtr = Ptr<T>;
429 template<typename T> using RefPtrWillBeMember = Member<T>;
430 template<typename T> using PtrWillBeMember = Member<T>;
431 template<typename T> using PtrWillBeWeakMember = WeakMember<T>;
432 template<typename T> using OwnPtrWillBeMember = Member<T>;
433 template<typename T> using PassOwnPtrWillBePtr = Ptr<T>;
434 template<typename T> using NoBaseWillBeGarbageCollected = GarbageCollected<T>;
435 template<typename T> using NoBaseWillBeGarbageCollectedFinalized = GarbageCollectedFinalized<T>;
436 #else // !COMPILER(CLANG)
437 #define PassRefPtrWillBePtr Ptr
438 #define RefCountedWillBeGarbageCollected GarbageCollected
439 #define RefCountedWillBeGarbageCollectedFinalized GarbageCollectedFinalized
440 #define RefPtrWillBePersistent Persistent
441 #define RefPtrWillBePtr Ptr
442 #define RefPtrWillBeMember Member
443 #define PtrWillBeMember Member
444 #define PtrWillBeWeakMember WeakMember
445 #define OwnPtrWillBeMember Member
446 #define PassOwnPtrWillBePtr Ptr
447 #define NoBaseWillBeGarbageCollected GarbageCollected
448 #define NoBaseWillBeGarbageCollectedFinalized GarbageCollectedFinalized
449 #endif // COMPILER(CLANG)
451 template<typename T> PassRefPtrWillBePtr<T> adoptRefWillBeNoop(T* ptr) { return PassRefPtrWillBePtr<T>(ptr); }
452 template<typename T> PassOwnPtrWillBePtr<T> adoptPtrWillBeNoop(T* ptr) { return PassOwnPtrWillBePtr<T>(ptr); }
454 #else // !ENABLE(OILPAN)
464 template<typename T> using PassRefPtrWillBePtr = PassRefPtr<T>;
465 template<typename T> using RefCountedWillBeGarbageCollected = RefCounted<T>;
466 template<typename T> using RefCountedWillBeGarbageCollectedFinalized = RefCounted<T>;
467 template<typename T> using RefPtrWillBePersistent = RefPtr<T>;
468 template<typename T> using RefPtrWillBePtr = RefPtr<T>;
469 template<typename T> using RefPtrWillBeMember = RefPtr<T>;
470 template<typename T> using PtrWillBeMember = Ptr<T>;
471 template<typename T> using PtrWillBeWeakMember = Ptr<T>;
472 template<typename T> using OwnPtrWillBeMember = OwnPtr<T>;
473 template<typename T> using PassOwnPtrWillBePtr = PassOwnPtr<T>;
474 template<typename T> using NoBaseWillBeGarbageCollected = DummyBase<T>;
475 template<typename T> using NoBaseWillBeGarbageCollectedFinalized = DummyBase<T>;
476 #else // !COMPILER(CLANG)
477 #define PassRefPtrWillBePtr PassRefPtr
478 #define RefCountedWillBeGarbageCollected RefCounted
479 #define RefCountedWillBeGarbageCollectedFinalized RefCounted
480 #define RefPtrWillBePersistent RefPtr
481 #define RefPtrWillBePtr RefPtr
482 #define RefPtrWillBeMember RefPtr
483 #define PtrWillBeMember Ptr
484 #define PtrWillBeWeakMember Ptr
485 #define OwnPtrWillBeMember OwnPtr
486 #define PassOwnPtrWillBePtr PassOwnPtr
487 #define NoBaseWillBeGarbageCollected DummyBase
488 #define NoBaseWillBeGarbageCollectedFinalized DummyBase
489 #endif // COMPILER(CLANG)
491 template<typename T> PassRefPtrWillBePtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
492 template<typename T> PassOwnPtrWillBePtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
494 #endif // ENABLE(OILPAN)
496 } // namespace WebCore
500 template <typename T> struct VectorTraits<WebCore::Member<T> > : VectorTraitsBase<false, WebCore::Member<T> > {
501 static const bool needsDestruction = false;
502 static const bool canInitializeWithMemset = true;
503 static const bool canMoveWithMemcpy = true;
506 template <typename T> struct VectorTraits<WebCore::WeakMember<T> > : VectorTraitsBase<false, WebCore::WeakMember<T> > {
507 static const bool needsDestruction = false;
508 static const bool canInitializeWithMemset = true;
509 static const bool canMoveWithMemcpy = true;
512 template<typename T> struct HashTraits<WebCore::Member<T> > : SimpleClassHashTraits<WebCore::Member<T> > {
513 static const bool needsDestruction = false;
514 // FIXME: The distinction between PeekInType and PassInType is there for
515 // the sake of the reference counting handles. When they are gone the two
516 // types can be merged into PassInType.
517 // FIXME: Implement proper const'ness for iterator types. Requires support
518 // in the marking Visitor.
519 typedef T* PeekInType;
520 typedef T* PassInType;
521 typedef T* IteratorGetType;
522 typedef T* IteratorConstGetType;
523 typedef T* IteratorReferenceType;
524 typedef T* IteratorConstReferenceType;
525 static IteratorConstGetType getToConstGetConversion(const WebCore::Member<T>* x) { return x->get(); }
526 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x; }
527 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x; }
528 // FIXME: Similarly, there is no need for a distinction between PeekOutType
529 // and PassOutType without reference counting.
530 typedef T* PeekOutType;
531 typedef T* PassOutType;
534 static void store(const U& value, WebCore::Member<T>& storage) { storage = value; }
536 static PeekOutType peek(const WebCore::Member<T>& value) { return value; }
537 static PassOutType passOut(const WebCore::Member<T>& value) { return value; }
540 template<typename T> struct HashTraits<WebCore::WeakMember<T> > : SimpleClassHashTraits<WebCore::WeakMember<T> > {
541 static const bool needsDestruction = false;
542 // FIXME: The distinction between PeekInType and PassInType is there for
543 // the sake of the reference counting handles. When they are gone the two
544 // types can be merged into PassInType.
545 // FIXME: Implement proper const'ness for iterator types. Requires support
546 // in the marking Visitor.
547 typedef T* PeekInType;
548 typedef T* PassInType;
549 typedef T* IteratorGetType;
550 typedef T* IteratorConstGetType;
551 typedef T* IteratorReferenceType;
552 typedef T* IteratorConstReferenceType;
553 static IteratorConstGetType getToConstGetConversion(const WebCore::WeakMember<T>* x) { return x->get(); }
554 static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x; }
555 static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x; }
556 // FIXME: Similarly, there is no need for a distinction between PeekOutType
557 // and PassOutType without reference counting.
558 typedef T* PeekOutType;
559 typedef T* PassOutType;
562 static void store(const U& value, WebCore::WeakMember<T>& storage) { storage = value; }
564 static PeekOutType peek(const WebCore::WeakMember<T>& value) { return value; }
565 static PassOutType passOut(const WebCore::WeakMember<T>& value) { return value; }
568 template<typename T> struct PtrHash<WebCore::Member<T> > : PtrHash<T*> {
570 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); }
571 static bool equal(T* a, const WebCore::Member<T>& b) { return a == b; }
572 static bool equal(const WebCore::Member<T>& a, T* b) { return a == b; }
573 template<typename U, typename V>
574 static bool equal(const U& a, const V& b) { return a == b; }
577 template<typename T> struct PtrHash<WebCore::WeakMember<T> > : PtrHash<WebCore::Member<T> > {
580 // PtrHash is the default hash for hash tables with members.
581 template<typename T> struct DefaultHash<WebCore::Member<T> > {
582 typedef PtrHash<WebCore::Member<T> > Hash;
585 template<typename T> struct DefaultHash<WebCore::WeakMember<T> > {
586 typedef PtrHash<WebCore::WeakMember<T> > Hash;
590 struct NeedsTracing<WebCore::Member<T> > {
591 static const bool value = true;
595 struct IsWeak<WebCore::WeakMember<T> > {
596 static const bool value = true;
599 template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
600 struct IsWeak<WebCore::HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
601 static const bool value = Traits::isWeak;