Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/types.h b/src/types.h
index 4b7d8ba..9ce650d 100644
--- a/src/types.h
+++ b/src/types.h
@@ -6,8 +6,8 @@
 #define V8_TYPES_H_
 
 #include "src/conversions.h"
-#include "src/factory.h"
 #include "src/handles.h"
+#include "src/objects.h"
 #include "src/ostreams.h"
 
 namespace v8 {
@@ -95,10 +95,13 @@
 // RANGE TYPES
 //
 // A range type represents a continuous integer interval by its minimum and
-// maximum value.  Either value might be an infinity.
+// maximum value.  Either value may be an infinity, in which case that infinity
+// itself is also included in the range.   A range never contains NaN or -0.
 //
-// Constant(v) is considered a subtype of Range(x..y) if v happens to be an
-// integer between x and y.
+// If a value v happens to be an integer n, then Constant(v) is considered a
+// subtype of Range(n, n) (and therefore also a subtype of any larger range).
+// In order to avoid large unions, however, it is usually a good idea to use
+// Range rather than Constant.
 //
 //
 // PREDICATES
@@ -153,39 +156,32 @@
 // -----------------------------------------------------------------------------
 // Values for bitset types
 
+// clang-format off
+
 #define MASK_BITSET_TYPE_LIST(V) \
-  V(Representation, 0xfff00000u) \
-  V(Semantic,       0x000ffffeu)
+  V(Representation, 0xff800000u) \
+  V(Semantic,       0x007ffffeu)
 
 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
 #define SEMANTIC(k)       ((k) & BitsetType::kSemantic)
 
 #define REPRESENTATION_BITSET_TYPE_LIST(V)    \
   V(None,               0)                    \
-  V(UntaggedBit,        1u << 20 | kSemantic) \
-  V(UntaggedSigned8,    1u << 21 | kSemantic) \
-  V(UntaggedSigned16,   1u << 22 | kSemantic) \
-  V(UntaggedSigned32,   1u << 23 | kSemantic) \
-  V(UntaggedUnsigned8,  1u << 24 | kSemantic) \
-  V(UntaggedUnsigned16, 1u << 25 | kSemantic) \
-  V(UntaggedUnsigned32, 1u << 26 | kSemantic) \
+  V(UntaggedBit,        1u << 23 | kSemantic) \
+  V(UntaggedIntegral8,  1u << 24 | kSemantic) \
+  V(UntaggedIntegral16, 1u << 25 | kSemantic) \
+  V(UntaggedIntegral32, 1u << 26 | kSemantic) \
   V(UntaggedFloat32,    1u << 27 | kSemantic) \
   V(UntaggedFloat64,    1u << 28 | kSemantic) \
   V(UntaggedPointer,    1u << 29 | kSemantic) \
   V(TaggedSigned,       1u << 30 | kSemantic) \
   V(TaggedPointer,      1u << 31 | kSemantic) \
   \
-  V(UntaggedSigned,     kUntaggedSigned8 | kUntaggedSigned16 |              \
-                        kUntaggedSigned32)                                  \
-  V(UntaggedUnsigned,   kUntaggedUnsigned8 | kUntaggedUnsigned16 |          \
-                        kUntaggedUnsigned32)                                \
-  V(UntaggedIntegral8,  kUntaggedSigned8 | kUntaggedUnsigned8)              \
-  V(UntaggedIntegral16, kUntaggedSigned16 | kUntaggedUnsigned16)            \
-  V(UntaggedIntegral32, kUntaggedSigned32 | kUntaggedUnsigned32)            \
-  V(UntaggedIntegral,   kUntaggedBit | kUntaggedSigned | kUntaggedUnsigned) \
-  V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)                \
-  V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)                 \
-  V(Untagged,           kUntaggedNumber | kUntaggedPointer)                 \
+  V(UntaggedIntegral,   kUntaggedBit | kUntaggedIntegral8 |        \
+                        kUntaggedIntegral16 | kUntaggedIntegral32) \
+  V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)       \
+  V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)        \
+  V(Untagged,           kUntaggedNumber | kUntaggedPointer)        \
   V(Tagged,             kTaggedSigned | kTaggedPointer)
 
 #define INTERNAL_BITSET_TYPE_LIST(V)                                      \
