Renaming SpecInt32, SpecInt52, MachineInt to SpecInt32Only, SpecInt52Only, AnyInt.
[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 #ifndef DFGUseKind_h
27 #define DFGUseKind_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGNodeFlags.h"
32 #include "SpeculatedType.h"
33 #include <wtf/PrintStream.h>
34
35 namespace JSC { namespace DFG {
36
37 enum UseKind {
38     // The DFG has 3 representations of values used:
39
40     // 1. The JSValue representation for a JSValue that must be stored in a GP
41     //    register (or a GP register pair), and follows rules for boxing and unboxing
42     //    that allow the JSValue to be stored as either fully boxed JSValues, or
43     //    unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate.
44     UntypedUse, // UntypedUse must come first (value 0).
45     Int32Use,
46     KnownInt32Use,
47     AnyIntUse,
48     NumberUse,
49     RealNumberUse,
50     BooleanUse,
51     KnownBooleanUse,
52     CellUse,
53     KnownCellUse,
54     CellOrOtherUse,
55     ObjectUse,
56     FunctionUse,
57     FinalObjectUse,
58     RegExpObjectUse,
59     ObjectOrOtherUse,
60     StringIdentUse,
61     StringUse,
62     StringOrOtherUse,
63     KnownStringUse,
64     KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects).
65     SymbolUse,
66     StringObjectUse,
67     StringOrStringObjectUse,
68     NotStringVarUse,
69     NotCellUse,
70     OtherUse,
71     MiscUse,
72
73     // 2. The Double representation for an unboxed double value that must be stored
74     //    in an FP register.
75     DoubleRepUse,
76     DoubleRepRealUse,
77     DoubleRepAnyIntUse,
78
79     // 3. The Int52 representation for an unboxed integer value that must be stored
80     //    in a GP register.
81     Int52RepUse,
82
83     LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
84 };
85
86 inline SpeculatedType typeFilterFor(UseKind useKind)
87 {
88     switch (useKind) {
89     case UntypedUse:
90         return SpecFullTop;
91     case Int32Use:
92     case KnownInt32Use:
93         return SpecInt32Only;
94     case Int52RepUse:
95         return SpecAnyInt;
96     case AnyIntUse:
97         return SpecInt32Only | SpecAnyIntAsDouble;
98     case NumberUse:
99         return SpecBytecodeNumber;
100     case RealNumberUse:
101         return SpecBytecodeRealNumber;
102     case DoubleRepUse:
103         return SpecFullDouble;
104     case DoubleRepRealUse:
105         return SpecDoubleReal;
106     case DoubleRepAnyIntUse:
107         return SpecAnyIntAsDouble;
108     case BooleanUse:
109     case KnownBooleanUse:
110         return SpecBoolean;
111     case CellUse:
112     case KnownCellUse:
113         return SpecCell;
114     case CellOrOtherUse:
115         return SpecCell | SpecOther;
116     case ObjectUse:
117         return SpecObject;
118     case FunctionUse:
119         return SpecFunction;
120     case FinalObjectUse:
121         return SpecFinalObject;
122     case RegExpObjectUse:
123         return SpecRegExpObject;
124     case ObjectOrOtherUse:
125         return SpecObject | SpecOther;
126     case StringIdentUse:
127         return SpecStringIdent;
128     case StringUse:
129     case KnownStringUse:
130         return SpecString;
131     case StringOrOtherUse:
132         return SpecString | SpecOther;
133     case KnownPrimitiveUse:
134         return SpecHeapTop & ~SpecObject;
135     case SymbolUse:
136         return SpecSymbol;
137     case StringObjectUse:
138         return SpecStringObject;
139     case StringOrStringObjectUse:
140         return SpecString | SpecStringObject;
141     case NotStringVarUse:
142         return ~SpecStringVar;
143     case NotCellUse:
144         return ~SpecCell;
145     case OtherUse:
146         return SpecOther;
147     case MiscUse:
148         return SpecMisc;
149     default:
150         RELEASE_ASSERT_NOT_REACHED();
151         return SpecFullTop;
152     }
153 }
154
155 inline bool shouldNotHaveTypeCheck(UseKind kind)
156 {
157     switch (kind) {
158     case UntypedUse:
159     case KnownInt32Use:
160     case KnownCellUse:
161     case KnownStringUse:
162     case KnownPrimitiveUse:
163     case KnownBooleanUse:
164     case Int52RepUse:
165     case DoubleRepUse:
166         return true;
167     default:
168         return false;
169     }
170 }
171
172 inline bool mayHaveTypeCheck(UseKind kind)
173 {
174     return !shouldNotHaveTypeCheck(kind);
175 }
176
177 inline bool isNumerical(UseKind kind)
178 {
179     switch (kind) {
180     case Int32Use:
181     case KnownInt32Use:
182     case NumberUse:
183     case RealNumberUse:
184     case Int52RepUse:
185     case DoubleRepUse:
186     case DoubleRepRealUse:
187     case AnyIntUse:
188     case DoubleRepAnyIntUse:
189         return true;
190     default:
191         return false;
192     }
193 }
194
195 inline bool isDouble(UseKind kind)
196 {
197     switch (kind) {
198     case DoubleRepUse:
199     case DoubleRepRealUse:
200     case DoubleRepAnyIntUse:
201         return true;
202     default:
203         return false;
204     }
205 }
206
207 // Returns true if the use kind only admits cells, and is therefore appropriate for
208 // SpeculateCellOperand in the DFG or lowCell() in the FTL.
209 inline bool isCell(UseKind kind)
210 {
211     switch (kind) {
212     case CellUse:
213     case KnownCellUse:
214     case ObjectUse:
215     case FunctionUse:
216     case FinalObjectUse:
217     case RegExpObjectUse:
218     case StringIdentUse:
219     case StringUse:
220     case KnownStringUse:
221     case SymbolUse:
222     case StringObjectUse:
223     case StringOrStringObjectUse:
224         return true;
225     default:
226         return false;
227     }
228 }
229
230 // Returns true if it uses structure in a way that could be clobbered by
231 // things that change the structure.
232 inline bool usesStructure(UseKind kind)
233 {
234     switch (kind) {
235     case StringObjectUse:
236     case StringOrStringObjectUse:
237         return true;
238     default:
239         return false;
240     }
241 }
242
243 // Returns true if we've already guaranteed the type 
244 inline bool alreadyChecked(UseKind kind, SpeculatedType type)
245 {
246     // If the check involves the structure then we need to know more than just the type to be sure
247     // that the check is done.
248     if (usesStructure(kind))
249         return false;
250     
251     return !(type & ~typeFilterFor(kind));
252 }
253
254 inline UseKind useKindForResult(NodeFlags result)
255 {
256     ASSERT(!(result & ~NodeResultMask));
257     switch (result) {
258     case NodeResultInt52:
259         return Int52RepUse;
260     case NodeResultDouble:
261         return DoubleRepUse;
262     default:
263         return UntypedUse;
264     }
265 }
266
267 } } // namespace JSC::DFG
268
269 namespace WTF {
270
271 void printInternal(PrintStream&, JSC::DFG::UseKind);
272
273 } // namespace WTF
274
275 #endif // ENABLE(DFG_JIT)
276
277 #endif // DFGUseKind_h
278