Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / 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 "heap/Heap.h"
35 #include "heap/ThreadState.h"
36 #include "heap/Visitor.h"
37
38 #include "wtf/Ptr.h"
39 #include "wtf/RefCounted.h"
40
41 namespace WebCore {
42
43 template<typename T> class Member;
44
45 class PersistentNode {
46 public:
47     explicit PersistentNode(TraceCallback trace) : m_trace(trace) { }
48
49     virtual ~PersistentNode() { }
50
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)
59     {
60         m_trace(visitor, this);
61     }
62
63 protected:
64     TraceCallback m_trace;
65
66 private:
67     PersistentNode* m_next;
68     PersistentNode* m_prev;
69
70     template<ThreadAffinity affinity, typename Owner> friend class PersistentBase;
71     friend class PersistentAnchor;
72     friend class ThreadState;
73 };
74
75 template<ThreadAffinity Affinity, typename Owner>
76 class PersistentBase : public PersistentNode {
77 public:
78     ~PersistentBase()
79     {
80 #ifndef NDEBUG
81         m_threadState->checkThread();
82 #endif
83         m_next->m_prev = m_prev;
84         m_prev->m_next = m_next;
85     }
86
87 protected:
88     inline PersistentBase()
89         : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
90 #ifndef NDEBUG
91         , m_threadState(state())
92 #endif
93     {
94 #ifndef NDEBUG
95         m_threadState->checkThread();
96 #endif
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;
102     }
103
104     inline explicit PersistentBase(const PersistentBase& otherref)
105         : PersistentNode(otherref.m_trace)
106 #ifndef NDEBUG
107         , m_threadState(state())
108 #endif
109     {
110 #ifndef NDEBUG
111         m_threadState->checkThread();
112 #endif
113         ASSERT(otherref.m_threadState == m_threadState);
114         PersistentBase* other = const_cast<PersistentBase*>(&otherref);
115         m_prev = other;
116         m_next = other->m_next;
117         other->m_next = this;
118         m_next->m_prev = this;
119     }
120
121     inline PersistentBase& operator=(const PersistentBase& otherref)
122     {
123         return *this;
124     }
125
126     static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
127
128 #ifndef NDEBUG
129 private:
130     ThreadState* m_threadState;
131 #endif
132 };
133
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 {
137 public:
138     void trace(Visitor*) { }
139
140 private:
141     virtual ~PersistentAnchor() { }
142     PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline)
143     {
144         m_next = this;
145         m_prev = this;
146     }
147
148     friend class ThreadState;
149 };
150
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.
159 //
160 // A Persistent is always a GC root from the point of view of
161 // the garbage collector.
162 template<typename T>
163 class Persistent : public PersistentBase<ThreadingTrait<T>::Affinity, Persistent<T> > {
164 public:
165     Persistent() : m_raw(0) { }
166
167     Persistent(T* raw) : m_raw(raw) { }
168
169     Persistent(std::nullptr_t) : m_raw(0) { }
170
171     Persistent(const Persistent& other) : m_raw(other) { }
172
173     template<typename U>
174     Persistent(const Persistent<U>& other) : m_raw(other) { }
175
176     template<typename U>
177     Persistent(const Member<U>& other) : m_raw(other) { }
178
179     template<typename U>
180     Persistent(const Ptr<U>& other) : m_raw(other.get()) { }
181
182     template<typename U>
183     Persistent& operator=(U* other)
184     {
185         m_raw = other;
186         return *this;
187     }
188
189     virtual ~Persistent()
190     {
191         m_raw = 0;
192     }
193
194     template<typename U>
195     U* as() const
196     {
197         return static_cast<U*>(m_raw);
198     }
199
200     void trace(Visitor* visitor) { visitor->mark(m_raw); }
201
202     T* release()
203     {
204         T* result = m_raw;
205         m_raw = 0;
206         return result;
207     }
208
209     T& operator*() const { return *m_raw; }
210
211     bool operator!() const { return !m_raw; }
212
213     operator T*() const { return m_raw; }
214     operator Ptr<T>() const { return m_raw; }
215
216     T* operator->() const { return *this; }
217
218     Persistent& operator=(std::nullptr_t)
219     {
220         m_raw = 0;
221         return *this;
222     }
223
224     Persistent& operator=(const Persistent& other)
225     {
226         m_raw = other;
227         return *this;
228     }
229
230     template<typename U>
231     Persistent& operator=(const Persistent<U>& other)
232     {
233         m_raw = other;
234         return *this;
235     }
236
237     template<typename U>
238     Persistent& operator=(const Member<U>& other)
239     {
240         m_raw = other;
241         return *this;
242     }
243
244     T* get() const { return m_raw; }
245
246 private:
247     T* m_raw;
248 };
249
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.
255 template<typename T>
256 class Member {
257 public:
258     Member() : m_raw(0) { }
259
260     Member(T* raw) : m_raw(raw) { }
261
262     Member(std::nullptr_t) : m_raw(0) { }
263
264     Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) { }
265
266     bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
267
268     template<typename U>
269     Member(const Persistent<U>& other) : m_raw(other) { }
270
271     Member(const Member& other) : m_raw(other) { }
272
273     template<typename U>
274     Member(const Member<U>& other) : m_raw(other) { }
275
276     T* release()
277     {
278         T* result = m_raw;
279         m_raw = 0;
280         return result;
281     }
282
283     template<typename U>
284     U* as() const
285     {
286         return static_cast<U*>(m_raw);
287     }
288
289     bool operator!() const { return !m_raw; }
290
291     operator T*() const { return m_raw; }
292
293     T* operator->() const { return m_raw; }
294     T& operator*() const { return *m_raw; }
295
296     Member& operator=(std::nullptr_t)
297     {
298         m_raw = 0;
299         return *this;
300     }
301
302     template<typename U>
303     Member& operator=(const Persistent<U>& other)
304     {
305         m_raw = other;
306         return *this;
307     }
308
309     Member& operator=(const Member& other)
310     {
311         m_raw = other;
312         return *this;
313     }
314
315     template<typename U>
316     Member& operator=(const Member<U>& other)
317     {
318         m_raw = other;
319         return *this;
320     }
321
322     template<typename U>
323     Member& operator=(U* other)
324     {
325         m_raw = other;
326         return *this;
327     }
328
329     void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); }
330
331     T* get() const { return m_raw; }
332
333 protected:
334     T* m_raw;
335
336     template<bool x, bool y, bool z, typename U, typename V> friend struct CollectionBackingTraceTrait;
337 };
338
339 template<typename T>
340 class TraceTrait<Member<T> > {
341 public:
342     static void trace(Visitor* visitor, void* self)
343     {
344         TraceTrait<T>::mark(visitor, *static_cast<Member<T>*>(self));
345     }
346 };
347
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.
354 template<typename T>
355 class WeakMember : public Member<T> {
356 public:
357     WeakMember() : Member<T>() { }
358
359     WeakMember(T* raw) : Member<T>(raw) { }
360
361     WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
362
363     WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
364
365     template<typename U>
366     WeakMember(const Persistent<U>& other) : Member<T>(other) { }
367
368     template<typename U>
369     WeakMember(const Member<U>& other) : Member<T>(other) { }
370
371     WeakMember& operator=(std::nullptr_t)
372     {
373         this->m_raw = 0;
374         return *this;
375     }
376
377     template<typename U>
378     WeakMember& operator=(const Persistent<U>& other)
379     {
380         this->m_raw = other;
381         return *this;
382     }
383
384     template<typename U>
385     WeakMember& operator=(const Member<U>& other)
386     {
387         this->m_raw = other;
388         return *this;
389     }
390
391     template<typename U>
392     WeakMember& operator=(U* other)
393     {
394         this->m_raw = other;
395         return *this;
396     }
397
398 private:
399     T** cell() const { return const_cast<T**>(&this->m_raw); }
400
401     friend class Visitor;
402 };
403
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(); }
413
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.
417 //
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.
421 #if ENABLE(OILPAN)
422
423 #if COMPILER(CLANG)
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)
450
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); }
453
454 #else // !ENABLE(OILPAN)
455
456 template<typename T>
457 class DummyBase {
458 public:
459     DummyBase() { }
460     ~DummyBase() { }
461 };
462
463 #if COMPILER(CLANG)
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)
490
491 template<typename T> PassRefPtrWillBePtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
492 template<typename T> PassOwnPtrWillBePtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
493
494 #endif // ENABLE(OILPAN)
495
496 } // namespace WebCore
497
498 namespace WTF {
499
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;
504 };
505
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;
510 };
511
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;
532
533     template<typename U>
534     static void store(const U& value, WebCore::Member<T>& storage) { storage = value; }
535
536     static PeekOutType peek(const WebCore::Member<T>& value) { return value; }
537     static PassOutType passOut(const WebCore::Member<T>& value) { return value; }
538 };
539
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;
560
561     template<typename U>
562     static void store(const U& value, WebCore::WeakMember<T>& storage) { storage = value; }
563
564     static PeekOutType peek(const WebCore::WeakMember<T>& value) { return value; }
565     static PassOutType passOut(const WebCore::WeakMember<T>& value) { return value; }
566 };
567
568 template<typename T> struct PtrHash<WebCore::Member<T> > : PtrHash<T*> {
569     template<typename U>
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; }
575 };
576
577 template<typename T> struct PtrHash<WebCore::WeakMember<T> > : PtrHash<WebCore::Member<T> > {
578 };
579
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;
583 };
584
585 template<typename T> struct DefaultHash<WebCore::WeakMember<T> > {
586     typedef PtrHash<WebCore::WeakMember<T> > Hash;
587 };
588
589 template<typename T>
590 struct NeedsTracing<WebCore::Member<T> > {
591     static const bool value = true;
592 };
593
594 template<typename T>
595 struct IsWeak<WebCore::WeakMember<T> > {
596     static const bool value = true;
597 };
598
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;
602 };
603
604 } // namespace WTF
605
606 #endif