]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGStructureAbstractValue.h
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / dfg / DFGStructureAbstractValue.h
CommitLineData
93a37866
A
1/*
2 * Copyright (C) 2011, 2012, 2013 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. ``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 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 DFGStructureAbstractValue_h
27#define DFGStructureAbstractValue_h
28
29#include <wtf/Platform.h>
30
31#if ENABLE(DFG_JIT)
32
33#include "JSCell.h"
34#include "SpeculatedType.h"
35#include "StructureSet.h"
36
37namespace JSC { namespace DFG {
38
39class StructureAbstractValue {
40public:
41 StructureAbstractValue()
42 : m_structure(0)
43 {
44 }
45
46 StructureAbstractValue(Structure* structure)
47 : m_structure(structure)
48 {
49 }
50
51 StructureAbstractValue(const StructureSet& set)
52 {
53 switch (set.size()) {
54 case 0:
55 m_structure = 0;
56 break;
57
58 case 1:
59 m_structure = set[0];
60 break;
61
62 default:
63 m_structure = topValue();
64 break;
65 }
66 }
67
68 void clear()
69 {
70 m_structure = 0;
71 }
72
73 void makeTop()
74 {
75 m_structure = topValue();
76 }
77
78 static StructureAbstractValue top()
79 {
80 StructureAbstractValue value;
81 value.makeTop();
82 return value;
83 }
84
85 void add(Structure* structure)
86 {
87 ASSERT(!contains(structure) && !isTop());
88 if (m_structure)
89 makeTop();
90 else
91 m_structure = structure;
92 }
93
94 bool addAll(const StructureSet& other)
95 {
96 if (isTop() || !other.size())
97 return false;
98 if (other.size() > 1) {
99 makeTop();
100 return true;
101 }
102 if (!m_structure) {
103 m_structure = other[0];
104 return true;
105 }
106 if (m_structure == other[0])
107 return false;
108 makeTop();
109 return true;
110 }
111
112 bool addAll(const StructureAbstractValue& other)
113 {
114 if (!other.m_structure)
115 return false;
116 if (isTop())
117 return false;
118 if (other.isTop()) {
119 makeTop();
120 return true;
121 }
122 if (m_structure) {
123 if (m_structure == other.m_structure)
124 return false;
125 makeTop();
126 return true;
127 }
128 m_structure = other.m_structure;
129 return true;
130 }
131
132 bool contains(Structure* structure) const
133 {
134 if (isTop())
135 return true;
136 if (m_structure == structure)
137 return true;
138 return false;
139 }
140
141 bool isSubsetOf(const StructureSet& other) const
142 {
143 if (isTop())
144 return false;
145 if (!m_structure)
146 return true;
147 return other.contains(m_structure);
148 }
149
150 bool doesNotContainAnyOtherThan(Structure* structure) const
151 {
152 if (isTop())
153 return false;
154 if (!m_structure)
155 return true;
156 return m_structure == structure;
157 }
158
159 bool isSupersetOf(const StructureSet& other) const
160 {
161 if (isTop())
162 return true;
163 if (!other.size())
164 return true;
165 if (other.size() > 1)
166 return false;
167 return m_structure == other[0];
168 }
169
170 bool isSubsetOf(const StructureAbstractValue& other) const
171 {
172 if (other.isTop())
173 return true;
174 if (isTop())
175 return false;
176 if (m_structure) {
177 if (other.m_structure)
178 return m_structure == other.m_structure;
179 return false;
180 }
181 return true;
182 }
183
184 bool isSupersetOf(const StructureAbstractValue& other) const
185 {
186 return other.isSubsetOf(*this);
187 }
188
189 void filter(const StructureSet& other)
190 {
191 if (!m_structure)
192 return;
193
194 if (isTop()) {
195 switch (other.size()) {
196 case 0:
197 m_structure = 0;
198 return;
199
200 case 1:
201 m_structure = other[0];
202 return;
203
204 default:
205 return;
206 }
207 }
208
209 if (other.contains(m_structure))
210 return;
211
212 m_structure = 0;
213 }
214
215 void filter(const StructureAbstractValue& other)
216 {
217 if (isTop()) {
218 m_structure = other.m_structure;
219 return;
220 }
221 if (m_structure == other.m_structure)
222 return;
223 if (other.isTop())
224 return;
225 m_structure = 0;
226 }
227
228 void filter(SpeculatedType other)
229 {
230 if (!(other & SpecCell)) {
231 clear();
232 return;
233 }
234
235 if (isClearOrTop())
236 return;
237
238 if (!(speculationFromStructure(m_structure) & other))
239 m_structure = 0;
240 }
241
242 bool isClear() const
243 {
244 return !m_structure;
245 }
246
247 bool isTop() const { return m_structure == topValue(); }
248
249 bool isClearOrTop() const { return m_structure <= topValue(); }
250 bool isNeitherClearNorTop() const { return !isClearOrTop(); }
251
252 size_t size() const
253 {
254 ASSERT(!isTop());
255 return !!m_structure;
256 }
257
258 Structure* at(size_t i) const
259 {
260 ASSERT(!isTop());
261 ASSERT(m_structure);
262 ASSERT_UNUSED(i, !i);
263 return m_structure;
264 }
265
266 Structure* operator[](size_t i) const
267 {
268 return at(i);
269 }
270
271 Structure* last() const
272 {
273 return at(0);
274 }
275
276 SpeculatedType speculationFromStructures() const
277 {
278 if (isTop())
279 return SpecCell;
280 if (isClear())
281 return SpecNone;
282 return speculationFromStructure(m_structure);
283 }
284
285 bool hasSingleton() const
286 {
287 return isNeitherClearNorTop();
288 }
289
290 Structure* singleton() const
291 {
292 ASSERT(isNeitherClearNorTop());
293 return m_structure;
294 }
295
296 bool operator==(const StructureAbstractValue& other) const
297 {
298 return m_structure == other.m_structure;
299 }
300
301 void dump(PrintStream& out) const
302 {
303 if (isTop()) {
304 out.print("TOP");
305 return;
306 }
307
308 out.print("[");
309 if (m_structure)
310 out.print(RawPointer(m_structure), "(", m_structure->classInfo()->className, ")");
311 out.print("]");
312 }
313
314private:
315 static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
316
317 // NB. This must have a trivial destructor.
318
319 // This can only remember one structure at a time.
320 Structure* m_structure;
321};
322
323} } // namespace JSC::DFG
324
325#endif // ENABLE(DFG_JIT)
326
327#endif // DFGStructureAbstractValue_h
328
329