js/src/jit/IonTypes.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial