initial import
[vuplus_webkit] / Source / JavaScriptCore / heap / Weak.h
1 /*
2  * Copyright (C) 2009 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef Weak_h
27 #define Weak_h
28
29 #include "Assertions.h"
30 #include "Handle.h"
31 #include "HandleHeap.h"
32 #include "JSGlobalData.h"
33
34 namespace JSC {
35
36 // A weakly referenced handle that becomes 0 when the value it points to is garbage collected.
37 template <typename T> class Weak : public Handle<T> {
38     using Handle<T>::slot;
39     using Handle<T>::setSlot;
40
41 public:
42     typedef typename Handle<T>::ExternalType ExternalType;
43
44     Weak()
45         : Handle<T>()
46     {
47     }
48
49     Weak(JSGlobalData& globalData, ExternalType value = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
50         : Handle<T>(globalData.allocateGlobalHandle())
51     {
52         HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
53         set(value);
54     }
55
56     enum AdoptTag { Adopt };
57     template<typename U> Weak(AdoptTag, Handle<U> handle)
58         : Handle<T>(handle.slot())
59     {
60         validateCell(get());
61     }
62     
63     Weak(const Weak& other)
64         : Handle<T>()
65     {
66         if (!other.slot())
67             return;
68         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
69     }
70
71     template <typename U> Weak(const Weak<U>& other)
72         : Handle<T>()
73     {
74         if (!other.slot())
75             return;
76         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
77     }
78     
79     enum HashTableDeletedValueTag { HashTableDeletedValue };
80     bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
81     Weak(HashTableDeletedValueTag)
82         : Handle<T>(hashTableDeletedValue())
83     {
84     }
85
86     ~Weak()
87     {
88         clear();
89     }
90
91     void swap(Weak& other)
92     {
93         Handle<T>::swap(other);
94     }
95
96     ExternalType get() const { return  HandleTypes<T>::getFromSlot(slot()); }
97     
98     void clear()
99     {
100         if (!slot())
101             return;
102         HandleHeap::heapFor(slot())->deallocate(slot());
103         setSlot(0);
104     }
105     
106     void set(JSGlobalData& globalData, ExternalType value, WeakHandleOwner* weakOwner = 0, void* context = 0)
107     {
108         if (!slot()) {
109             setSlot(globalData.allocateGlobalHandle());
110             HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
111         }
112         ASSERT(HandleHeap::heapFor(slot())->hasWeakOwner(slot(), weakOwner));
113         set(value);
114     }
115
116     template <typename U> Weak& operator=(const Weak<U>& other)
117     {
118         clear();
119         if (other.slot())
120             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
121         return *this;
122     }
123
124     Weak& operator=(const Weak& other)
125     {
126         clear();
127         if (other.slot())
128             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
129         return *this;
130     }
131     
132     HandleSlot leakHandle()
133     {
134         ASSERT(HandleHeap::heapFor(slot())->hasFinalizer(slot()));
135         HandleSlot result = slot();
136         setSlot(0);
137         return result;
138     }
139
140 private:
141     static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
142
143     void set(ExternalType externalType)
144     {
145         ASSERT(slot());
146         JSValue value = HandleTypes<T>::toJSValue(externalType);
147         ASSERT(!value || !value.isCell() || Heap::isMarked(value.asCell()));
148         HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
149         *slot() = value;
150     }
151 };
152
153 template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
154 {
155     a.swap(b);
156 }
157
158 } // namespace JSC
159
160 namespace WTF {
161
162 template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits {
163     static const bool canCompareWithMemcmp = false;
164 };
165
166 template<typename P> struct HashTraits<JSC::Weak<P> > : SimpleClassHashTraits<JSC::Weak<P> > { };
167
168 }
169
170 #endif // Weak_h