Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / heap / Handle.h
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 hasIsHeapObjectAlive(char[&U::isHeapObjectAlive != 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 hasIsHeapObjectAlive(F<sizeof(&U::isHeapObjectAlive)>*);
65 #endif
66     template<typename U> static FalseType hasIsHeapObjectAlive(...);
67     template<typename U> static FalseType hasAdjustAndMark(...);
68
69     static bool const value = (sizeof(TrueType) == sizeof(hasAdjustAndMark<T>(0))) && (sizeof(TrueType) == sizeof(hasIsHeapObjectAlive<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::IsSubclassOfTemplate<NonConstType, HeapHashSet> HeapHashSetSubclass;
83     typedef WTF::IsSubclassOfTemplate<NonConstType, HeapLinkedHashSet> HeapLinkedHashSetSubclass;
84     typedef WTF::IsSubclassOfTemplateTypenameSizeTypename<NonConstType, HeapListHashSet> HeapListHashSetSubclass;
85     typedef WTF::IsSubclassOfTemplate<NonConstType, HeapHashMap> HeapHashMapSubclass;
86     typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapVector> HeapVectorSubclass;
87     typedef WTF::IsSubclassOfTemplateTypenameSize<NonConstType, HeapDeque> HeapDequeSubclass;
88     typedef WTF::IsSubclassOfTemplate<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 // RootsAccessor for Persistent that provides access to thread-local list
154 // of persistent handles. Can only be used to create handles that
155 // are constructed and destructed on the same thread.
156 template<ThreadAffinity Affinity>
157 class ThreadLocalPersistents {
158 public:
159     static PersistentNode* roots() { return state()->roots(); }
160
161     // No locking required. Just check that we are at the right thread.
162     class Lock {
163     public:
164         Lock() { state()->checkThread(); }
165     };
166
167 private:
168     static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
169 };
170
171 // RootsAccessor for Persistent that provides synchronized access to global
172 // list of persistent handles. Can be used for persistent handles that are
173 // passed between threads.
174 class GlobalPersistents {
175 public:
176     static PersistentNode* roots() { return ThreadState::globalRoots(); }
177
178     class Lock {
179     public:
180         Lock() : m_locker(ThreadState::globalRootsMutex()) { }
181     private:
182         MutexLocker m_locker;
183     };
184 };
185
186 // Base class for persistent handles. RootsAccessor specifies which list to
187 // link resulting handle into. Owner specifies the class containing trace
188 // method.
189 template<typename RootsAccessor, typename Owner>
190 class PersistentBase : public PersistentNode {
191 public:
192     ~PersistentBase()
193     {
194         typename RootsAccessor::Lock lock;
195         ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is using the same roots list.
196         ASSERT(isAlive());
197         ASSERT(m_next->isAlive());
198         ASSERT(m_prev->isAlive());
199         m_next->m_prev = m_prev;
200         m_prev->m_next = m_next;
201     }
202
203 protected:
204     inline PersistentBase()
205         : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
206 #if ENABLE(ASSERT)
207         , m_roots(RootsAccessor::roots())
208 #endif
209     {
210         typename RootsAccessor::Lock lock;
211         m_prev = RootsAccessor::roots();
212         m_next = m_prev->m_next;
213         m_prev->m_next = this;
214         m_next->m_prev = this;
215     }
216
217     inline explicit PersistentBase(const PersistentBase& otherref)
218         : PersistentNode(otherref.m_trace)
219 #if ENABLE(ASSERT)
220         , m_roots(RootsAccessor::roots())
221 #endif
222     {
223         // We don't support allocation of thread local Persistents while doing
224         // thread shutdown/cleanup.
225         ASSERT(!ThreadState::current()->isTerminating());
226         typename RootsAccessor::Lock lock;
227         ASSERT(otherref.m_roots == m_roots); // Handles must belong to the same list.
228         PersistentBase* other = const_cast<PersistentBase*>(&otherref);
229         m_prev = other;
230         m_next = other->m_next;
231         other->m_next = this;
232         m_next->m_prev = this;
233     }
234
235     inline PersistentBase& operator=(const PersistentBase& otherref) { return *this; }
236
237 #if ENABLE(ASSERT)
238 private:
239     PersistentNode* m_roots;
240 #endif
241 };
242
243 // A dummy Persistent handle that ensures the list of persistents is never null.
244 // This removes a test from a hot path.
245 class PersistentAnchor : public PersistentNode {
246 public:
247     void trace(Visitor* visitor)
248     {
249         for (PersistentNode* current = m_next; current != this; current = current->m_next)
250             current->trace(visitor);
251     }
252
253     int numberOfPersistents()
254     {
255         int numberOfPersistents = 0;
256         for (PersistentNode* current = m_next; current != this; current = current->m_next)
257             ++numberOfPersistents;
258         return numberOfPersistents;
259     }
260
261     virtual ~PersistentAnchor()
262     {
263         // FIXME: oilpan: Ideally we should have no left-over persistents at this point. However currently there is a
264         // large number of objects leaked when we tear down the main thread. Since some of these might contain a
265         // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
266         // this point.
267     }
268
269 private:
270     PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
271     {
272         m_next = this;
273         m_prev = this;
274     }
275
276     friend class ThreadState;
277 };
278
279 #if ENABLE(ASSERT)
280     // For global persistent handles we cannot check that the
281     // pointer is in the heap because that would involve
282     // inspecting the heap of running threads.
283 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \
284     bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>::value; \
285     ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(pointer))
286 #else
287 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer)
288 #endif
289
290 template<typename T>
291 class CrossThreadPersistent;
292
293 // Persistent handles are used to store pointers into the
294 // managed heap. As long as the Persistent handle is alive
295 // the GC will keep the object pointed to alive. Persistent
296 // handles can be stored in objects and they are not scoped.
297 // Persistent handles must not be used to contain pointers
298 // between objects that are in the managed heap. They are only
299 // meant to point to managed heap objects from variables/members
300 // outside the managed heap.
301 //
302 // A Persistent is always a GC root from the point of view of
303 // the garbage collector.
304 //
305 // We have to construct and destruct Persistent with default RootsAccessor in
306 // the same thread.
307 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > */ >
308 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAccessor> > {
309 public:
310     Persistent() : m_raw(0) { }
311
312     Persistent(std::nullptr_t) : m_raw(0) { }
313
314     Persistent(T* raw) : m_raw(raw)
315     {
316         ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
317         recordBacktrace();
318     }
319
320     explicit Persistent(T& raw) : m_raw(&raw)
321     {
322         ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw);
323         recordBacktrace();
324     }
325
326     Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); }
327
328     template<typename U>
329     Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recordBacktrace(); }
330
331     template<typename U>
332     Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); }
333
334     template<typename U>
335     Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); }
336
337     template<typename U>
338     Persistent& operator=(U* other)
339     {
340         m_raw = other;
341         recordBacktrace();
342         return *this;
343     }
344
345     Persistent& operator=(std::nullptr_t)
346     {
347         m_raw = 0;
348         return *this;
349     }
350
351     void clear() { m_raw = 0; }
352
353     virtual ~Persistent()
354     {
355         m_raw = 0;
356     }
357
358     template<typename U>
359     U* as() const
360     {
361         return static_cast<U*>(m_raw);
362     }
363
364     void trace(Visitor* visitor)
365     {
366         COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersistent);
367 #if ENABLE(GC_PROFILE_MARKING)
368         visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tracingName);
369 #endif
370         visitor->mark(m_raw);
371     }
372
373     RawPtr<T> release()
374     {
375         RawPtr<T> result = m_raw;
376         m_raw = 0;
377         return result;
378     }
379
380     T& operator*() const { return *m_raw; }
381
382     bool operator!() const { return !m_raw; }
383
384     operator T*() const { return m_raw; }
385     operator RawPtr<T>() const { return m_raw; }
386
387     T* operator->() const { return *this; }
388
389     Persistent& operator=(const Persistent& other)
390     {
391         m_raw = other;
392         recordBacktrace();
393         return *this;
394     }
395
396     template<typename U>
397     Persistent& operator=(const Persistent<U, RootsAccessor>& other)
398     {
399         m_raw = other;
400         recordBacktrace();
401         return *this;
402     }
403
404     template<typename U>
405     Persistent& operator=(const Member<U>& other)
406     {
407         m_raw = other;
408         recordBacktrace();
409         return *this;
410     }
411
412     template<typename U>
413     Persistent& operator=(const RawPtr<U>& other)
414     {
415         m_raw = other;
416         recordBacktrace();
417         return *this;
418     }
419
420     T* get() const { return m_raw; }
421
422 private:
423 #if ENABLE(GC_PROFILE_MARKING)
424     void recordBacktrace()
425     {
426         if (m_raw)
427             m_tracingName = Heap::createBacktraceString();
428     }
429
430     String m_tracingName;
431 #else
432     inline void recordBacktrace() const { }
433 #endif
434     T* m_raw;
435
436     friend class CrossThreadPersistent<T>;
437 };
438
439 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
440 // different from the construction thread.
441 template<typename T>
442 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> {
443 public:
444     CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { }
445
446     using Persistent<T, GlobalPersistents>::operator=;
447 };
448
449 // FIXME: derive affinity based on the collection.
450 template<typename Collection, ThreadAffinity Affinity = AnyThread>
451 class PersistentHeapCollectionBase
452     : public Collection
453     , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapCollectionBase<Collection, Affinity> > {
454     // We overload the various new and delete operators with using the WTF DefaultAllocator to ensure persistent
455     // heap collections are always allocated off-heap. This allows persistent collections to be used in
456     // DEFINE_STATIC_LOCAL et. al.
457     WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
458 public:
459     PersistentHeapCollectionBase() { }
460
461     template<typename OtherCollection>
462     PersistentHeapCollectionBase(const OtherCollection& other) : Collection(other) { }
463
464     void trace(Visitor* visitor)
465     {
466 #if ENABLE(GC_PROFILE_MARKING)
467         visitor->setHostInfo(this, "PersistentHeapCollectionBase");
468 #endif
469         visitor->trace(*static_cast<Collection*>(this));
470     }
471 };
472
473 template<
474     typename KeyArg,
475     typename MappedArg,
476     typename HashArg = typename DefaultHash<KeyArg>::Hash,
477     typename KeyTraitsArg = HashTraits<KeyArg>,
478     typename MappedTraitsArg = HashTraits<MappedArg> >
479 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { };
480
481 template<
482     typename ValueArg,
483     typename HashArg = typename DefaultHash<ValueArg>::Hash,
484     typename TraitsArg = HashTraits<ValueArg> >
485 class PersistentHeapHashSet : public PersistentHeapCollectionBase<HeapHashSet<ValueArg, HashArg, TraitsArg> > { };
486
487 template<
488     typename ValueArg,
489     typename HashArg = typename DefaultHash<ValueArg>::Hash,
490     typename TraitsArg = HashTraits<ValueArg> >
491 class PersistentHeapLinkedHashSet : public PersistentHeapCollectionBase<HeapLinkedHashSet<ValueArg, HashArg, TraitsArg> > { };
492
493 template<
494     typename ValueArg,
495     size_t inlineCapacity = 0,
496     typename HashArg = typename DefaultHash<ValueArg>::Hash>
497 class PersistentHeapListHashSet : public PersistentHeapCollectionBase<HeapListHashSet<ValueArg, inlineCapacity, HashArg> > { };
498
499 template<typename T, typename U, typename V>
500 class PersistentHeapHashCountedSet : public PersistentHeapCollectionBase<HeapHashCountedSet<T, U, V> > { };
501
502 template<typename T, size_t inlineCapacity = 0>
503 class PersistentHeapVector : public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> > {
504 public:
505     PersistentHeapVector() { }
506
507     template<size_t otherCapacity>
508     PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
509         : PersistentHeapCollectionBase<HeapVector<T, inlineCapacity> >(other)
510     {
511     }
512 };
513
514 template<typename T, size_t inlineCapacity = 0>
515 class PersistentHeapDeque : public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> > {
516 public:
517     PersistentHeapDeque() { }
518
519     template<size_t otherCapacity>
520     PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
521         : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity> >(other)
522     {
523     }
524 };
525
526 // Members are used in classes to contain strong pointers to other oilpan heap
527 // allocated objects.
528 // All Member fields of a class must be traced in the class' trace method.
529 // During the mark phase of the GC all live objects are marked as live and
530 // all Member fields of a live object will be traced marked as live as well.
531 template<typename T>
532 class Member {
533 public:
534     Member() : m_raw(0)
535     {
536     }
537
538     Member(std::nullptr_t) : m_raw(0)
539     {
540     }
541
542     Member(T* raw) : m_raw(raw)
543     {
544     }
545
546     explicit Member(T& raw) : m_raw(&raw)
547     {
548     }
549
550     template<typename U>
551     Member(const RawPtr<U>& other) : m_raw(other.get())
552     {
553     }
554
555     Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
556     {
557     }
558
559     bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
560
561     template<typename U>
562     Member(const Persistent<U>& other) : m_raw(other) { }
563
564     Member(const Member& other) : m_raw(other) { }
565
566     template<typename U>
567     Member(const Member<U>& other) : m_raw(other) { }
568
569     T* release()
570     {
571         T* result = m_raw;
572         m_raw = 0;
573         return result;
574     }
575
576     template<typename U>
577     U* as() const
578     {
579         return static_cast<U*>(m_raw);
580     }
581
582     bool operator!() const { return !m_raw; }
583
584     operator T*() const { return m_raw; }
585
586     T* operator->() const { return m_raw; }
587     T& operator*() const { return *m_raw; }
588     template<typename U>
589     operator RawPtr<U>() const { return m_raw; }
590
591     template<typename U>
592     Member& operator=(const Persistent<U>& other)
593     {
594         m_raw = other;
595         return *this;
596     }
597
598     template<typename U>
599     Member& operator=(const Member<U>& other)
600     {
601         m_raw = other;
602         return *this;
603     }
604
605     template<typename U>
606     Member& operator=(U* other)
607     {
608         m_raw = other;
609         return *this;
610     }
611
612     template<typename U>
613     Member& operator=(RawPtr<U> other)
614     {
615         m_raw = other;
616         return *this;
617     }
618
619     Member& operator=(std::nullptr_t)
620     {
621         m_raw = 0;
622         return *this;
623     }
624
625     void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
626
627     T* get() const { return m_raw; }
628
629     void clear() { m_raw = 0; }
630
631
632 protected:
633     void verifyTypeIsGarbageCollected() const
634     {
635         COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember);
636     }
637
638     T* m_raw;
639
640     template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
641     friend class Visitor;
642 };
643
644 template<typename T>
645 class TraceTrait<Member<T> > {
646 public:
647     static void trace(Visitor* visitor, void* self)
648     {
649         TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
650     }
651 };
652
653 // TraceTrait to allow compilation of trace method bodies when oilpan is disabled.
654 // This should never be called, but is needed to compile.
655 template<typename T>
656 class TraceTrait<RefPtr<T> > {
657 public:
658     static void trace(Visitor*, void*)
659     {
660         ASSERT_NOT_REACHED();
661     }
662 };
663
664 template<typename T>
665 class TraceTrait<OwnPtr<T> > {
666 public:
667     static void trace(Visitor* visitor, OwnPtr<T>* ptr)
668     {
669         ASSERT_NOT_REACHED();
670     }
671 };
672
673 template<typename T, bool needsTracing>
674 struct TraceIfEnabled;
675
676 template<typename T>
677 struct TraceIfEnabled<T, false>  {
678     static void trace(Visitor*, T*) { }
679 };
680
681 template<typename T>
682 struct TraceIfEnabled<T, true> {
683     static void trace(Visitor* visitor, T* t)
684     {
685         visitor->trace(*t);
686     }
687 };
688
689 template <typename T> struct RemoveHeapPointerWrapperTypes {
690     typedef typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<typename WTF::RemoveTemplate<T, Member>::Type, WeakMember>::Type, RawPtr>::Type Type;
691 };
692
693 // FIXME: Oilpan: TraceIfNeeded should be implemented ala:
694 // NeedsTracing<T>::value || IsWeakMember<T>::value. It should not need to test
695 // raw pointer types. To remove these tests, we may need support for
696 // instantiating a template with a RawPtrOrMember'ish template.
697 template<typename T>
698 struct TraceIfNeeded : public TraceIfEnabled<T, WTF::NeedsTracing<T>::value || blink::IsGarbageCollectedType<typename RemoveHeapPointerWrapperTypes<typename WTF::RemovePointer<T>::Type>::Type>::value> { };
699
700 // This trace trait for std::pair will null weak members if their referent is
701 // collected. If you have a collection that contain weakness it does not remove
702 // entries from the collection that contain nulled weak members.
703 template<typename T, typename U>
704 class TraceTrait<std::pair<T, U> > {
705 public:
706     static const bool firstNeedsTracing = WTF::NeedsTracing<T>::value || WTF::IsWeak<T>::value;
707     static const bool secondNeedsTracing = WTF::NeedsTracing<U>::value || WTF::IsWeak<U>::value;
708     static void trace(Visitor* visitor, std::pair<T, U>* pair)
709     {
710         TraceIfEnabled<T, firstNeedsTracing>::trace(visitor, &pair->first);
711         TraceIfEnabled<U, secondNeedsTracing>::trace(visitor, &pair->second);
712     }
713 };
714
715 // WeakMember is similar to Member in that it is used to point to other oilpan
716 // heap allocated objects.
717 // However instead of creating a strong pointer to the object, the WeakMember creates
718 // a weak pointer, which does not keep the pointee alive. Hence if all pointers to
719 // to a heap allocated object are weak the object will be garbage collected. At the
720 // time of GC the weak pointers will automatically be set to null.
721 template<typename T>
722 class WeakMember : public Member<T> {
723 public:
724     WeakMember() : Member<T>() { }
725
726     WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
727
728     WeakMember(T* raw) : Member<T>(raw) { }
729
730     WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
731
732     template<typename U>
733     WeakMember(const Persistent<U>& other) : Member<T>(other) { }
734
735     template<typename U>
736     WeakMember(const Member<U>& other) : Member<T>(other) { }
737
738     template<typename U>
739     WeakMember& operator=(const Persistent<U>& other)
740     {
741         this->m_raw = other;
742         return *this;
743     }
744
745     template<typename U>
746     WeakMember& operator=(const Member<U>& other)
747     {
748         this->m_raw = other;
749         return *this;
750     }
751
752     template<typename U>
753     WeakMember& operator=(U* other)
754     {
755         this->m_raw = other;
756         return *this;
757     }
758
759     template<typename U>
760     WeakMember& operator=(const RawPtr<U>& other)
761     {
762         this->m_raw = other;
763         return *this;
764     }
765
766     WeakMember& operator=(std::nullptr_t)
767     {
768         this->m_raw = 0;
769         return *this;
770     }
771
772 private:
773     T** cell() const { return const_cast<T**>(&this->m_raw); }
774
775     friend class Visitor;
776 };
777
778 // Comparison operators between (Weak)Members and Persistents
779 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
780 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
781 template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
782 template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
783 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
784 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
785 template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
786 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
787
788 // CPP-defined type names for the transition period where we want to
789 // support both reference counting and garbage collection based on a
790 // compile-time flag.
791 //
792 // C++11 template aliases were initially used (with clang only, not
793 // with GCC nor MSVC.) However, supporting both CPP defines and
794 // template aliases is problematic from outside a WebCore namespace
795 // when Oilpan is disabled: e.g.,
796 // blink::RefCountedWillBeGarbageCollected as a template alias would
797 // uniquely resolve from within any namespace, but if it is backed by
798 // a CPP #define, it would expand to blink::RefCounted, and not the
799 // required WTF::RefCounted.
800 //
801 // Having the CPP expansion instead be fully namespace qualified, and the
802 // transition type be unqualified, would dually not work for template
803 // aliases. So, slightly unfortunately, fall back/down to the lowest
804 // commmon denominator of using CPP macros only.
805 #if ENABLE(OILPAN)
806 #define PassRefPtrWillBeRawPtr WTF::RawPtr
807 #define RefCountedWillBeGarbageCollected blink::GarbageCollected
808 #define RefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
809 #define RefCountedWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
810 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
811 #define ThreadSafeRefCountedWillBeGarbageCollected blink::GarbageCollected
812 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
813 #define PersistentWillBeMember blink::Member
814 #define CrossThreadPersistentWillBeMember blink::Member
815 #define RefPtrWillBePersistent blink::Persistent
816 #define RefPtrWillBeRawPtr WTF::RawPtr
817 #define RefPtrWillBeMember blink::Member
818 #define RefPtrWillBeWeakMember blink::WeakMember
819 #define RefPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent
820 #define RawPtrWillBeMember blink::Member
821 #define RawPtrWillBePersistent blink::Persistent
822 #define RawPtrWillBeWeakMember blink::WeakMember
823 #define OwnPtrWillBeMember blink::Member
824 #define OwnPtrWillBePersistent blink::Persistent
825 #define OwnPtrWillBeRawPtr WTF::RawPtr
826 #define PassOwnPtrWillBeRawPtr WTF::RawPtr
827 #define WeakPtrWillBeMember blink::Member
828 #define WeakPtrWillBeRawPtr WTF::RawPtr
829 #define WeakPtrWillBeMember blink::Member
830 #define WeakPtrWillBeWeakMember blink::WeakMember
831 #define NoBaseWillBeGarbageCollected blink::GarbageCollected
832 #define NoBaseWillBeGarbageCollectedFinalized blink::GarbageCollectedFinalized
833 #define NoBaseWillBeRefCountedGarbageCollected blink::RefCountedGarbageCollected
834 #define WillBeHeapHashMap blink::HeapHashMap
835 #define WillBePersistentHeapHashMap blink::PersistentHeapHashMap
836 #define WillBeHeapHashSet blink::HeapHashSet
837 #define WillBePersistentHeapHashSet blink::PersistentHeapHashSet
838 #define WillBeHeapLinkedHashSet blink::HeapLinkedHashSet
839 #define WillBePersistentHeapLinkedHashSet blink::PersistentHeapLinkedHashSet
840 #define WillBeHeapListHashSet blink::HeapListHashSet
841 #define WillBePersistentHeapListHashSet blink::PersistentHeapListHashSet
842 #define WillBeHeapVector blink::HeapVector
843 #define WillBePersistentHeapVector blink::PersistentHeapVector
844 #define WillBeHeapDeque blink::HeapDeque
845 #define WillBePersistentHeapDeque blink::PersistentHeapDeque
846 #define WillBeHeapHashCountedSet blink::HeapHashCountedSet
847 #define WillBePersistentHeapHashCountedSet blink::PersistentHeapHashCountedSet
848 #define WillBeGarbageCollectedMixin blink::GarbageCollectedMixin
849 #define WillBeHeapSupplement blink::HeapSupplement
850 #define WillBeHeapSupplementable blink::HeapSupplementable
851 #define WillBeHeapTerminatedArray blink::HeapTerminatedArray
852 #define WillBeHeapTerminatedArrayBuilder blink::HeapTerminatedArrayBuilder
853 #define WillBeHeapLinkedStack blink::HeapLinkedStack
854 #define PersistentHeapHashMapWillBeHeapHashMap blink::HeapHashMap
855 #define PersistentHeapHashSetWillBeHeapHashSet blink::HeapHashSet
856 #define PersistentHeapDequeWillBeHeapDeque blink::HeapDeque
857 #define PersistentHeapVectorWillBeHeapVector blink::HeapVector
858
859 template<typename T> T* adoptRefWillBeNoop(T* ptr)
860 {
861     static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
862     COMPILE_ASSERT(notRefCounted, youMustAdopt);
863     return ptr;
864 }
865
866 template<typename T> T* adoptPtrWillBeNoop(T* ptr)
867 {
868     static const bool notRefCounted = !WTF::IsSubclassOfTemplate<typename WTF::RemoveConst<T>::Type, RefCounted>::value;
869     COMPILE_ASSERT(notRefCounted, youMustAdopt);
870     return ptr;
871 }
872
873 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED // do nothing when oilpan is enabled.
874 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
875 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
876 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) // do nothing
877
878 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
879     static type* name = (new Persistent<type>(arguments))->get();
880
881 #else // !ENABLE(OILPAN)
882
883 template<typename T>
884 class DummyBase {
885 public:
886     DummyBase() { }
887     ~DummyBase() { }
888 };
889
890 #define PassRefPtrWillBeRawPtr WTF::PassRefPtr
891 #define RefCountedWillBeGarbageCollected WTF::RefCounted
892 #define RefCountedWillBeGarbageCollectedFinalized WTF::RefCounted
893 #define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted
894 #define RefCountedGarbageCollectedWillBeGarbageCollectedFinalized blink::RefCountedGarbageCollected
895 #define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted
896 #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted
897 #define PersistentWillBeMember blink::Persistent
898 #define CrossThreadPersistentWillBeMember blink::CrossThreadPersistent
899 #define RefPtrWillBePersistent WTF::RefPtr
900 #define RefPtrWillBeRawPtr WTF::RefPtr
901 #define RefPtrWillBeMember WTF::RefPtr
902 #define RefPtrWillBeWeakMember WTF::RefPtr
903 #define RefPtrWillBeCrossThreadPersistent WTF::RefPtr
904 #define RawPtrWillBeMember WTF::RawPtr
905 #define RawPtrWillBePersistent WTF::RawPtr
906 #define RawPtrWillBeWeakMember WTF::RawPtr
907 #define OwnPtrWillBeMember WTF::OwnPtr
908 #define OwnPtrWillBePersistent WTF::OwnPtr
909 #define OwnPtrWillBeRawPtr WTF::OwnPtr
910 #define PassOwnPtrWillBeRawPtr WTF::PassOwnPtr
911 #define WeakPtrWillBeMember WTF::WeakPtr
912 #define WeakPtrWillBeRawPtr WTF::WeakPtr
913 #define WeakPtrWillBeMember WTF::WeakPtr
914 #define WeakPtrWillBeWeakMember WTF::WeakPtr
915 #define NoBaseWillBeGarbageCollected blink::DummyBase
916 #define NoBaseWillBeGarbageCollectedFinalized blink::DummyBase
917 #define NoBaseWillBeRefCountedGarbageCollected blink::DummyBase
918 #define WillBeHeapHashMap WTF::HashMap
919 #define WillBePersistentHeapHashMap WTF::HashMap
920 #define WillBeHeapHashSet WTF::HashSet
921 #define WillBePersistentHeapHashSet WTF::HashSet
922 #define WillBeHeapLinkedHashSet WTF::LinkedHashSet
923 #define WillBePersistentLinkedHeapHashSet WTF::LinkedHashSet
924 #define WillBeHeapListHashSet WTF::ListHashSet
925 #define WillBePersistentListHeapHashSet WTF::ListHashSet
926 #define WillBeHeapVector WTF::Vector
927 #define WillBePersistentHeapVector WTF::Vector
928 #define WillBeHeapDeque WTF::Deque
929 #define WillBePersistentHeapDeque WTF::Deque
930 #define WillBeHeapHashCountedSet WTF::HashCountedSet
931 #define WillBePersistentHeapHashCountedSet WTF::HashCountedSet
932 #define WillBeGarbageCollectedMixin blink::DummyBase<void>
933 #define WillBeHeapSupplement blink::Supplement
934 #define WillBeHeapSupplementable blink::Supplementable
935 #define WillBeHeapTerminatedArray WTF::TerminatedArray
936 #define WillBeHeapTerminatedArrayBuilder WTF::TerminatedArrayBuilder
937 #define WillBeHeapLinkedStack WTF::LinkedStack
938 #define PersistentHeapHashMapWillBeHeapHashMap blink::PersistentHeapHashMap
939 #define PersistentHeapHashSetWillBeHeapHashSet blink::PersistentHeapHashSet
940 #define PersistentHeapDequeWillBeHeapDeque blink::PersistentHeapDeque
941 #define PersistentHeapVectorWillBeHeapVector blink::PersistentHeapVector
942
943 template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
944 template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
945
946 #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED
947 #define DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
948     public:                                            \
949         ~type();                                       \
950     private:
951 #define DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(type) \
952     public:                                                    \
953         virtual ~type();                                       \
954     private:
955
956 #define DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(type) \
957     type::~type() { }
958
959 #define DEFINE_STATIC_REF_WILL_BE_PERSISTENT(type, name, arguments) \
960     DEFINE_STATIC_REF(type, name, arguments)
961
962 #endif // ENABLE(OILPAN)
963
964 } // namespace blink
965
966 namespace WTF {
967
968 template <typename T> struct VectorTraits<blink::Member<T> > : VectorTraitsBase<blink::Member<T> > {
969     static const bool needsDestruction = false;
970     static const bool canInitializeWithMemset = true;
971     static const bool canMoveWithMemcpy = true;
972 };
973
974 template <typename T> struct VectorTraits<blink::WeakMember<T> > : VectorTraitsBase<blink::WeakMember<T> > {
975     static const bool needsDestruction = false;
976     static const bool canInitializeWithMemset = true;
977     static const bool canMoveWithMemcpy = true;
978 };
979
980 template <typename T> struct VectorTraits<blink::HeapVector<T, 0> > : VectorTraitsBase<blink::HeapVector<T, 0> > {
981     static const bool needsDestruction = false;
982     static const bool canInitializeWithMemset = true;
983     static const bool canMoveWithMemcpy = true;
984 };
985
986 template <typename T> struct VectorTraits<blink::HeapDeque<T, 0> > : VectorTraitsBase<blink::HeapDeque<T, 0> > {
987     static const bool needsDestruction = false;
988     static const bool canInitializeWithMemset = true;
989     static const bool canMoveWithMemcpy = true;
990 };
991
992 template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapVector<T, inlineCapacity> > : VectorTraitsBase<blink::HeapVector<T, inlineCapacity> > {
993     static const bool needsDestruction = VectorTraits<T>::needsDestruction;
994     static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
995     static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
996 };
997
998 template <typename T, size_t inlineCapacity> struct VectorTraits<blink::HeapDeque<T, inlineCapacity> > : VectorTraitsBase<blink::HeapDeque<T, inlineCapacity> > {
999     static const bool needsDestruction = VectorTraits<T>::needsDestruction;
1000     static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
1001     static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
1002 };
1003
1004 template<typename T> struct HashTraits<blink::Member<T> > : SimpleClassHashTraits<blink::Member<T> > {
1005     static const bool needsDestruction = false;
1006     // FIXME: The distinction between PeekInType and PassInType is there for
1007     // the sake of the reference counting handles. When they are gone the two
1008     // types can be merged into PassInType.
1009     // FIXME: Implement proper const'ness for iterator types. Requires support
1010     // in the marking Visitor.
1011     typedef RawPtr<T> PeekInType;
1012     typedef RawPtr<T> PassInType;
1013     typedef blink::Member<T>* IteratorGetType;
1014     typedef const blink::Member<T>* IteratorConstGetType;
1015     typedef blink::Member<T>& IteratorReferenceType;
1016     typedef T* const IteratorConstReferenceType;
1017     static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1018     static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1019     // FIXME: Similarly, there is no need for a distinction between PeekOutType
1020     // and PassOutType without reference counting.
1021     typedef T* PeekOutType;
1022     typedef T* PassOutType;
1023
1024     template<typename U>
1025     static void store(const U& value, blink::Member<T>& storage) { storage = value; }
1026
1027     static PeekOutType peek(const blink::Member<T>& value) { return value; }
1028     static PassOutType passOut(const blink::Member<T>& value) { return value; }
1029 };
1030
1031 template<typename T> struct HashTraits<blink::WeakMember<T> > : SimpleClassHashTraits<blink::WeakMember<T> > {
1032     static const bool needsDestruction = false;
1033     // FIXME: The distinction between PeekInType and PassInType is there for
1034     // the sake of the reference counting handles. When they are gone the two
1035     // types can be merged into PassInType.
1036     // FIXME: Implement proper const'ness for iterator types. Requires support
1037     // in the marking Visitor.
1038     typedef RawPtr<T> PeekInType;
1039     typedef RawPtr<T> PassInType;
1040     typedef blink::WeakMember<T>* IteratorGetType;
1041     typedef const blink::WeakMember<T>* IteratorConstGetType;
1042     typedef blink::WeakMember<T>& IteratorReferenceType;
1043     typedef T* const IteratorConstReferenceType;
1044     static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
1045     static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->get(); }
1046     // FIXME: Similarly, there is no need for a distinction between PeekOutType
1047     // and PassOutType without reference counting.
1048     typedef T* PeekOutType;
1049     typedef T* PassOutType;
1050
1051     template<typename U>
1052     static void store(const U& value, blink::WeakMember<T>& storage) { storage = value; }
1053
1054     static PeekOutType peek(const blink::WeakMember<T>& value) { return value; }
1055     static PassOutType passOut(const blink::WeakMember<T>& value) { return value; }
1056     static bool traceInCollection(blink::Visitor* visitor, blink::WeakMember<T>& weakMember, ShouldWeakPointersBeMarkedStrongly strongify)
1057     {
1058         if (strongify == WeakPointersActStrong) {
1059             visitor->trace(reinterpret_cast<blink::Member<T>&>(weakMember)); // Strongified visit.
1060             return false;
1061         }
1062         return !visitor->isAlive(weakMember);
1063     }
1064 };
1065
1066 template<typename T> struct PtrHash<blink::Member<T> > : PtrHash<T*> {
1067     template<typename U>
1068     static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); }
1069     static bool equal(T* a, const blink::Member<T>& b) { return a == b; }
1070     static bool equal(const blink::Member<T>& a, T* b) { return a == b; }
1071     template<typename U, typename V>
1072     static bool equal(const U& a, const V& b) { return a == b; }
1073 };
1074
1075 template<typename T> struct PtrHash<blink::WeakMember<T> > : PtrHash<blink::Member<T> > {
1076 };
1077
1078 template<typename P> struct PtrHash<blink::Persistent<P> > : PtrHash<P*> {
1079     using PtrHash<P*>::hash;
1080     static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); }
1081     using PtrHash<P*>::equal;
1082     static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; }
1083     static bool equal(P* a, const RefPtr<P>& b) { return a == b; }
1084     static bool equal(const RefPtr<P>& a, P* b) { return a == b; }
1085 };
1086
1087 // PtrHash is the default hash for hash tables with members.
1088 template<typename T> struct DefaultHash<blink::Member<T> > {
1089     typedef PtrHash<blink::Member<T> > Hash;
1090 };
1091
1092 template<typename T> struct DefaultHash<blink::WeakMember<T> > {
1093     typedef PtrHash<blink::WeakMember<T> > Hash;
1094 };
1095
1096 template<typename T> struct DefaultHash<blink::Persistent<T> > {
1097     typedef PtrHash<blink::Persistent<T> > Hash;
1098 };
1099
1100 template<typename T>
1101 struct NeedsTracing<blink::Member<T> > {
1102     static const bool value = true;
1103 };
1104
1105 template<typename T>
1106 struct IsWeak<blink::WeakMember<T> > {
1107     static const bool value = true;
1108 };
1109
1110 template<typename T> inline T* getPtr(const blink::Member<T>& p)
1111 {
1112     return p.get();
1113 }
1114
1115 template<typename T> inline T* getPtr(const blink::Persistent<T>& p)
1116 {
1117     return p.get();
1118 }
1119
1120 template<typename T, size_t inlineCapacity>
1121 struct NeedsTracing<ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity> > *> {
1122     // All heap allocated node pointers need visiting to keep the nodes alive,
1123     // regardless of whether they contain pointers to other heap allocated
1124     // objects.
1125     static const bool value = true;
1126 };
1127
1128 // For wtf/Functional.h
1129 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
1130
1131 template<typename T>
1132 struct PointerParamStorageTraits<T*, false> {
1133     typedef T* StorageType;
1134
1135     static StorageType wrap(T* value) { return value; }
1136     static T* unwrap(const StorageType& value) { return value; }
1137 };
1138
1139 template<typename T>
1140 struct PointerParamStorageTraits<T*, true> {
1141     typedef blink::CrossThreadPersistent<T> StorageType;
1142
1143     static StorageType wrap(T* value) { return value; }
1144     static T* unwrap(const StorageType& value) { return value.get(); }
1145 };
1146
1147 template<typename T>
1148 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
1149 };
1150
1151 template<typename T>
1152 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, blink::IsGarbageCollectedType<T>::value> {
1153 };
1154
1155 } // namespace WTF
1156
1157 #endif