@@ -195,71 +191,70 @@
   V(OtherNumber,     1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
 
 #define SEMANTIC_BITSET_TYPE_LIST(V) \
-  V(NegativeSignedSmall, 1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(Negative31,          1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
   V(Null,                1u << 6  | REPRESENTATION(kTaggedPointer)) \
   V(Undefined,           1u << 7  | REPRESENTATION(kTaggedPointer)) \
   V(Boolean,             1u << 8  | REPRESENTATION(kTaggedPointer)) \
-  V(UnsignedSmall,       1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(Unsigned30,          1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
   V(MinusZero,           1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
   V(NaN,                 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
   V(Symbol,              1u << 12 | REPRESENTATION(kTaggedPointer)) \
   V(InternalizedString,  1u << 13 | REPRESENTATION(kTaggedPointer)) \
   V(OtherString,         1u << 14 | REPRESENTATION(kTaggedPointer)) \
-  V(Undetectable,        1u << 15 | REPRESENTATION(kTaggedPointer)) \
-  V(Array,               1u << 16 | REPRESENTATION(kTaggedPointer)) \
+  V(Simd,                1u << 15 | REPRESENTATION(kTaggedPointer)) \
+  V(Undetectable,        1u << 16 | REPRESENTATION(kTaggedPointer)) \
   V(OtherObject,         1u << 17 | REPRESENTATION(kTaggedPointer)) \
   V(Proxy,               1u << 18 | REPRESENTATION(kTaggedPointer)) \
-  V(Internal,            1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
+  V(Function,            1u << 19 | REPRESENTATION(kTaggedPointer)) \
+  V(Internal,            1u << 20 | REPRESENTATION(kTagged | kUntagged)) \
   \
-  V(SignedSmall,         kUnsignedSmall | kNegativeSignedSmall) \
-  V(Signed32,            kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
-  V(NegativeSigned32,    kNegativeSignedSmall | kOtherSigned32) \
-  V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \
-  V(Unsigned32,          kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \
-  V(Integral32,          kSigned32 | kUnsigned32) \
-  V(PlainNumber,         kIntegral32 | kOtherNumber) \
-  V(OrderedNumber,       kPlainNumber | kMinusZero) \
-  V(Number,              kOrderedNumber | kNaN) \
-  V(String,              kInternalizedString | kOtherString) \
-  V(UniqueName,          kSymbol | kInternalizedString) \
-  V(Name,                kSymbol | kString) \
-  V(NumberOrString,      kNumber | kString) \
-  V(PlainPrimitive,      kNumberOrString | kBoolean | kNull | kUndefined) \
-  V(Primitive,           kSymbol | kPlainPrimitive) \
-  V(DetectableObject,    kArray | kOtherObject) \
-  V(DetectableReceiver,  kDetectableObject | kProxy) \
-  V(Detectable,          kDetectableReceiver | kNumber | kName) \
-  V(Object,              kDetectableObject | kUndetectable) \
-  V(Receiver,            kObject | kProxy) \
-  V(StringOrReceiver,    kString | kReceiver) \
-  V(Unique,              kBoolean | kUniqueName | kNull | kUndefined | \
-                         kReceiver) \
-  V(NonNumber,           kUnique | kString | kInternal) \
-  V(Any,                 0xfffffffeu)
+  V(Signed31,                 kUnsigned30 | kNegative31) \
+  V(Signed32,                 kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
+  V(Negative32,               kNegative31 | kOtherSigned32) \
+  V(Unsigned31,               kUnsigned30 | kOtherUnsigned31) \
+  V(Unsigned32,               kUnsigned30 | kOtherUnsigned31 | \
+                              kOtherUnsigned32) \
+  V(Integral32,               kSigned32 | kUnsigned32) \
+  V(PlainNumber,              kIntegral32 | kOtherNumber) \
+  V(OrderedNumber,            kPlainNumber | kMinusZero) \
+  V(MinusZeroOrNaN,           kMinusZero | kNaN) \
+  V(Number,                   kOrderedNumber | kNaN) \
+  V(String,                   kInternalizedString | kOtherString) \
+  V(UniqueName,               kSymbol | kInternalizedString) \
+  V(Name,                     kSymbol | kString) \
+  V(BooleanOrNumber,          kBoolean | kNumber) \
+  V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
+  V(NullOrUndefined,          kNull | kUndefined) \
+  V(NumberOrString,           kNumber | kString) \
+  V(NumberOrUndefined,        kNumber | kUndefined) \
+  V(PlainPrimitive,           kNumberOrString | kBoolean | kNullOrUndefined) \
+  V(Primitive,                kSymbol | kSimd | kPlainPrimitive) \
+  V(DetectableReceiver,       kFunction | kOtherObject | kProxy) \
+  V(Detectable,               kDetectableReceiver | kNumber | kName) \
+  V(Object,                   kFunction | kOtherObject | kUndetectable) \
+  V(Receiver,                 kObject | kProxy) \
+  V(StringOrReceiver,         kString | kReceiver) \
+  V(Unique,                   kBoolean | kUniqueName | kNull | kUndefined | \
+                              kReceiver) \
+  V(NonNumber,                kUnique | kString | kInternal) \
+  V(Any,                      0xfffffffeu)
 
+// clang-format on
 
 /*
  * The following diagrams show how integers (in the mathematical sense) are
  * divided among the different atomic numerical types.
  *
- * If SmiValuesAre31Bits():
- *
- *   ON    OS32     OSS     US     OU31    OU32     ON
+ *   ON    OS32     N31     U30     OU31    OU32     ON
  * ______[_______[_______[_______[_______[_______[_______
  *     -2^31   -2^30     0      2^30    2^31    2^32
  *
- * Otherwise:
- *
- *   ON         OSS             US         OU32     ON
- * ______[_______________[_______________[_______[_______
- *     -2^31             0              2^31    2^32
- *
- *
  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
  *
- * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are
- *       32-bit wide.  They should thus never be used directly, only indirectly
- *       via e.g. Number.
+ * Some of the atomic numerical bitsets are internal only (see
+ * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
+ * union with certain other bitsets.  For instance, OtherNumber should only
+ * occur as part of PlainNumber.
  */
 
 #define PROPER_BITSET_TYPE_LIST(V) \
@@ -280,21 +275,30 @@
 //   typedef TypeImpl<Config> Type;
 //   typedef Base;
 //   typedef Struct;
+//   typedef Range;
 //   typedef Region;
 //   template<class> struct Handle { typedef type; }  // No template typedefs...
+//
 //   template<class T> static Handle<T>::type null_handle();
 //   template<class T> static Handle<T>::type handle(T* t);  // !is_bitset(t)
 //   template<class T> static Handle<T>::type cast(Handle<Type>::type);
+//
 //   static bool is_bitset(Type*);
 //   static bool is_class(Type*);
 //   static bool is_struct(Type*, int tag);
+//   static bool is_range(Type*);
+//
 //   static bitset as_bitset(Type*);
 //   static i::Handle<i::Map> as_class(Type*);
 //   static Handle<Struct>::type as_struct(Type*);
+//   static Handle<Range>::type as_range(Type*);
+//
 //   static Type* from_bitset(bitset);
 //   static Handle<Type>::type from_bitset(bitset, Region*);
 //   static Handle<Type>::type from_class(i::Handle<Map>, Region*);
 //   static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
+//   static Handle<Type>::type from_range(Handle<Range>::type);
+//
 //   static Handle<Struct>::type struct_create(int tag, int length, Region*);
 //   static void struct_shrink(Handle<Struct>::type, int length);
 //   static int struct_tag(Handle<Struct>::type);
@@ -305,6 +309,12 @@
 //   static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
 //   template<class V>
 //   static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
+//
+//   static Handle<Range>::type range_create(Region*);
+//   static int range_get_bitset(Handle<Range>::type);
+//   static void range_set_bitset(Handle<Range>::type, int);
+//   static double range_get_double(Handle<Range>::type, int);
+//   static void range_set_double(Handle<Range>::type, int, double, Region*);
 // }
 template<class Config>
 class TypeImpl : public Config::Base {
@@ -345,15 +355,31 @@
   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
   #undef DEFINE_TYPE_CONSTRUCTOR
 
+  static TypeImpl* SignedSmall() {
+    return BitsetType::New(BitsetType::SignedSmall());
+  }
+  static TypeHandle SignedSmall(Region* region) {
+    return BitsetType::New(BitsetType::SignedSmall(), region);
+  }
+  static TypeImpl* UnsignedSmall() {
+    return BitsetType::New(BitsetType::UnsignedSmall());
+  }
+  static TypeHandle UnsignedSmall(Region* region) {
+    return BitsetType::New(BitsetType::UnsignedSmall(), region);
+  }
+
   static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
     return ClassType::New(map, region);
   }
   static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
     return ConstantType::New(value, region);
   }
-  static TypeHandle Range(
-      i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
-    return RangeType::New(min, max, region);
+  static TypeHandle Range(double min, double max, Region* region) {
+    return RangeType::New(
+        min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged |
+                                                 BitsetType::kUntaggedNumber),
+                                  region),
+        region);
   }
   static TypeHandle Context(TypeHandle outer, Region* region) {
     return ContextType::New(outer, region);
@@ -390,28 +416,40 @@
     function->InitParameter(2, param2);
     return function;
   }
+  static TypeHandle Function(TypeHandle result, int arity, TypeHandle* params,
+                             Region* region) {
+    FunctionHandle function = Function(result, Any(region), arity, region);
+    for (int i = 0; i < arity; ++i) {
+      function->InitParameter(i, params[i]);
+    }
+    return function;
+  }
+
+#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
+  static TypeHandle Name(Isolate* isolate, Region* region);
+  SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
+#undef CONSTRUCT_SIMD_TYPE
 
   static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
   static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
-  static TypeImpl* Union(TypeImpl* type1, TypeImpl* type2) {
-    return BitsetType::New(type1->AsBitset() | type2->AsBitset());
-  }
-  static TypeImpl* Intersect(TypeImpl* type1, TypeImpl* type2) {
-    return BitsetType::New(type1->AsBitset() & type2->AsBitset());
-  }
 
   static TypeHandle Of(double value, Region* region) {
-    return Config::from_bitset(BitsetType::Lub(value), region);
+    return Config::from_bitset(BitsetType::ExpandInternals(
+        BitsetType::Lub(value)), region);
   }
   static TypeHandle Of(i::Object* value, Region* region) {
-    return Config::from_bitset(BitsetType::Lub(value), region);
+    return Config::from_bitset(BitsetType::ExpandInternals(
+        BitsetType::Lub(value)), region);
   }
   static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
     return Of(*value, region);
   }
 
-  // Predicates.
+  // Extraction of components.
+  static TypeHandle Representation(TypeHandle t, Region* region);
+  static TypeHandle Semantic(TypeHandle t, Region* region);
 
+  // Predicates.
   bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
 
   bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
@@ -446,6 +484,7 @@
 
   // Inspection.
 
+  bool IsRange() { return Config::is_range(this); }
   bool IsClass() {
     return Config::is_class(this)
         || Config::is_struct(this, StructuralType::kClassTag);
@@ -453,9 +492,6 @@
   bool IsConstant() {
     return Config::is_struct(this, StructuralType::kConstantTag);
   }
-  bool IsRange() {
-    return Config::is_struct(this, StructuralType::kRangeTag);
-  }
   bool IsContext() {
     return Config::is_struct(this, StructuralType::kContextTag);
   }
@@ -480,11 +516,17 @@
   double Min();
   double Max();
 
-  // Extracts a range from the type. If the type is a range, it just
-  // returns it; if it is a union, it returns the range component.
-  // Note that it does not contain range for constants.
+  // Extracts a range from the type: if the type is a range or a union
+  // containing a range, that range is returned; otherwise, NULL is returned.
   RangeType* GetRange();
 
+  static bool IsInteger(double x) {
+    return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
+  }
+  static bool IsInteger(i::Object* x) {
+    return x->IsNumber() && IsInteger(x->Number());
+  }
+
   int NumClasses();
   int NumConstants();
 
@@ -516,6 +558,8 @@
   void Print();
 #endif
 
+  bool IsUnionForTesting() { return IsUnion(); }
+
  protected:
   // Friends.
 
@@ -543,48 +587,52 @@
   }
   UnionType* AsUnion() { return UnionType::cast(this); }
 
+  bitset Representation();
+
   // Auxiliary functions.
+  bool SemanticMaybe(TypeImpl* that);
 
   bitset BitsetGlb() { return BitsetType::Glb(this); }
   bitset BitsetLub() { return BitsetType::Lub(this); }
 
   bool SlowIs(TypeImpl* that);
-
-  static bool IsInteger(double x) {
-    return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
-  }
-  static bool IsInteger(i::Object* x) {
-    return x->IsNumber() && IsInteger(x->Number());
-  }
+  bool SemanticIs(TypeImpl* that);
 
   struct Limits {
-    i::Handle<i::Object> min;
-    i::Handle<i::Object> max;
-    Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) :
-      min(min), max(max) {}
-    explicit Limits(RangeType* range) :
-      min(range->Min()), max(range->Max()) {}
+    double min;
+    double max;
+    Limits(double min, double max) : min(min), max(max) {}
+    explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
+    bool IsEmpty();
+    static Limits Empty() { return Limits(1, 0); }
+    static Limits Intersect(Limits lhs, Limits rhs);
+    static Limits Union(Limits lhs, Limits rhs);
   };
 
-  static Limits Intersect(Limits lhs, Limits rhs);
-  static Limits Union(Limits lhs, Limits rhs);
   static bool Overlap(RangeType* lhs, RangeType* rhs);
   static bool Contains(RangeType* lhs, RangeType* rhs);
+  static bool Contains(RangeType* range, ConstantType* constant);
   static bool Contains(RangeType* range, i::Object* val);
 
   static int UpdateRange(
       RangeHandle type, UnionHandle result, int size, Region* region);
 
+  static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits,
+                                        Region* region);
+  static Limits ToLimits(bitset bits, Region* region);
+
   bool SimplyEquals(TypeImpl* that);
   template<class TypeHandle>
   bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); }
 
   static int AddToUnion(
       TypeHandle type, UnionHandle result, int size, Region* region);
-  static int IntersectAux(
-      TypeHandle type, TypeHandle other,
-      UnionHandle result, int size, Region* region);
-  static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
+  static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result,
+                          int size, Limits* limits, Region* region);
+  static TypeHandle NormalizeUnion(UnionHandle unioned, int size,
+                                   Region* region);
+  static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits,
+                                            Region* region);
 };
 
 
@@ -596,42 +644,31 @@
  protected:
   friend class TypeImpl<Config>;
 
-  enum {
+  enum : uint32_t {
     #define DECLARE_TYPE(type, value) k##type = (value),
     BITSET_TYPE_LIST(DECLARE_TYPE)
     #undef DECLARE_TYPE
     kUnusedEOL = 0
   };
 
+  static bitset SignedSmall();
+  static bitset UnsignedSmall();
+
   bitset Bitset() { return Config::as_bitset(this); }
 
   static TypeImpl* New(bitset bits) {
-    DCHECK(bits == kNone || IsInhabited(bits));
-
-    if (FLAG_enable_slow_asserts) {
-      // Check that the bitset does not contain any holes in number ranges.
-      bitset mask = kSemantic;
-      if (!i::SmiValuesAre31Bits()) {
-        mask &= ~(kOtherUnsigned31 | kOtherSigned32);
-      }
-      bitset number_bits = bits & kPlainNumber & mask;
-      if (number_bits != 0) {
-        bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask;
-        CHECK(lub == number_bits);
-      }
-    }
-
     return Config::from_bitset(bits);
   }
   static TypeHandle New(bitset bits, Region* region) {
-    DCHECK(bits == kNone || IsInhabited(bits));
     return Config::from_bitset(bits, region);
   }
-  // TODO(neis): Eventually allow again for types with empty semantics
-  // part and modify intersection and possibly subtyping accordingly.
 
   static bool IsInhabited(bitset bits) {
-    return bits & kSemantic;
+    return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
+  }
+
+  static bool SemanticIsInhabited(bitset bits) {
+    return SEMANTIC(bits) != kNone;
   }
 
   static bool Is(bitset bits1, bitset bits2) {
@@ -642,11 +679,13 @@
   static double Max(bitset);
 
   static bitset Glb(TypeImpl* type);  // greatest lower bound that's a bitset
+  static bitset Glb(double min, double max);
   static bitset Lub(TypeImpl* type);  // least upper bound that's a bitset
   static bitset Lub(i::Map* map);
   static bitset Lub(i::Object* value);
   static bitset Lub(double value);
   static bitset Lub(double min, double max);
+  static bitset ExpandInternals(bitset bits);
 
   static const char* Name(bitset);
   static void Print(std::ostream& os, bitset);  // NOLINT
@@ -654,21 +693,17 @@
   static void Print(bitset);
 #endif
 
+  static bitset NumberBits(bitset bits);
+
  private:
-  struct BitsetMin{
-    bitset bits;
+  struct Boundary {
+    bitset internal;
+    bitset external;
     double min;
   };
-  static const BitsetMin BitsetMins31[];
-  static const BitsetMin BitsetMins32[];
-  static const BitsetMin* BitsetMins() {
-    return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32;
-  }
-  static size_t BitsetMinsSize() {
-    return i::SmiValuesAre31Bits() ? 7 : 5;
-    /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */
-    // Using arraysize here doesn't compile on Windows.
-  }
+  static const Boundary BoundariesArray[];
+  static inline const Boundary* Boundaries();
+  static inline size_t BoundariesSize();
 };
 
 
@@ -686,7 +721,6 @@
   enum Tag {
     kClassTag,
     kConstantTag,
-    kRangeTag,
     kContextTag,
     kArrayTag,
     kFunctionTag,
@@ -754,11 +788,6 @@
 template<class Config>
 class TypeImpl<Config>::ClassType : public StructuralType {
  public:
-  TypeHandle Bound(Region* region) {
-    return Config::is_class(this) ?
-        BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region) :
-        this->Get(0);
-  }
   i::Handle<i::Map> Map() {
     return Config::is_class(this) ? Config::as_class(this) :
         this->template GetValue<i::Map>(1);
@@ -780,6 +809,14 @@
     DCHECK(type->IsClass());
     return static_cast<ClassType*>(type);
   }
+
+ private:
+  template<class> friend class TypeImpl;
+  bitset Lub() {
+    return Config::is_class(this) ?
+        BitsetType::Lub(*Config::as_class(this)) :
+        this->Get(0)->AsBitset();
+  }
 };
 
 
@@ -789,7 +826,6 @@
 template<class Config>
 class TypeImpl<Config>::ConstantType : public StructuralType {
  public:
-  TypeHandle Bound() { return this->Get(0); }
   i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
 
   static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
@@ -804,6 +840,10 @@
     DCHECK(type->IsConstant());
     return static_cast<ConstantType*>(type);
   }
+
+ private:
+  template<class> friend class TypeImpl;
+  bitset Lub() { return this->Get(0)->AsBitset(); }
 };
 // TODO(neis): Also cache value if numerical.
 // TODO(neis): Allow restricting the representation.
@@ -812,37 +852,45 @@
 // -----------------------------------------------------------------------------
 // Range types.
 
-template<class Config>
-class TypeImpl<Config>::RangeType : public StructuralType {
+template <class Config>
+class TypeImpl<Config>::RangeType : public TypeImpl<Config> {
  public:
-  int BitsetLub() { return this->Get(0)->AsBitset(); }
-  i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); }
-  i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); }
+  double Min() { return Config::range_get_double(Config::as_range(this), 0); }
+  double Max() { return Config::range_get_double(Config::as_range(this), 1); }
 
