Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_IonTypes_h
8 #define jit_IonTypes_h
10 #include "jstypes.h"
12 #include "js/Value.h"
14 namespace js {
15 namespace jit {
17 typedef uint32_t RecoverOffset;
18 typedef uint32_t SnapshotOffset;
19 typedef uint32_t BailoutId;
21 // The maximum size of any buffer associated with an assembler or code object.
22 // This is chosen to not overflow a signed integer, leaving room for an extra
23 // bit on offsets.
24 static const uint32_t MAX_BUFFER_SIZE = (1 << 30) - 1;
26 // Maximum number of scripted arg slots.
27 static const uint32_t SNAPSHOT_MAX_NARGS = 127;
29 static const SnapshotOffset INVALID_RECOVER_OFFSET = uint32_t(-1);
30 static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1);
32 // Different kinds of bailouts. When extending this enum, make sure to check
33 // the bits reserved for bailout kinds in Bailouts.h
34 enum BailoutKind
35 {
36 // A normal bailout triggered from type, shape, and assorted overflow
37 // guards in the compiler.
38 Bailout_Normal,
40 // A bailout at the very start of a function indicates that there may be
41 // a type mismatch in the arguments that necessitates a reflow.
42 Bailout_ArgumentCheck,
44 // A bailout triggered by a bounds-check failure.
45 Bailout_BoundsCheck,
47 // A shape guard based on TI information failed.
48 Bailout_ShapeGuard,
50 // A bailout caused by invalid assumptions based on Baseline code.
51 Bailout_BaselineInfo,
53 // A bailout to baseline from Ion on exception to handle Debugger hooks.
54 Bailout_IonExceptionDebugMode,
55 };
57 inline const char *
58 BailoutKindString(BailoutKind kind)
59 {
60 switch (kind) {
61 case Bailout_Normal:
62 return "Bailout_Normal";
63 case Bailout_ArgumentCheck:
64 return "Bailout_ArgumentCheck";
65 case Bailout_BoundsCheck:
66 return "Bailout_BoundsCheck";
67 case Bailout_ShapeGuard:
68 return "Bailout_ShapeGuard";
69 case Bailout_BaselineInfo:
70 return "Bailout_BaselineInfo";
71 case Bailout_IonExceptionDebugMode:
72 return "Bailout_IonExceptionDebugMode";
73 default:
74 MOZ_ASSUME_UNREACHABLE("Invalid BailoutKind");
75 }
76 }
78 static const uint32_t ELEMENT_TYPE_BITS = 5;
79 static const uint32_t ELEMENT_TYPE_SHIFT = 0;
80 static const uint32_t ELEMENT_TYPE_MASK = (1 << ELEMENT_TYPE_BITS) - 1;
81 static const uint32_t VECTOR_SCALE_BITS = 2;
82 static const uint32_t VECTOR_SCALE_SHIFT = ELEMENT_TYPE_BITS + ELEMENT_TYPE_SHIFT;
83 static const uint32_t VECTOR_SCALE_MASK = (1 << VECTOR_SCALE_BITS) - 1;
85 // The ordering of this enumeration is important: Anything < Value is a
86 // specialized type. Furthermore, anything < String has trivial conversion to
87 // a number.
88 enum MIRType
89 {
90 MIRType_Undefined,
91 MIRType_Null,
92 MIRType_Boolean,
93 MIRType_Int32,
94 MIRType_Double,
95 MIRType_Float32,
96 MIRType_String,
97 MIRType_Object,
98 MIRType_MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
99 MIRType_MagicOptimizedOut, // JS_OPTIMIZED_OUT magic value.
100 MIRType_MagicHole, // JS_ELEMENTS_HOLE magic value.
101 MIRType_MagicIsConstructing, // JS_IS_CONSTRUCTING magic value.
102 MIRType_Value,
103 MIRType_None, // Invalid, used as a placeholder.
104 MIRType_Slots, // A slots vector
105 MIRType_Elements, // An elements vector
106 MIRType_Pointer, // An opaque pointer that receives no special treatment
107 MIRType_Shape, // A Shape pointer.
108 MIRType_ForkJoinContext, // js::ForkJoinContext*
109 MIRType_Last = MIRType_ForkJoinContext,
110 MIRType_Float32x4 = MIRType_Float32 | (2 << VECTOR_SCALE_SHIFT),
111 MIRType_Int32x4 = MIRType_Int32 | (2 << VECTOR_SCALE_SHIFT),
112 MIRType_Doublex2 = MIRType_Double | (1 << VECTOR_SCALE_SHIFT)
113 };
115 static inline MIRType
116 ElementType(MIRType type)
117 {
118 JS_STATIC_ASSERT(MIRType_Last <= ELEMENT_TYPE_MASK);
119 return static_cast<MIRType>((type >> ELEMENT_TYPE_SHIFT) & ELEMENT_TYPE_MASK);
120 }
122 static inline uint32_t
123 VectorSize(MIRType type)
124 {
125 return 1 << ((type >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK);
126 }
128 static inline MIRType
129 MIRTypeFromValueType(JSValueType type)
130 {
131 // This function does not deal with magic types. Magic constants should be
132 // filtered out in MIRTypeFromValue.
133 switch (type) {
134 case JSVAL_TYPE_DOUBLE:
135 return MIRType_Double;
136 case JSVAL_TYPE_INT32:
137 return MIRType_Int32;
138 case JSVAL_TYPE_UNDEFINED:
139 return MIRType_Undefined;
140 case JSVAL_TYPE_STRING:
141 return MIRType_String;
142 case JSVAL_TYPE_BOOLEAN:
143 return MIRType_Boolean;
144 case JSVAL_TYPE_NULL:
145 return MIRType_Null;
146 case JSVAL_TYPE_OBJECT:
147 return MIRType_Object;
148 case JSVAL_TYPE_UNKNOWN:
149 return MIRType_Value;
150 default:
151 MOZ_ASSUME_UNREACHABLE("unexpected jsval type");
152 }
153 }
155 static inline JSValueType
156 ValueTypeFromMIRType(MIRType type)
157 {
158 switch (type) {
159 case MIRType_Undefined:
160 return JSVAL_TYPE_UNDEFINED;
161 case MIRType_Null:
162 return JSVAL_TYPE_NULL;
163 case MIRType_Boolean:
164 return JSVAL_TYPE_BOOLEAN;
165 case MIRType_Int32:
166 return JSVAL_TYPE_INT32;
167 case MIRType_Float32: // Fall through, there's no JSVAL for Float32
168 case MIRType_Double:
169 return JSVAL_TYPE_DOUBLE;
170 case MIRType_String:
171 return JSVAL_TYPE_STRING;
172 case MIRType_MagicOptimizedArguments:
173 case MIRType_MagicOptimizedOut:
174 case MIRType_MagicHole:
175 case MIRType_MagicIsConstructing:
176 return JSVAL_TYPE_MAGIC;
177 default:
178 JS_ASSERT(type == MIRType_Object);
179 return JSVAL_TYPE_OBJECT;
180 }
181 }
183 static inline JSValueTag
184 MIRTypeToTag(MIRType type)
185 {
186 return JSVAL_TYPE_TO_TAG(ValueTypeFromMIRType(type));
187 }
189 static inline const char *
190 StringFromMIRType(MIRType type)
191 {
192 switch (type) {
193 case MIRType_Undefined:
194 return "Undefined";
195 case MIRType_Null:
196 return "Null";
197 case MIRType_Boolean:
198 return "Bool";
199 case MIRType_Int32:
200 return "Int32";
201 case MIRType_Double:
202 return "Double";
203 case MIRType_Float32:
204 return "Float32";
205 case MIRType_String:
206 return "String";
207 case MIRType_Object:
208 return "Object";
209 case MIRType_MagicOptimizedArguments:
210 return "MagicOptimizedArguments";
211 case MIRType_MagicOptimizedOut:
212 return "MagicOptimizedOut";
213 case MIRType_MagicHole:
214 return "MagicHole";
215 case MIRType_MagicIsConstructing:
216 return "MagicIsConstructing";
217 case MIRType_Value:
218 return "Value";
219 case MIRType_None:
220 return "None";
221 case MIRType_Slots:
222 return "Slots";
223 case MIRType_Elements:
224 return "Elements";
225 case MIRType_Pointer:
226 return "Pointer";
227 case MIRType_ForkJoinContext:
228 return "ForkJoinContext";
229 default:
230 MOZ_ASSUME_UNREACHABLE("Unknown MIRType.");
231 }
232 }
234 static inline bool
235 IsNumberType(MIRType type)
236 {
237 return type == MIRType_Int32 || type == MIRType_Double || type == MIRType_Float32;
238 }
240 static inline bool
241 IsFloatType(MIRType type)
242 {
243 return type == MIRType_Int32 || type == MIRType_Float32;
244 }
246 static inline bool
247 IsFloatingPointType(MIRType type)
248 {
249 return type == MIRType_Double || type == MIRType_Float32;
250 }
252 static inline bool
253 IsNullOrUndefined(MIRType type)
254 {
255 return type == MIRType_Null || type == MIRType_Undefined;
256 }
258 #ifdef DEBUG
259 // Track the pipeline of opcodes which has produced a snapshot.
260 #define TRACK_SNAPSHOTS 1
262 // Make sure registers are not modified between an instruction and
263 // its OsiPoint.
264 # if defined(JS_ION)
265 # define CHECK_OSIPOINT_REGISTERS 1
266 # endif
267 #endif
269 enum {
270 ArgType_General = 0x1,
271 ArgType_Double = 0x2,
272 ArgType_Float32 = 0x3,
274 RetType_Shift = 0x0,
275 ArgType_Shift = 0x2,
276 ArgType_Mask = 0x3
277 };
279 enum ABIFunctionType
280 {
281 // VM functions that take 0-9 non-double arguments
282 // and return a non-double value.
283 Args_General0 = ArgType_General << RetType_Shift,
284 Args_General1 = Args_General0 | (ArgType_General << (ArgType_Shift * 1)),
285 Args_General2 = Args_General1 | (ArgType_General << (ArgType_Shift * 2)),
286 Args_General3 = Args_General2 | (ArgType_General << (ArgType_Shift * 3)),
287 Args_General4 = Args_General3 | (ArgType_General << (ArgType_Shift * 4)),
288 Args_General5 = Args_General4 | (ArgType_General << (ArgType_Shift * 5)),
289 Args_General6 = Args_General5 | (ArgType_General << (ArgType_Shift * 6)),
290 Args_General7 = Args_General6 | (ArgType_General << (ArgType_Shift * 7)),
291 Args_General8 = Args_General7 | (ArgType_General << (ArgType_Shift * 8)),
293 // double f()
294 Args_Double_None = ArgType_Double << RetType_Shift,
296 // int f(double)
297 Args_Int_Double = Args_General0 | (ArgType_Double << ArgType_Shift),
299 // float f(float)
300 Args_Float32_Float32 = (ArgType_Float32 << RetType_Shift) | (ArgType_Float32 << ArgType_Shift),
302 // double f(double)
303 Args_Double_Double = Args_Double_None | (ArgType_Double << ArgType_Shift),
305 // double f(int)
306 Args_Double_Int = Args_Double_None | (ArgType_General << ArgType_Shift),
308 // double f(double, int)
309 Args_Double_DoubleInt = Args_Double_None |
310 (ArgType_General << (ArgType_Shift * 1)) |
311 (ArgType_Double << (ArgType_Shift * 2)),
313 // double f(double, double)
314 Args_Double_DoubleDouble = Args_Double_Double | (ArgType_Double << (ArgType_Shift * 2)),
316 // double f(int, double)
317 Args_Double_IntDouble = Args_Double_None |
318 (ArgType_Double << (ArgType_Shift * 1)) |
319 (ArgType_General << (ArgType_Shift * 2)),
321 // int f(int, double)
322 Args_Int_IntDouble = Args_General0 |
323 (ArgType_Double << (ArgType_Shift * 1)) |
324 (ArgType_General << (ArgType_Shift * 2))
325 };
327 } // namespace jit
328 } // namespace js
330 #endif /* jit_IonTypes_h */