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