initial import
[vuplus_webkit] / Source / JavaScriptCore / runtime / StructureTransitionTable.h
1 /*
2  * Copyright (C) 2008, 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 COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef StructureTransitionTable_h
27 #define StructureTransitionTable_h
28
29 #include "UString.h"
30 #include "WeakGCMap.h"
31 #include <wtf/HashFunctions.h>
32 #include <wtf/HashTraits.h>
33 #include <wtf/OwnPtr.h>
34 #include <wtf/RefPtr.h>
35
36 namespace JSC {
37
38 class Structure;
39
40 class StructureTransitionTable {
41     static const intptr_t UsingSingleSlotFlag = 1;
42
43     struct Hash {
44         typedef std::pair<RefPtr<StringImpl>, unsigned> Key;
45         static unsigned hash(const Key& p)
46         {
47             return p.first->existingHash();
48         }
49
50         static bool equal(const Key& a, const Key& b)
51         {
52             return a == b;
53         }
54
55         static const bool safeToCompareToEmptyOrDeleted = true;
56     };
57
58     struct HashTraits {
59         typedef WTF::HashTraits<RefPtr<StringImpl> > FirstTraits;
60         typedef WTF::GenericHashTraits<unsigned> SecondTraits;
61         typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType;
62
63         static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
64         static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
65
66         static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
67
68         static const int minimumTableSize = FirstTraits::minimumTableSize;
69
70         static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
71         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
72     };
73
74     struct WeakGCMapFinalizerCallback {
75         static void* finalizerContextFor(Hash::Key)
76         {
77             return 0;
78         }
79
80         static inline Hash::Key keyForFinalizer(void* context, Structure* structure)
81         {
82             return keyForWeakGCMapFinalizer(context, structure);
83         }
84     };
85
86     typedef WeakGCMap<Hash::Key, Structure, WeakGCMapFinalizerCallback, Hash, HashTraits> TransitionMap;
87
88     static Hash::Key keyForWeakGCMapFinalizer(void* context, Structure*);
89
90 public:
91     StructureTransitionTable()
92         : m_data(UsingSingleSlotFlag)
93     {
94     }
95
96     ~StructureTransitionTable()
97     {
98         if (!isUsingSingleSlot()) {
99             delete map();
100             return;
101         }
102
103         HandleSlot slot = this->slot();
104         if (!slot)
105             return;
106         HandleHeap::heapFor(slot)->deallocate(slot);
107     }
108
109     inline void add(JSGlobalData&, Structure*);
110     inline bool contains(StringImpl* rep, unsigned attributes) const;
111     inline Structure* get(StringImpl* rep, unsigned attributes) const;
112
113 private:
114     bool isUsingSingleSlot() const
115     {
116         return m_data & UsingSingleSlotFlag;
117     }
118
119     TransitionMap* map() const
120     {
121         ASSERT(!isUsingSingleSlot());
122         return reinterpret_cast<TransitionMap*>(m_data);
123     }
124
125     HandleSlot slot() const
126     {
127         ASSERT(isUsingSingleSlot());
128         return reinterpret_cast<HandleSlot>(m_data & ~UsingSingleSlotFlag);
129     }
130
131     void setMap(TransitionMap* map)
132     {
133         ASSERT(isUsingSingleSlot());
134         
135         if (HandleSlot slot = this->slot())
136             HandleHeap::heapFor(slot)->deallocate(slot);
137
138         // This implicitly clears the flag that indicates we're using a single transition
139         m_data = reinterpret_cast<intptr_t>(map);
140
141         ASSERT(!isUsingSingleSlot());
142     }
143
144     Structure* singleTransition() const
145     {
146         ASSERT(isUsingSingleSlot());
147         if (HandleSlot slot = this->slot()) {
148             if (*slot)
149                 return reinterpret_cast<Structure*>(slot->asCell());
150         }
151         return 0;
152     }
153     
154     void setSingleTransition(JSGlobalData& globalData, Structure* structure)
155     {
156         ASSERT(isUsingSingleSlot());
157         HandleSlot slot = this->slot();
158         if (!slot) {
159             slot = globalData.allocateGlobalHandle();
160             HandleHeap::heapFor(slot)->makeWeak(slot, 0, 0);
161             m_data = reinterpret_cast<intptr_t>(slot) | UsingSingleSlotFlag;
162         }
163         HandleHeap::heapFor(slot)->writeBarrier(slot, reinterpret_cast<JSCell*>(structure));
164         *slot = reinterpret_cast<JSCell*>(structure);
165     }
166
167     intptr_t m_data;
168 };
169
170 } // namespace JSC
171
172 #endif // StructureTransitionTable_h