2147b9bcc94726511d474f10cd21e5bcafe179d3
[WebKit-https.git] / Source / JavaScriptCore / bytecode / SpeculatedType.cpp
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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "SpeculatedType.h"
31
32 #include "Arguments.h"
33 #include "JSArray.h"
34 #include "JSFunction.h"
35 #include "Operations.h"
36 #include "StringObject.h"
37 #include "ValueProfile.h"
38 #include <wtf/BoundsCheckedPointer.h>
39 #include <wtf/StringPrintStream.h>
40
41 namespace JSC {
42
43 void dumpSpeculation(PrintStream& out, SpeculatedType value)
44 {
45     if (value == SpecNone) {
46         out.print("None");
47         return;
48     }
49     
50     StringPrintStream myOut;
51     
52     bool isTop = true;
53     
54     if ((value & SpecCell) == SpecCell)
55         myOut.print("Cell");
56     else {
57         if ((value & SpecObject) == SpecObject)
58             myOut.print("Object");
59         else {
60             if (value & SpecCellOther)
61                 myOut.print("Othercell");
62             else
63                 isTop = false;
64     
65             if (value & SpecObjectOther)
66                 myOut.print("Otherobj");
67             else
68                 isTop = false;
69     
70             if (value & SpecFinalObject)
71                 myOut.print("Final");
72             else
73                 isTop = false;
74
75             if (value & SpecArray)
76                 myOut.print("Array");
77             else
78                 isTop = false;
79     
80             if (value & SpecInt8Array)
81                 myOut.print("Int8array");
82             else
83                 isTop = false;
84     
85             if (value & SpecInt16Array)
86                 myOut.print("Int16array");
87             else
88                 isTop = false;
89     
90             if (value & SpecInt32Array)
91                 myOut.print("Int32array");
92             else
93                 isTop = false;
94     
95             if (value & SpecUint8Array)
96                 myOut.print("Uint8array");
97             else
98                 isTop = false;
99
100             if (value & SpecUint8ClampedArray)
101                 myOut.print("Uint8clampedarray");
102             else
103                 isTop = false;
104     
105             if (value & SpecUint16Array)
106                 myOut.print("Uint16array");
107             else
108                 isTop = false;
109     
110             if (value & SpecUint32Array)
111                 myOut.print("Uint32array");
112             else
113                 isTop = false;
114     
115             if (value & SpecFloat32Array)
116                 myOut.print("Float32array");
117             else
118                 isTop = false;
119     
120             if (value & SpecFloat64Array)
121                 myOut.print("Float64array");
122             else
123                 isTop = false;
124     
125             if (value & SpecFunction)
126                 myOut.print("Function");
127             else
128                 isTop = false;
129     
130             if (value & SpecArguments)
131                 myOut.print("Arguments");
132             else
133                 isTop = false;
134     
135             if (value & SpecStringObject)
136                 myOut.print("Stringobject");
137             else
138                 isTop = false;
139         }
140
141         if ((value & SpecString) == SpecString)
142             myOut.print("String");
143         else {
144             if (value & SpecStringIdent)
145                 myOut.print("Stringident");
146             else
147                 isTop = false;
148             
149             if (value & SpecStringVar)
150                 myOut.print("Stringvar");
151             else
152                 isTop = false;
153         }
154     }
155     
156     if (value & SpecInt32)
157         myOut.print("Int");
158     else
159         isTop = false;
160     
161     if ((value & SpecDouble) == SpecDouble)
162         myOut.print("Double");
163     else {
164         if (value & SpecDoubleReal)
165             myOut.print("Doublereal");
166         else
167             isTop = false;
168         
169         if (value & SpecDoubleNaN)
170             myOut.print("Doublenan");
171         else
172             isTop = false;
173     }
174     
175     if (value & SpecBoolean)
176         myOut.print("Bool");
177     else
178         isTop = false;
179     
180     if (value & SpecOther)
181         myOut.print("Other");
182     else
183         isTop = false;
184     
185     if (isTop)
186         out.print("Top");
187     else
188         out.print(myOut.toCString());
189     
190     if (value & SpecEmpty)
191         out.print("Empty");
192 }
193
194 // We don't expose this because we don't want anyone relying on the fact that this method currently
195 // just returns string constants.
196 static const char* speculationToAbbreviatedString(SpeculatedType prediction)
197 {
198     if (isFinalObjectSpeculation(prediction))
199         return "<Final>";
200     if (isArraySpeculation(prediction))
201         return "<Array>";
202     if (isStringIdentSpeculation(prediction))
203         return "<StringIdent>";
204     if (isStringSpeculation(prediction))
205         return "<String>";
206     if (isFunctionSpeculation(prediction))
207         return "<Function>";
208     if (isInt8ArraySpeculation(prediction))
209         return "<Int8array>";
210     if (isInt16ArraySpeculation(prediction))
211         return "<Int16array>";
212     if (isInt32ArraySpeculation(prediction))
213         return "<Int32array>";
214     if (isUint8ArraySpeculation(prediction))
215         return "<Uint8array>";
216     if (isUint16ArraySpeculation(prediction))
217         return "<Uint16array>";
218     if (isUint32ArraySpeculation(prediction))
219         return "<Uint32array>";
220     if (isFloat32ArraySpeculation(prediction))
221         return "<Float32array>";
222     if (isFloat64ArraySpeculation(prediction))
223         return "<Float64array>";
224     if (isArgumentsSpeculation(prediction))
225         return "<Arguments>";
226     if (isStringObjectSpeculation(prediction))
227         return "<StringObject>";
228     if (isStringOrStringObjectSpeculation(prediction))
229         return "<StringOrStringObject>";
230     if (isObjectSpeculation(prediction))
231         return "<Object>";
232     if (isCellSpeculation(prediction))
233         return "<Cell>";
234     if (isInt32Speculation(prediction))
235         return "<Int32>";
236     if (isDoubleSpeculation(prediction))
237         return "<Double>";
238     if (isNumberSpeculation(prediction))
239         return "<Number>";
240     if (isBooleanSpeculation(prediction))
241         return "<Boolean>";
242     if (isOtherSpeculation(prediction))
243         return "<Other>";
244     return "";
245 }
246
247 void dumpSpeculationAbbreviated(PrintStream& out, SpeculatedType value)
248 {
249     out.print(speculationToAbbreviatedString(value));
250 }
251
252 SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
253 {
254     if (classInfo == &JSFinalObject::s_info)
255         return SpecFinalObject;
256     
257     if (classInfo == &JSArray::s_info)
258         return SpecArray;
259     
260     if (classInfo == &Arguments::s_info)
261         return SpecArguments;
262     
263     if (classInfo == &StringObject::s_info)
264         return SpecStringObject;
265     
266     if (classInfo->isSubClassOf(&JSFunction::s_info))
267         return SpecFunction;
268     
269     if (classInfo->typedArrayStorageType != TypedArrayNone) {
270         switch (classInfo->typedArrayStorageType) {
271         case TypedArrayInt8:
272             return SpecInt8Array;
273         case TypedArrayInt16:
274             return SpecInt16Array;
275         case TypedArrayInt32:
276             return SpecInt32Array;
277         case TypedArrayUint8:
278             return SpecUint8Array;
279         case TypedArrayUint8Clamped:
280             return SpecUint8ClampedArray;
281         case TypedArrayUint16:
282             return SpecUint16Array;
283         case TypedArrayUint32:
284             return SpecUint32Array;
285         case TypedArrayFloat32:
286             return SpecFloat32Array;
287         case TypedArrayFloat64:
288             return SpecFloat64Array;
289         default:
290             break;
291         }
292     }
293     
294     if (classInfo->isSubClassOf(&JSObject::s_info))
295         return SpecObjectOther;
296     
297     return SpecCellOther;
298 }
299
300 SpeculatedType speculationFromStructure(Structure* structure)
301 {
302     if (structure->typeInfo().type() == StringType)
303         return SpecString;
304     return speculationFromClassInfo(structure->classInfo());
305 }
306
307 SpeculatedType speculationFromCell(JSCell* cell)
308 {
309     if (JSString* string = jsDynamicCast<JSString*>(cell)) {
310         if (const StringImpl* impl = string->tryGetValueImpl()) {
311             if (impl->isIdentifier())
312                 return SpecStringIdent;
313         }
314         return SpecStringVar;
315     }
316     return speculationFromStructure(cell->structure());
317 }
318
319 SpeculatedType speculationFromValue(JSValue value)
320 {
321     if (value.isEmpty())
322         return SpecEmpty;
323     if (value.isInt32())
324         return SpecInt32;
325     if (value.isDouble()) {
326         double number = value.asNumber();
327         if (number == number)
328             return SpecDoubleReal;
329         return SpecDoubleNaN;
330     }
331     if (value.isCell())
332         return speculationFromCell(value.asCell());
333     if (value.isBoolean())
334         return SpecBoolean;
335     ASSERT(value.isUndefinedOrNull());
336     return SpecOther;
337 }
338
339 } // namespace JSC
340