js/src/jit/IonTypes.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/IonTypes.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,330 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef jit_IonTypes_h
    1.11 +#define jit_IonTypes_h
    1.12 +
    1.13 +#include "jstypes.h"
    1.14 +
    1.15 +#include "js/Value.h"
    1.16 +
    1.17 +namespace js {
    1.18 +namespace jit {
    1.19 +
    1.20 +typedef uint32_t RecoverOffset;
    1.21 +typedef uint32_t SnapshotOffset;
    1.22 +typedef uint32_t BailoutId;
    1.23 +
    1.24 +// The maximum size of any buffer associated with an assembler or code object.
    1.25 +// This is chosen to not overflow a signed integer, leaving room for an extra
    1.26 +// bit on offsets.
    1.27 +static const uint32_t MAX_BUFFER_SIZE = (1 << 30) - 1;
    1.28 +
    1.29 +// Maximum number of scripted arg slots.
    1.30 +static const uint32_t SNAPSHOT_MAX_NARGS = 127;
    1.31 +
    1.32 +static const SnapshotOffset INVALID_RECOVER_OFFSET = uint32_t(-1);
    1.33 +static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1);
    1.34 +
    1.35 +// Different kinds of bailouts. When extending this enum, make sure to check
    1.36 +// the bits reserved for bailout kinds in Bailouts.h
    1.37 +enum BailoutKind
    1.38 +{
    1.39 +    // A normal bailout triggered from type, shape, and assorted overflow
    1.40 +    // guards in the compiler.
    1.41 +    Bailout_Normal,
    1.42 +
    1.43 +    // A bailout at the very start of a function indicates that there may be
    1.44 +    // a type mismatch in the arguments that necessitates a reflow.
    1.45 +    Bailout_ArgumentCheck,
    1.46 +
    1.47 +    // A bailout triggered by a bounds-check failure.
    1.48 +    Bailout_BoundsCheck,
    1.49 +
    1.50 +    // A shape guard based on TI information failed.
    1.51 +    Bailout_ShapeGuard,
    1.52 +
    1.53 +    // A bailout caused by invalid assumptions based on Baseline code.
    1.54 +    Bailout_BaselineInfo,
    1.55 +
    1.56 +    // A bailout to baseline from Ion on exception to handle Debugger hooks.
    1.57 +    Bailout_IonExceptionDebugMode,
    1.58 +};
    1.59 +
    1.60 +inline const char *
    1.61 +BailoutKindString(BailoutKind kind)
    1.62 +{
    1.63 +    switch (kind) {
    1.64 +      case Bailout_Normal:
    1.65 +        return "Bailout_Normal";
    1.66 +      case Bailout_ArgumentCheck:
    1.67 +        return "Bailout_ArgumentCheck";
    1.68 +      case Bailout_BoundsCheck:
    1.69 +        return "Bailout_BoundsCheck";
    1.70 +      case Bailout_ShapeGuard:
    1.71 +        return "Bailout_ShapeGuard";
    1.72 +      case Bailout_BaselineInfo:
    1.73 +        return "Bailout_BaselineInfo";
    1.74 +      case Bailout_IonExceptionDebugMode:
    1.75 +        return "Bailout_IonExceptionDebugMode";
    1.76 +      default:
    1.77 +        MOZ_ASSUME_UNREACHABLE("Invalid BailoutKind");
    1.78 +    }
    1.79 +}
    1.80 +
    1.81 +static const uint32_t ELEMENT_TYPE_BITS = 5;
    1.82 +static const uint32_t ELEMENT_TYPE_SHIFT = 0;
    1.83 +static const uint32_t ELEMENT_TYPE_MASK = (1 << ELEMENT_TYPE_BITS) - 1;
    1.84 +static const uint32_t VECTOR_SCALE_BITS = 2;
    1.85 +static const uint32_t VECTOR_SCALE_SHIFT = ELEMENT_TYPE_BITS + ELEMENT_TYPE_SHIFT;
    1.86 +static const uint32_t VECTOR_SCALE_MASK = (1 << VECTOR_SCALE_BITS) - 1;
    1.87 +
    1.88 +// The ordering of this enumeration is important: Anything < Value is a
    1.89 +// specialized type. Furthermore, anything < String has trivial conversion to
    1.90 +// a number.
    1.91 +enum MIRType
    1.92 +{
    1.93 +    MIRType_Undefined,
    1.94 +    MIRType_Null,
    1.95 +    MIRType_Boolean,
    1.96 +    MIRType_Int32,
    1.97 +    MIRType_Double,
    1.98 +    MIRType_Float32,
    1.99 +    MIRType_String,
   1.100 +    MIRType_Object,
   1.101 +    MIRType_MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
   1.102 +    MIRType_MagicOptimizedOut,       // JS_OPTIMIZED_OUT magic value.
   1.103 +    MIRType_MagicHole,               // JS_ELEMENTS_HOLE magic value.
   1.104 +    MIRType_MagicIsConstructing,     // JS_IS_CONSTRUCTING magic value.
   1.105 +    MIRType_Value,
   1.106 +    MIRType_None,                    // Invalid, used as a placeholder.
   1.107 +    MIRType_Slots,                   // A slots vector
   1.108 +    MIRType_Elements,                // An elements vector
   1.109 +    MIRType_Pointer,                 // An opaque pointer that receives no special treatment
   1.110 +    MIRType_Shape,                   // A Shape pointer.
   1.111 +    MIRType_ForkJoinContext,         // js::ForkJoinContext*
   1.112 +    MIRType_Last = MIRType_ForkJoinContext,
   1.113 +    MIRType_Float32x4 = MIRType_Float32 | (2 << VECTOR_SCALE_SHIFT),
   1.114 +    MIRType_Int32x4   = MIRType_Int32   | (2 << VECTOR_SCALE_SHIFT),
   1.115 +    MIRType_Doublex2  = MIRType_Double  | (1 << VECTOR_SCALE_SHIFT)
   1.116 +};
   1.117 +
   1.118 +static inline MIRType
   1.119 +ElementType(MIRType type)
   1.120 +{
   1.121 +    JS_STATIC_ASSERT(MIRType_Last <= ELEMENT_TYPE_MASK);
   1.122 +    return static_cast<MIRType>((type >> ELEMENT_TYPE_SHIFT) & ELEMENT_TYPE_MASK);
   1.123 +}
   1.124 +
   1.125 +static inline uint32_t
   1.126 +VectorSize(MIRType type)
   1.127 +{
   1.128 +    return 1 << ((type >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK);
   1.129 +}
   1.130 +
   1.131 +static inline MIRType
   1.132 +MIRTypeFromValueType(JSValueType type)
   1.133 +{
   1.134 +    // This function does not deal with magic types. Magic constants should be
   1.135 +    // filtered out in MIRTypeFromValue.
   1.136 +    switch (type) {
   1.137 +      case JSVAL_TYPE_DOUBLE:
   1.138 +        return MIRType_Double;
   1.139 +      case JSVAL_TYPE_INT32:
   1.140 +        return MIRType_Int32;
   1.141 +      case JSVAL_TYPE_UNDEFINED:
   1.142 +        return MIRType_Undefined;
   1.143 +      case JSVAL_TYPE_STRING:
   1.144 +        return MIRType_String;
   1.145 +      case JSVAL_TYPE_BOOLEAN:
   1.146 +        return MIRType_Boolean;
   1.147 +      case JSVAL_TYPE_NULL:
   1.148 +        return MIRType_Null;
   1.149 +      case JSVAL_TYPE_OBJECT:
   1.150 +        return MIRType_Object;
   1.151 +      case JSVAL_TYPE_UNKNOWN:
   1.152 +        return MIRType_Value;
   1.153 +      default:
   1.154 +        MOZ_ASSUME_UNREACHABLE("unexpected jsval type");
   1.155 +    }
   1.156 +}
   1.157 +
   1.158 +static inline JSValueType
   1.159 +ValueTypeFromMIRType(MIRType type)
   1.160 +{
   1.161 +  switch (type) {
   1.162 +    case MIRType_Undefined:
   1.163 +      return JSVAL_TYPE_UNDEFINED;
   1.164 +    case MIRType_Null:
   1.165 +      return JSVAL_TYPE_NULL;
   1.166 +    case MIRType_Boolean:
   1.167 +      return JSVAL_TYPE_BOOLEAN;
   1.168 +    case MIRType_Int32:
   1.169 +      return JSVAL_TYPE_INT32;
   1.170 +    case MIRType_Float32: // Fall through, there's no JSVAL for Float32
   1.171 +    case MIRType_Double:
   1.172 +      return JSVAL_TYPE_DOUBLE;
   1.173 +    case MIRType_String:
   1.174 +      return JSVAL_TYPE_STRING;
   1.175 +    case MIRType_MagicOptimizedArguments:
   1.176 +    case MIRType_MagicOptimizedOut:
   1.177 +    case MIRType_MagicHole:
   1.178 +    case MIRType_MagicIsConstructing:
   1.179 +      return JSVAL_TYPE_MAGIC;
   1.180 +    default:
   1.181 +      JS_ASSERT(type == MIRType_Object);
   1.182 +      return JSVAL_TYPE_OBJECT;
   1.183 +  }
   1.184 +}
   1.185 +
   1.186 +static inline JSValueTag
   1.187 +MIRTypeToTag(MIRType type)
   1.188 +{
   1.189 +    return JSVAL_TYPE_TO_TAG(ValueTypeFromMIRType(type));
   1.190 +}
   1.191 +
   1.192 +static inline const char *
   1.193 +StringFromMIRType(MIRType type)
   1.194 +{
   1.195 +  switch (type) {
   1.196 +    case MIRType_Undefined:
   1.197 +      return "Undefined";
   1.198 +    case MIRType_Null:
   1.199 +      return "Null";
   1.200 +    case MIRType_Boolean:
   1.201 +      return "Bool";
   1.202 +    case MIRType_Int32:
   1.203 +      return "Int32";
   1.204 +    case MIRType_Double:
   1.205 +      return "Double";
   1.206 +    case MIRType_Float32:
   1.207 +      return "Float32";
   1.208 +    case MIRType_String:
   1.209 +      return "String";
   1.210 +    case MIRType_Object:
   1.211 +      return "Object";
   1.212 +    case MIRType_MagicOptimizedArguments:
   1.213 +      return "MagicOptimizedArguments";
   1.214 +    case MIRType_MagicOptimizedOut:
   1.215 +      return "MagicOptimizedOut";
   1.216 +    case MIRType_MagicHole:
   1.217 +      return "MagicHole";
   1.218 +    case MIRType_MagicIsConstructing:
   1.219 +      return "MagicIsConstructing";
   1.220 +    case MIRType_Value:
   1.221 +      return "Value";
   1.222 +    case MIRType_None:
   1.223 +      return "None";
   1.224 +    case MIRType_Slots:
   1.225 +      return "Slots";
   1.226 +    case MIRType_Elements:
   1.227 +      return "Elements";
   1.228 +    case MIRType_Pointer:
   1.229 +      return "Pointer";
   1.230 +    case MIRType_ForkJoinContext:
   1.231 +      return "ForkJoinContext";
   1.232 +    default:
   1.233 +      MOZ_ASSUME_UNREACHABLE("Unknown MIRType.");
   1.234 +  }
   1.235 +}
   1.236 +
   1.237 +static inline bool
   1.238 +IsNumberType(MIRType type)
   1.239 +{
   1.240 +    return type == MIRType_Int32 || type == MIRType_Double || type == MIRType_Float32;
   1.241 +}
   1.242 +
   1.243 +static inline bool
   1.244 +IsFloatType(MIRType type)
   1.245 +{
   1.246 +    return type == MIRType_Int32 || type == MIRType_Float32;
   1.247 +}
   1.248 +
   1.249 +static inline bool
   1.250 +IsFloatingPointType(MIRType type)
   1.251 +{
   1.252 +    return type == MIRType_Double || type == MIRType_Float32;
   1.253 +}
   1.254 +
   1.255 +static inline bool
   1.256 +IsNullOrUndefined(MIRType type)
   1.257 +{
   1.258 +    return type == MIRType_Null || type == MIRType_Undefined;
   1.259 +}
   1.260 +
   1.261 +#ifdef DEBUG
   1.262 +// Track the pipeline of opcodes which has produced a snapshot.
   1.263 +#define TRACK_SNAPSHOTS 1
   1.264 +
   1.265 +// Make sure registers are not modified between an instruction and
   1.266 +// its OsiPoint.
   1.267 +#  if defined(JS_ION)
   1.268 +#    define CHECK_OSIPOINT_REGISTERS 1
   1.269 +#  endif
   1.270 +#endif
   1.271 +
   1.272 +enum {
   1.273 +    ArgType_General = 0x1,
   1.274 +    ArgType_Double  = 0x2,
   1.275 +    ArgType_Float32 = 0x3,
   1.276 +
   1.277 +    RetType_Shift   = 0x0,
   1.278 +    ArgType_Shift   = 0x2,
   1.279 +    ArgType_Mask    = 0x3
   1.280 +};
   1.281 +
   1.282 +enum ABIFunctionType
   1.283 +{
   1.284 +    // VM functions that take 0-9 non-double arguments
   1.285 +    // and return a non-double value.
   1.286 +    Args_General0 = ArgType_General << RetType_Shift,
   1.287 +    Args_General1 = Args_General0 | (ArgType_General << (ArgType_Shift * 1)),
   1.288 +    Args_General2 = Args_General1 | (ArgType_General << (ArgType_Shift * 2)),
   1.289 +    Args_General3 = Args_General2 | (ArgType_General << (ArgType_Shift * 3)),
   1.290 +    Args_General4 = Args_General3 | (ArgType_General << (ArgType_Shift * 4)),
   1.291 +    Args_General5 = Args_General4 | (ArgType_General << (ArgType_Shift * 5)),
   1.292 +    Args_General6 = Args_General5 | (ArgType_General << (ArgType_Shift * 6)),
   1.293 +    Args_General7 = Args_General6 | (ArgType_General << (ArgType_Shift * 7)),
   1.294 +    Args_General8 = Args_General7 | (ArgType_General << (ArgType_Shift * 8)),
   1.295 +
   1.296 +    // double f()
   1.297 +    Args_Double_None = ArgType_Double << RetType_Shift,
   1.298 +
   1.299 +    // int f(double)
   1.300 +    Args_Int_Double = Args_General0 | (ArgType_Double << ArgType_Shift),
   1.301 +
   1.302 +    // float f(float)
   1.303 +    Args_Float32_Float32 = (ArgType_Float32 << RetType_Shift) | (ArgType_Float32 << ArgType_Shift),
   1.304 +
   1.305 +    // double f(double)
   1.306 +    Args_Double_Double = Args_Double_None | (ArgType_Double << ArgType_Shift),
   1.307 +
   1.308 +    // double f(int)
   1.309 +    Args_Double_Int = Args_Double_None | (ArgType_General << ArgType_Shift),
   1.310 +
   1.311 +    // double f(double, int)
   1.312 +    Args_Double_DoubleInt = Args_Double_None |
   1.313 +        (ArgType_General << (ArgType_Shift * 1)) |
   1.314 +        (ArgType_Double << (ArgType_Shift * 2)),
   1.315 +
   1.316 +    // double f(double, double)
   1.317 +    Args_Double_DoubleDouble = Args_Double_Double | (ArgType_Double << (ArgType_Shift * 2)),
   1.318 +
   1.319 +    // double f(int, double)
   1.320 +    Args_Double_IntDouble = Args_Double_None |
   1.321 +        (ArgType_Double << (ArgType_Shift * 1)) |
   1.322 +        (ArgType_General << (ArgType_Shift * 2)),
   1.323 +
   1.324 +    // int f(int, double)
   1.325 +    Args_Int_IntDouble = Args_General0 |
   1.326 +        (ArgType_Double << (ArgType_Shift * 1)) |
   1.327 +        (ArgType_General << (ArgType_Shift * 2))
   1.328 +};
   1.329 +
   1.330 +} // namespace jit
   1.331 +} // namespace js
   1.332 +
   1.333 +#endif /* jit_IonTypes_h */

mercurial