-  static RangeHandle New(
-      i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
-    DCHECK(IsInteger(min->Number()) && IsInteger(max->Number()));
-    DCHECK(min->Number() <= max->Number());
-    RangeHandle type = Config::template cast<RangeType>(
-        StructuralType::New(StructuralType::kRangeTag, 3, region));
-    type->Set(0, BitsetType::New(
-        BitsetType::Lub(min->Number(), max->Number()), region));
-    type->SetValue(1, min);
-    type->SetValue(2, max);
-    return type;
+  static RangeHandle New(double min, double max, TypeHandle representation,
+                         Region* region) {
+    DCHECK(IsInteger(min) && IsInteger(max));
+    DCHECK(min <= max);
+    bitset representation_bits = representation->AsBitset();
+    DCHECK(REPRESENTATION(representation_bits) == representation_bits);
+
+    typename Config::template Handle<typename Config::Range>::type range =
+        Config::range_create(region);
+
+    bitset bits = SEMANTIC(BitsetType::Lub(min, max)) | representation_bits;
+    Config::range_set_bitset(range, bits);
+    Config::range_set_double(range, 0, min, region);
+    Config::range_set_double(range, 1, max, region);
+    return Config::template cast<RangeType>(Config::from_range(range));
   }
 
-  static RangeHandle New(Limits lim, Region* region) {
-    return New(lim.min, lim.max, region);
+  static RangeHandle New(Limits lim, bitset representation, Region* region) {
+    return New(lim.min, lim.max, BitsetType::New(representation, region),
+               region);
   }
 
   static RangeType* cast(TypeImpl* type) {
     DCHECK(type->IsRange());
     return static_cast<RangeType*>(type);
   }
+
+ private:
+  template<class> friend class TypeImpl;
+  bitset Lub() {
+    return Config::range_get_bitset(Config::as_range(this));
+  }
 };
-// TODO(neis): Also cache min and max values.
-// TODO(neis): Allow restricting the representation.
 
 
 // -----------------------------------------------------------------------------
@@ -952,25 +1000,38 @@
   typedef TypeImpl<ZoneTypeConfig> Type;
   class Base {};
   typedef void* Struct;
+  // Hack: the Struct and Range types can be aliased in memory, the first
+  // pointer word of each both must be the tag (kRangeStructTag for Range,
+  // anything else for Struct) so that we can differentiate them.
+  struct Range {
+    void* tag;
+    int bitset;
+    double limits[2];
+  };
   typedef i::Zone Region;
   template<class T> struct Handle { typedef T* type; };
 
-  template<class T> static inline T* null_handle();
+  static const int kRangeStructTag = 0x1000;
+
+  template<class T> static inline T* null_handle() { return nullptr; }
   template<class T> static inline T* handle(T* type);
   template<class T> static inline T* cast(Type* type);
 
   static inline bool is_bitset(Type* type);
   static inline bool is_class(Type* type);
   static inline bool is_struct(Type* type, int tag);
+  static inline bool is_range(Type* type);
 
   static inline Type::bitset as_bitset(Type* type);
   static inline i::Handle<i::Map> as_class(Type* type);
   static inline Struct* as_struct(Type* type);
+  static inline Range* as_range(Type* type);
 
   static inline Type* from_bitset(Type::bitset);
   static inline Type* from_bitset(Type::bitset, Zone* zone);
   static inline Type* from_class(i::Handle<i::Map> map, Zone* zone);
   static inline Type* from_struct(Struct* structured);
+  static inline Type* from_range(Range* range);
 
   static inline Struct* struct_create(int tag, int length, Zone* zone);
   static inline void struct_shrink(Struct* structure, int length);
@@ -982,6 +1043,12 @@
   static inline i::Handle<V> struct_get_value(Struct* structure, int i);
   template<class V> static inline void struct_set_value(
       Struct* structure, int i, i::Handle<V> x);
+
+  static inline Range* range_create(Zone* zone);
+  static inline int range_get_bitset(Range* range);
+  static inline void range_set_bitset(Range* range, int);
+  static inline double range_get_double(Range*, int index);
+  static inline void range_set_double(Range*, int index, double value, Zone*);
 };
 
 typedef TypeImpl<ZoneTypeConfig> Type;
