[LFC] Devirtualize FormattingState
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGUseKind.h
1 /*
2  * Copyright (C) 2013-2016 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 #pragma once
27
28 #if ENABLE(DFG_JIT)
29
30 #include "DFGNodeFlags.h"
31 #include "SpeculatedType.h"
32 #include <wtf/PrintStream.h>
33
34 namespace JSC { namespace DFG {
35
36 enum UseKind {
37     // The DFG has 3 representations of values used:
38
39     // 1. The JSValue representation for a JSValue that must be stored in a GP
40     //    register (or a GP register pair), and follows rules for boxing and unboxing
41     //    that allow the JSValue to be stored as either fully boxed JSValues, or
42     //    unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate.
43     UntypedUse, // UntypedUse must come first (value 0).
44     Int32Use,
45     KnownInt32Use,
46     AnyIntUse,
47     NumberUse,
48     RealNumberUse,
49     BooleanUse,
50     KnownBooleanUse,
51     CellUse,
52     KnownCellUse,
53     CellOrOtherUse,
54     ObjectUse,
55     ArrayUse,
56     FunctionUse,
57     FinalObjectUse,
58     PromiseObjectUse,
59     RegExpObjectUse,
60     ProxyObjectUse,
61     DerivedArrayUse,
62     ObjectOrOtherUse,
63     StringIdentUse,
64     StringUse,
65     StringOrOtherUse,
66     KnownStringUse,
67     KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects).
68     SymbolUse,
69     BigIntUse,
70     DateObjectUse,
71     MapObjectUse,
72     SetObjectUse,
73     WeakMapObjectUse,
74     WeakSetObjectUse,
75     DataViewObjectUse,
76     StringObjectUse,
77     StringOrStringObjectUse,
78     NotStringVarUse,
79     NotSymbolUse,
80     NotCellUse,
81     KnownOtherUse,
82     OtherUse,
83     MiscUse,
84
85     // 2. The Double representation for an unboxed double value that must be stored
86     //    in an FP register.
87     DoubleRepUse,
88     DoubleRepRealUse,
89     DoubleRepAnyIntUse,
90
91     // 3. The Int52 representation for an unboxed integer value that must be stored
92     //    in a GP register.
93     Int52RepUse,
94
95     LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
96 };
97
98 inline SpeculatedType typeFilterFor(UseKind useKind)
99 {
100     switch (useKind) {
101     case UntypedUse:
102         return SpecBytecodeTop;
103     case Int32Use:
104     case KnownInt32Use:
105         return SpecInt32Only;
106     case Int52RepUse:
107         return SpecInt52Any;
108     case AnyIntUse:
109         return SpecInt32Only | SpecAnyIntAsDouble;
110     case NumberUse:
111         return SpecBytecodeNumber;
112     case RealNumberUse:
113         return SpecBytecodeRealNumber;
114     case DoubleRepUse:
115         return SpecFullDouble;
116     case DoubleRepRealUse:
117         return SpecDoubleReal;
118     case DoubleRepAnyIntUse:
119         return SpecAnyIntAsDouble;
120     case BooleanUse:
121     case KnownBooleanUse:
122         return SpecBoolean;
123     case CellUse:
124     case KnownCellUse:
125         return SpecCellCheck;
126     case CellOrOtherUse:
127         return SpecCellCheck | SpecOther;
128     case ObjectUse:
129         return SpecObject;
130     case ArrayUse:
131         return SpecArray;
132     case FunctionUse:
133         return SpecFunction;
134     case FinalObjectUse:
135         return SpecFinalObject;
136     case RegExpObjectUse:
137         return SpecRegExpObject;
138     case ProxyObjectUse:
139         return SpecProxyObject;
140     case DerivedArrayUse:
141         return SpecDerivedArray;
142     case ObjectOrOtherUse:
143         return SpecObject | SpecOther;
144     case StringIdentUse:
145         return SpecStringIdent;
146     case StringUse:
147     case KnownStringUse:
148         return SpecString;
149     case StringOrOtherUse:
150         return SpecString | SpecOther;
151     case KnownPrimitiveUse:
152         return SpecHeapTop & ~SpecObject;
153     case SymbolUse:
154         return SpecSymbol;
155     case BigIntUse:
156         return SpecBigInt;
157     case PromiseObjectUse:
158         return SpecPromiseObject;
159     case DateObjectUse:
160         return SpecDateObject;
161     case MapObjectUse:
162         return SpecMapObject;
163     case SetObjectUse:
164         return SpecSetObject;
165     case WeakMapObjectUse:
166         return SpecWeakMapObject;
167     case WeakSetObjectUse:
168         return SpecWeakSetObject;
169     case DataViewObjectUse:
170         return SpecDataViewObject;
171     case StringObjectUse:
172         return SpecStringObject;
173     case StringOrStringObjectUse:
174         return SpecString | SpecStringObject;
175     case NotStringVarUse:
176         return ~SpecStringVar;
177     case NotSymbolUse:
178         return ~SpecSymbol;
179     case NotCellUse:
180         return ~SpecCellCheck;
181     case KnownOtherUse:
182     case OtherUse:
183         return SpecOther;
184     case MiscUse:
185         return SpecMisc;
186     default:
187         RELEASE_ASSERT_NOT_REACHED();
188         return SpecFullTop;
189     }
190 }
191
192 inline bool shouldNotHaveTypeCheck(UseKind kind)
193 {
194     switch (kind) {
195     case UntypedUse:
196     case KnownInt32Use:
197     case KnownCellUse:
198     case KnownStringUse:
199     case KnownPrimitiveUse:
200     case KnownBooleanUse:
201     case KnownOtherUse:
202     case Int52RepUse:
203     case DoubleRepUse:
204         return true;
205     default:
206         return false;
207     }
208 }
209
210 inline bool mayHaveTypeCheck(UseKind kind)
211 {
212     return !shouldNotHaveTypeCheck(kind);
213 }
214
215 inline bool isNumerical(UseKind kind)
216 {
217     switch (kind) {
218     case Int32Use:
219     case KnownInt32Use:
220     case NumberUse:
221     case RealNumberUse:
222     case Int52RepUse:
223     case DoubleRepUse:
224     case DoubleRepRealUse:
225     case AnyIntUse:
226     case DoubleRepAnyIntUse:
227         return true;
228     default:
229         return false;
230     }
231 }
232
233 inline bool isDouble(UseKind kind)
234 {
235     switch (kind) {
236     case DoubleRepUse:
237     case DoubleRepRealUse:
238     case DoubleRepAnyIntUse:
239         return true;
240     default:
241         return false;
242     }
243 }
244
245 // Returns true if the use kind only admits cells, and is therefore appropriate for
246 // SpeculateCellOperand in the DFG or lowCell() in the FTL.
247 inline bool isCell(UseKind kind)
248 {
249     switch (kind) {
250     case CellUse:
251     case KnownCellUse:
252     case ObjectUse:
253     case ArrayUse:
254     case FunctionUse:
255     case FinalObjectUse:
256     case RegExpObjectUse:
257     case PromiseObjectUse:
258     case ProxyObjectUse:
259     case DerivedArrayUse:
260     case StringIdentUse:
261     case StringUse:
262     case KnownStringUse:
263     case SymbolUse:
264     case BigIntUse:
265     case StringObjectUse:
266     case StringOrStringObjectUse:
267     case DateObjectUse:
268     case MapObjectUse:
269     case SetObjectUse:
270     case WeakMapObjectUse:
271     case WeakSetObjectUse:
272     case DataViewObjectUse:
273         return true;
274     default:
275         return false;
276     }
277 }
278
279 // Returns true if we've already guaranteed the type 
280 inline bool alreadyChecked(UseKind kind, SpeculatedType type)
281 {
282     return !(type & ~typeFilterFor(kind));
283 }
284
285 inline UseKind useKindForResult(NodeFlags result)
286 {
287     ASSERT(!(result & ~NodeResultMask));
288     switch (result) {
289     case NodeResultInt52:
290         return Int52RepUse;
291     case NodeResultDouble:
292         return DoubleRepUse;
293     default:
294         return UntypedUse;
295     }
296 }
297
298 inline bool checkMayCrashIfInputIsEmpty(UseKind kind)
299 {
300 #if USE(JSVALUE64)
301     switch (kind) {
302     case UntypedUse:
303     case Int32Use:
304     case KnownInt32Use:
305     case AnyIntUse:
306     case NumberUse:
307     case BooleanUse:
308     case KnownBooleanUse:
309     case CellUse:
310     case KnownCellUse:
311     case CellOrOtherUse:
312     case KnownOtherUse:
313     case OtherUse:
314     case MiscUse:
315     case NotCellUse:
316         return false;
317     default:
318         return true;
319     }
320 #else
321     UNUSED_PARAM(kind);
322     return true;
323 #endif
324 }
325
326 } } // namespace JSC::DFG
327
328 namespace WTF {
329
330 void printInternal(PrintStream&, JSC::DFG::UseKind);
331
332 } // namespace WTF
333
334 #endif // ENABLE(DFG_JIT)