@@ -995,26 +1062,34 @@
   typedef TypeImpl<HeapTypeConfig> Type;
   typedef i::Object Base;
   typedef i::FixedArray Struct;
+  typedef i::FixedArray Range;
   typedef i::Isolate Region;
   template<class T> struct Handle { typedef i::Handle<T> type; };
 
-  template<class T> static inline i::Handle<T> null_handle();
+  static const int kRangeStructTag = 0xffff;
+
+  template<class T> static inline i::Handle<T> null_handle() {
+    return i::Handle<T>();
+  }
   template<class T> static inline i::Handle<T> handle(T* type);
   template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
 
   static inline bool is_bitset(Type* type);
   static inline bool is_class(Type* type);
   static inline bool is_struct(Type* type, int tag);
+  static inline bool is_range(Type* type);
 
   static inline Type::bitset as_bitset(Type* type);
   static inline i::Handle<i::Map> as_class(Type* type);
   static inline i::Handle<Struct> as_struct(Type* type);
+  static inline i::Handle<Range> as_range(Type* type);
 
   static inline Type* from_bitset(Type::bitset);
   static inline i::Handle<Type> from_bitset(Type::bitset, Isolate* isolate);
   static inline i::Handle<Type> from_class(
       i::Handle<i::Map> map, Isolate* isolate);
   static inline i::Handle<Type> from_struct(i::Handle<Struct> structure);
+  static inline i::Handle<Type> from_range(i::Handle<Range> range);
 
   static inline i::Handle<Struct> struct_create(
       int tag, int length, Isolate* isolate);
@@ -1030,6 +1105,13 @@
   template<class V>
   static inline void struct_set_value(
       i::Handle<Struct> structure, int i, i::Handle<V> x);
+
+  static inline i::Handle<Range> range_create(Isolate* isolate);
+  static inline int range_get_bitset(i::Handle<Range> range);
+  static inline void range_set_bitset(i::Handle<Range> range, int value);
+  static inline double range_get_double(i::Handle<Range> range, int index);
+  static inline void range_set_double(i::Handle<Range> range, int index,
+                                      double value, Isolate* isolate);
 };
 
 typedef TypeImpl<HeapTypeConfig> HeapType;
@@ -1056,8 +1138,8 @@
   }
 
   // Unrestricted bounds.
-  static BoundsImpl Unbounded(Region* region) {
-    return BoundsImpl(Type::None(region), Type::Any(region));
+  static BoundsImpl Unbounded() {
+    return BoundsImpl(Type::None(), Type::Any());
   }
 
   // Meet: both b1 and b2 are known to hold.
@@ -1097,6 +1179,7 @@
 
 typedef BoundsImpl<ZoneTypeConfig> Bounds;
 
-} }  // namespace v8::internal
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_TYPES_H_