Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/types.cc b/src/types.cc
index 9261060..d54826e 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -6,8 +6,8 @@
 
 #include "src/types.h"
 
+#include "src/handles-inl.h"
 #include "src/ostreams.h"
-#include "src/types-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -16,19 +16,17 @@
 // NOTE: If code is marked as being a "shortcut", this means that removing
 // the code won't affect the semantics of the surrounding function definition.
 
+// static
+bool Type::IsInteger(i::Object* x) {
+  return x->IsNumber() && Type::IsInteger(x->Number());
+}
 
 // -----------------------------------------------------------------------------
 // Range-related helper functions.
 
-template <class Config>
-bool TypeImpl<Config>::Limits::IsEmpty() {
-  return this->min > this->max;
-}
+bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
 
-
-template<class Config>
-typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Intersect(
-    Limits lhs, Limits rhs) {
+RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
   DisallowHeapAllocation no_allocation;
   Limits result(lhs);
   if (lhs.min < rhs.min) result.min = rhs.min;
@@ -36,10 +34,7 @@
   return result;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Union(
-    Limits lhs, Limits rhs) {
+RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
   DisallowHeapAllocation no_allocation;
   if (lhs.IsEmpty()) return rhs;
   if (rhs.IsEmpty()) return lhs;
@@ -49,38 +44,26 @@
   return result;
 }
 
-
-template<class Config>
-bool TypeImpl<Config>::Overlap(
-    typename TypeImpl<Config>::RangeType* lhs,
-    typename TypeImpl<Config>::RangeType* rhs) {
+bool Type::Overlap(RangeType* lhs, RangeType* rhs) {
   DisallowHeapAllocation no_allocation;
-  return !Limits::Intersect(Limits(lhs), Limits(rhs)).IsEmpty();
+  return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
+                                       RangeType::Limits(rhs))
+              .IsEmpty();
 }
 
-
-template<class Config>
-bool TypeImpl<Config>::Contains(
-    typename TypeImpl<Config>::RangeType* lhs,
-    typename TypeImpl<Config>::RangeType* rhs) {
+bool Type::Contains(RangeType* lhs, RangeType* rhs) {
   DisallowHeapAllocation no_allocation;
   return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
 }
 
-
-template <class Config>
-bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs,
-                                typename TypeImpl<Config>::ConstantType* rhs) {
+bool Type::Contains(RangeType* lhs, ConstantType* rhs) {
   DisallowHeapAllocation no_allocation;
   return IsInteger(*rhs->Value()) &&
          lhs->Min() <= rhs->Value()->Number() &&
          rhs->Value()->Number() <= lhs->Max();
 }
 
-
-template<class Config>
-bool TypeImpl<Config>::Contains(
-    typename TypeImpl<Config>::RangeType* range, i::Object* val) {
+bool Type::Contains(RangeType* range, i::Object* val) {
   DisallowHeapAllocation no_allocation;
   return IsInteger(val) &&
          range->Min() <= val->Number() && val->Number() <= range->Max();
@@ -90,8 +73,7 @@
 // -----------------------------------------------------------------------------
 // Min and Max computation.
 
-template<class Config>
-double TypeImpl<Config>::Min() {
+double Type::Min() {
   DCHECK(this->SemanticIs(Number()));
   if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
   if (this->IsUnion()) {
@@ -107,9 +89,7 @@
   return 0;
 }
 
-
-template<class Config>
-double TypeImpl<Config>::Max() {
+double Type::Max() {
   DCHECK(this->SemanticIs(Number()));
   if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
   if (this->IsUnion()) {
@@ -131,12 +111,10 @@
 
 
 // The largest bitset subsumed by this type.
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
+Type::bitset BitsetType::Glb(Type* type) {
   DisallowHeapAllocation no_allocation;
   // Fast case.
-  if (type->IsBitset()) {
+  if (IsBitset(type)) {
     return type->AsBitset();
   } else if (type->IsUnion()) {
     SLOW_DCHECK(type->AsUnion()->Wellformed());
@@ -153,11 +131,9 @@
 
 
 // The smallest bitset subsuming this type, possibly not a proper one.
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
+Type::bitset BitsetType::Lub(Type* type) {
   DisallowHeapAllocation no_allocation;
-  if (type->IsBitset()) return type->AsBitset();
+  if (IsBitset(type)) return type->AsBitset();
   if (type->IsUnion()) {
     // Take the representation from the first element, which is always
     // a bitset.
@@ -174,14 +150,12 @@
   if (type->IsContext()) return kInternal & kTaggedPointer;
   if (type->IsArray()) return kOtherObject;
   if (type->IsFunction()) return kFunction;
+  if (type->IsTuple()) return kInternal;
   UNREACHABLE();
   return kNone;
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
+Type::bitset BitsetType::Lub(i::Map* map) {
   DisallowHeapAllocation no_allocation;
   switch (map->instance_type()) {
     case STRING_TYPE:
@@ -241,7 +215,6 @@
     case JS_MAP_TYPE:
     case JS_SET_ITERATOR_TYPE:
     case JS_MAP_ITERATOR_TYPE:
-    case JS_ITERATOR_RESULT_TYPE:
     case JS_WEAK_MAP_TYPE:
     case JS_WEAK_SET_TYPE:
     case JS_PROMISE_TYPE:
@@ -267,8 +240,7 @@
       // over type or class variables, esp ones with bounds...
       return kDetectable & kTaggedPointer;
     case ALLOCATION_SITE_TYPE:
-    case DECLARED_ACCESSOR_INFO_TYPE:
-    case EXECUTABLE_ACCESSOR_INFO_TYPE:
+    case ACCESSOR_INFO_TYPE:
     case SHARED_FUNCTION_INFO_TYPE:
     case ACCESSOR_PAIR_TYPE:
     case FIXED_ARRAY_TYPE:
@@ -292,7 +264,6 @@
       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
 #undef FIXED_TYPED_ARRAY_CASE
     case FILLER_TYPE:
-    case DECLARED_ACCESSOR_DESCRIPTOR_TYPE:
     case ACCESS_CHECK_INFO_TYPE:
     case INTERCEPTOR_INFO_TYPE:
     case CALL_HANDLER_INFO_TYPE:
@@ -319,10 +290,7 @@
   return kNone;
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
+Type::bitset BitsetType::Lub(i::Object* value) {
   DisallowHeapAllocation no_allocation;
   if (value->IsNumber()) {
     return Lub(value->Number()) &
@@ -331,10 +299,7 @@
   return Lub(i::HeapObject::cast(value)->map());
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(double value) {
+Type::bitset BitsetType::Lub(double value) {
   DisallowHeapAllocation no_allocation;
   if (i::IsMinusZero(value)) return kMinusZero;
   if (std::isnan(value)) return kNaN;
@@ -344,36 +309,24 @@
 
 
 // Minimum values of plain numeric bitsets.
-template <class Config>
-const typename TypeImpl<Config>::BitsetType::Boundary
-TypeImpl<Config>::BitsetType::BoundariesArray[] = {
-        {kOtherNumber, kPlainNumber, -V8_INFINITY},
-        {kOtherSigned32, kNegative32, kMinInt},
-        {kNegative31, kNegative31, -0x40000000},
-        {kUnsigned30, kUnsigned30, 0},
-        {kOtherUnsigned31, kUnsigned31, 0x40000000},
-        {kOtherUnsigned32, kUnsigned32, 0x80000000},
-        {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
+const BitsetType::Boundary BitsetType::BoundariesArray[] = {
+    {kOtherNumber, kPlainNumber, -V8_INFINITY},
+    {kOtherSigned32, kNegative32, kMinInt},
+    {kNegative31, kNegative31, -0x40000000},
+    {kUnsigned30, kUnsigned30, 0},
+    {kOtherUnsigned31, kUnsigned31, 0x40000000},
+    {kOtherUnsigned32, kUnsigned32, 0x80000000},
+    {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
 
+const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
 
-template <class Config>
-const typename TypeImpl<Config>::BitsetType::Boundary*
-TypeImpl<Config>::BitsetType::Boundaries() {
-  return BoundariesArray;
-}
-
-
-template <class Config>
-size_t TypeImpl<Config>::BitsetType::BoundariesSize() {
+size_t BitsetType::BoundariesSize() {
   // Windows doesn't like arraysize here.
   // return arraysize(BoundariesArray);
   return 7;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::ExpandInternals(
-    typename TypeImpl<Config>::bitset bits) {
+Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
   DisallowHeapAllocation no_allocation;
   if (!(bits & SEMANTIC(kPlainNumber))) return bits;  // Shortcut.
   const Boundary* boundaries = Boundaries();
@@ -385,10 +338,7 @@
   return bits;
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(double min, double max) {
+Type::bitset BitsetType::Lub(double min, double max) {
   DisallowHeapAllocation no_allocation;
   int lub = kNone;
   const Boundary* mins = Boundaries();
@@ -402,17 +352,11 @@
   return lub | mins[BoundariesSize() - 1].internal;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::NumberBits(
-    bitset bits) {
+Type::bitset BitsetType::NumberBits(bitset bits) {
   return SEMANTIC(bits & kPlainNumber);
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
-    double min, double max) {
+Type::bitset BitsetType::Glb(double min, double max) {
   DisallowHeapAllocation no_allocation;
   int glb = kNone;
   const Boundary* mins = Boundaries();
@@ -431,9 +375,7 @@
   return glb & ~(SEMANTIC(kOtherNumber));
 }
 
-
-template <class Config>
-double TypeImpl<Config>::BitsetType::Min(bitset bits) {
+double BitsetType::Min(bitset bits) {
   DisallowHeapAllocation no_allocation;
   DCHECK(Is(SEMANTIC(bits), kNumber));
   const Boundary* mins = Boundaries();
@@ -447,9 +389,7 @@
   return std::numeric_limits<double>::quiet_NaN();
 }
 
-
-template<class Config>
-double TypeImpl<Config>::BitsetType::Max(bitset bits) {
+double BitsetType::Max(bitset bits) {
   DisallowHeapAllocation no_allocation;
   DCHECK(Is(SEMANTIC(bits), kNumber));
   const Boundary* mins = Boundaries();
@@ -471,9 +411,7 @@
 // -----------------------------------------------------------------------------
 // Predicates.
 
-
-template<class Config>
-bool TypeImpl<Config>::SimplyEquals(TypeImpl* that) {
+bool Type::SimplyEquals(Type* that) {
   DisallowHeapAllocation no_allocation;
   if (this->IsClass()) {
     return that->IsClass()
@@ -505,20 +443,29 @@
     }
     return true;
   }
+  if (this->IsTuple()) {
+    if (!that->IsTuple()) return false;
+    TupleType* this_tuple = this->AsTuple();
+    TupleType* that_tuple = that->AsTuple();
+    if (this_tuple->Arity() != that_tuple->Arity()) {
+      return false;
+    }
+    for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
+      if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
+    }
+    return true;
+  }
   UNREACHABLE();
   return false;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::bitset TypeImpl<Config>::Representation() {
+Type::bitset Type::Representation() {
   return REPRESENTATION(this->BitsetLub());
 }
 
 
 // Check if [this] <= [that].
-template<class Config>
-bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
+bool Type::SlowIs(Type* that) {
   DisallowHeapAllocation no_allocation;
 
   // Fast bitset cases
@@ -542,8 +489,7 @@
 
 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method
 // should be independent of the representation axis of the types.
-template <class Config>
-bool TypeImpl<Config>::SemanticIs(TypeImpl* that) {
+bool Type::SemanticIs(Type* that) {
   DisallowHeapAllocation no_allocation;
 
   if (this == that) return true;
@@ -566,7 +512,7 @@
   // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
   if (that->IsUnion()) {
     for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
-      if (this->SemanticIs(that->AsUnion()->Get(i)->unhandle())) return true;
+      if (this->SemanticIs(that->AsUnion()->Get(i))) return true;
       if (i > 1 && this->IsRange()) return false;  // Shortcut.
     }
     return false;
@@ -582,9 +528,28 @@
   return this->SimplyEquals(that);
 }
 
+// Most precise _current_ type of a value (usually its class).
+Type* Type::NowOf(i::Object* value, Zone* zone) {
+  if (value->IsSmi() ||
+      i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
+    return Of(value, zone);
+  }
+  return Class(i::handle(i::HeapObject::cast(value)->map()), zone);
+}
 
-template<class Config>
-bool TypeImpl<Config>::NowIs(TypeImpl* that) {
+bool Type::NowContains(i::Object* value) {
+  DisallowHeapAllocation no_allocation;
+  if (this->IsAny()) return true;
+  if (value->IsHeapObject()) {
+    i::Map* map = i::HeapObject::cast(value)->map();
+    for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
+      if (*it.Current() == map) return true;
+    }
+  }
+  return this->Contains(value);
+}
+
+bool Type::NowIs(Type* that) {
   DisallowHeapAllocation no_allocation;
 
   // TODO(rossberg): this is incorrect for
@@ -604,16 +569,14 @@
 
 
 // Check if [this] contains only (currently) stable classes.
-template<class Config>
-bool TypeImpl<Config>::NowStable() {
+bool Type::NowStable() {
   DisallowHeapAllocation no_allocation;
   return !this->IsClass() || this->AsClass()->Map()->is_stable();
 }
 
 
 // Check if [this] and [that] overlap.
-template<class Config>
-bool TypeImpl<Config>::Maybe(TypeImpl* that) {
+bool Type::Maybe(Type* that) {
   DisallowHeapAllocation no_allocation;
 
   // Take care of the representation part (and also approximate
@@ -624,8 +587,7 @@
   return SemanticMaybe(that);
 }
 
-template <class Config>
-bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) {
+bool Type::SemanticMaybe(Type* that) {
   DisallowHeapAllocation no_allocation;
 
   // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
@@ -639,7 +601,7 @@
   // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
   if (that->IsUnion()) {
     for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
-      if (this->SemanticMaybe(that->AsUnion()->Get(i)->unhandle())) return true;
+      if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true;
     }
     return false;
   }
@@ -679,33 +641,28 @@
 
 
 // Return the range in [this], or [NULL].
-template<class Config>
-typename TypeImpl<Config>::RangeType* TypeImpl<Config>::GetRange() {
+Type* Type::GetRange() {
   DisallowHeapAllocation no_allocation;
-  if (this->IsRange()) return this->AsRange();
+  if (this->IsRange()) return this;
   if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
-    return this->AsUnion()->Get(1)->AsRange();
+    return this->AsUnion()->Get(1);
   }
   return NULL;
 }
 
-
-template<class Config>
-bool TypeImpl<Config>::Contains(i::Object* value) {
+bool Type::Contains(i::Object* value) {
   DisallowHeapAllocation no_allocation;
   for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
     if (*it.Current() == value) return true;
   }
   if (IsInteger(value)) {
-    RangeType* range = this->GetRange();
-    if (range != NULL && Contains(range, value)) return true;
+    Type* range = this->GetRange();
+    if (range != NULL && Contains(range->AsRange(), value)) return true;
   }
   return BitsetType::New(BitsetType::Lub(value))->Is(this);
 }
 
-
-template<class Config>
-bool TypeImpl<Config>::UnionType::Wellformed() {
+bool UnionType::Wellformed() {
   DisallowHeapAllocation no_allocation;
   // This checks the invariants of the union representation:
   // 1. There are at least two elements.
@@ -724,7 +681,7 @@
     DCHECK(!this->Get(i)->IsUnion());               // (4)
     for (int j = 0; j < this->Length(); ++j) {
       if (i != j && i != 0)
-        DCHECK(!this->Get(i)->SemanticIs(this->Get(j)->unhandle()));  // (5)
+        DCHECK(!this->Get(i)->SemanticIs(this->Get(j)));  // (5)
     }
   }
   DCHECK(!this->Get(1)->IsRange() ||
@@ -744,14 +701,10 @@
       y >= std::numeric_limits<int>::min() - x;
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
-    TypeHandle type1, TypeHandle type2, Region* region) {
-
+Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) {
   // Fast case: bit sets.
   if (type1->IsBitset() && type2->IsBitset()) {
-    return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
+    return BitsetType::New(type1->AsBitset() & type2->AsBitset());
   }
 
   // Fast case: top or bottom types.
@@ -775,47 +728,45 @@
   // semi-fast case above - we should behave the same way regardless of
   // representations. Intersection with a universal bitset should only update
   // the representations.
-  if (type1->SemanticIs(type2->unhandle())) {
-    type2 = Any(region);
-  } else if (type2->SemanticIs(type1->unhandle())) {
-    type1 = Any(region);
+  if (type1->SemanticIs(type2)) {
+    type2 = Any();
+  } else if (type2->SemanticIs(type1)) {
+    type1 = Any();
   }
 
   bitset bits =
       SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation;
   int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
   int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
-  if (!AddIsSafe(size1, size2)) return Any(region);
+  if (!AddIsSafe(size1, size2)) return Any();
   int size = size1 + size2;
-  if (!AddIsSafe(size, 2)) return Any(region);
+  if (!AddIsSafe(size, 2)) return Any();
   size += 2;
-  UnionHandle result = UnionType::New(size, region);
+  Type* result_type = UnionType::New(size, zone);
+  UnionType* result = result_type->AsUnion();
   size = 0;
 
   // Deal with bitsets.
-  result->Set(size++, BitsetType::New(bits, region));
+  result->Set(size++, BitsetType::New(bits));
 
-  Limits lims = Limits::Empty();
-  size = IntersectAux(type1, type2, result, size, &lims, region);
+  RangeType::Limits lims = RangeType::Limits::Empty();
+  size = IntersectAux(type1, type2, result, size, &lims, zone);
 
   // If the range is not empty, then insert it into the union and
   // remove the number bits from the bitset.
   if (!lims.IsEmpty()) {
-    size = UpdateRange(RangeType::New(lims, representation, region), result,
-                       size, region);
+    size = UpdateRange(RangeType::New(lims, representation, zone), result, size,
+                       zone);
 
     // Remove the number bits.
     bitset number_bits = BitsetType::NumberBits(bits);
     bits &= ~number_bits;
-    result->Set(0, BitsetType::New(bits, region));
+    result->Set(0, BitsetType::New(bits));
   }
-  return NormalizeUnion(result, size, region);
+  return NormalizeUnion(result_type, size, zone);
 }
 
-
-template<class Config>
-int TypeImpl<Config>::UpdateRange(
-    RangeHandle range, UnionHandle result, int size, Region* region) {
+int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) {
   if (size == 1) {
     result->Set(size++, range);
   } else {
@@ -826,7 +777,7 @@
 
   // Remove any components that just got subsumed.
   for (int i = 2; i < size; ) {
-    if (result->Get(i)->SemanticIs(range->unhandle())) {
+    if (result->Get(i)->SemanticIs(range)) {
       result->Set(i, result->Get(--size));
     } else {
       ++i;
@@ -835,44 +786,37 @@
   return size;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits,
-                                                             Region* region) {
+RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
   bitset number_bits = BitsetType::NumberBits(bits);
 
   if (number_bits == BitsetType::kNone) {
-    return Limits::Empty();
+    return RangeType::Limits::Empty();
   }
 
-  return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits));
+  return RangeType::Limits(BitsetType::Min(number_bits),
+                           BitsetType::Max(number_bits));
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset(
-    TypeHandle range, TypeHandle bitset, Region* region) {
-  Limits range_lims(range->AsRange());
-  Limits bitset_lims = ToLimits(bitset->AsBitset(), region);
-  return Limits::Intersect(range_lims, bitset_lims);
+RangeType::Limits Type::IntersectRangeAndBitset(Type* range, Type* bitset,
+                                                Zone* zone) {
+  RangeType::Limits range_lims(range->AsRange());
+  RangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
+  return RangeType::Limits::Intersect(range_lims, bitset_lims);
 }
 
-
-template <class Config>
-int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs,
-                                   UnionHandle result, int size, Limits* lims,
-                                   Region* region) {
+int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
+                       RangeType::Limits* lims, Zone* zone) {
   if (lhs->IsUnion()) {
     for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
       size =
-          IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, region);
+          IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
     }
     return size;
   }
   if (rhs->IsUnion()) {
     for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
       size =
-          IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region);
+          IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
     }
     return size;
   }
@@ -883,40 +827,41 @@
 
   if (lhs->IsRange()) {
     if (rhs->IsBitset()) {
-      Limits lim = IntersectRangeAndBitset(lhs, rhs, region);
+      RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
 
       if (!lim.IsEmpty()) {
-        *lims = Limits::Union(lim, *lims);
+        *lims = RangeType::Limits::Union(lim, *lims);
       }
       return size;
     }
     if (rhs->IsClass()) {
-      *lims = Limits::Union(Limits(lhs->AsRange()), *lims);
+      *lims =
+          RangeType::Limits::Union(RangeType::Limits(lhs->AsRange()), *lims);
     }
     if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
-      return AddToUnion(rhs, result, size, region);
+      return AddToUnion(rhs, result, size, zone);
     }
     if (rhs->IsRange()) {
-      Limits lim = Limits::Intersect(
-          Limits(lhs->AsRange()), Limits(rhs->AsRange()));
+      RangeType::Limits lim = RangeType::Limits::Intersect(
+          RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
       if (!lim.IsEmpty()) {
-        *lims = Limits::Union(lim, *lims);
+        *lims = RangeType::Limits::Union(lim, *lims);
       }
     }
     return size;
   }
   if (rhs->IsRange()) {
     // This case is handled symmetrically above.
-    return IntersectAux(rhs, lhs, result, size, lims, region);
+    return IntersectAux(rhs, lhs, result, size, lims, zone);
   }
   if (lhs->IsBitset() || rhs->IsBitset()) {
-    return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, region);
+    return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
   }
   if (lhs->IsClass() != rhs->IsClass()) {
-    return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, region);
+    return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, zone);
   }
-  if (lhs->SimplyEquals(rhs->unhandle())) {
-    return AddToUnion(lhs, result, size, region);
+  if (lhs->SimplyEquals(rhs)) {
+    return AddToUnion(lhs, result, size, zone);
   }
   return size;
 }
@@ -926,9 +871,7 @@
 // If the range is non-empty, the number bits in the bitset should be
 // clear. Moreover, if we have a canonical range (such as Signed32),
 // we want to produce a bitset rather than a range.
-template <class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
-    RangeHandle range, bitset* bits, Region* region) {
+Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
   // Fast path: If the bitset does not mention numbers, we can just keep the
   // range.
   bitset number_bits = BitsetType::NumberBits(*bits);
@@ -940,7 +883,7 @@
   // leave the bitset untouched.
   bitset range_lub = SEMANTIC(range->BitsetLub());
   if (BitsetType::Is(range_lub, *bits)) {
-    return None(region);
+    return None();
   }
 
   // Slow path: reconcile the bitset range and the range.
@@ -966,17 +909,13 @@
   if (bitset_max > range_max) {
     range_max = bitset_max;
   }
-  return RangeType::New(range_min, range_max,
-                        BitsetType::New(BitsetType::kNone, region), region);
+  return RangeType::New(range_min, range_max, BitsetType::kNone, zone);
 }
 
-
-template<class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
-    TypeHandle type1, TypeHandle type2, Region* region) {
+Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
   // Fast case: bit sets.
   if (type1->IsBitset() && type2->IsBitset()) {
-    return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
+    return BitsetType::New(type1->AsBitset() | type2->AsBitset());
   }
 
   // Fast case: top or bottom types.
@@ -997,63 +936,62 @@
   // Slow case: create union.
   int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
   int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
-  if (!AddIsSafe(size1, size2)) return Any(region);
+  if (!AddIsSafe(size1, size2)) return Any();
   int size = size1 + size2;
-  if (!AddIsSafe(size, 2)) return Any(region);
+  if (!AddIsSafe(size, 2)) return Any();
   size += 2;
-  UnionHandle result = UnionType::New(size, region);
+  Type* result_type = UnionType::New(size, zone);
+  UnionType* result = result_type->AsUnion();
   size = 0;
 
   // Compute the new bitset.
   bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb());
 
   // Deal with ranges.
-  TypeHandle range = None(region);
-  RangeType* range1 = type1->GetRange();
-  RangeType* range2 = type2->GetRange();
+  Type* range = None();
+  Type* range1 = type1->GetRange();
+  Type* range2 = type2->GetRange();
   if (range1 != NULL && range2 != NULL) {
-    Limits lims = Limits::Union(Limits(range1), Limits(range2));
-    RangeHandle union_range = RangeType::New(lims, representation, region);
-    range = NormalizeRangeAndBitset(union_range, &new_bitset, region);
+    RangeType::Limits lims =
+        RangeType::Limits::Union(RangeType::Limits(range1->AsRange()),
+                                 RangeType::Limits(range2->AsRange()));
+    Type* union_range = RangeType::New(lims, representation, zone);
+    range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
   } else if (range1 != NULL) {
-    range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region);
+    range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
   } else if (range2 != NULL) {
-    range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region);
+    range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
   }
   new_bitset = SEMANTIC(new_bitset) | representation;
-  TypeHandle bits = BitsetType::New(new_bitset, region);
+  Type* bits = BitsetType::New(new_bitset);
   result->Set(size++, bits);
   if (!range->IsNone()) result->Set(size++, range);
 
-  size = AddToUnion(type1, result, size, region);
-  size = AddToUnion(type2, result, size, region);
-  return NormalizeUnion(result, size, region);
+  size = AddToUnion(type1, result, size, zone);
+  size = AddToUnion(type2, result, size, zone);
+  return NormalizeUnion(result_type, size, zone);
 }
 
 
 // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
 // Return new size of [result].
-template<class Config>
-int TypeImpl<Config>::AddToUnion(
-    TypeHandle type, UnionHandle result, int size, Region* region) {
+int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) {
   if (type->IsBitset() || type->IsRange()) return size;
   if (type->IsUnion()) {
     for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
-      size = AddToUnion(type->AsUnion()->Get(i), result, size, region);
+      size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
     }
     return size;
   }
   for (int i = 0; i < size; ++i) {
-    if (type->SemanticIs(result->Get(i)->unhandle())) return size;
+    if (type->SemanticIs(result->Get(i))) return size;
   }
   result->Set(size++, type);
   return size;
 }
 
-
-template <class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion(
-    UnionHandle unioned, int size, Region* region) {
+Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
+  UnionType* unioned = union_type->AsUnion();
   DCHECK(size >= 1);
   DCHECK(unioned->Get(0)->IsBitset());
   // If the union has just one element, return it.
@@ -1069,13 +1007,13 @@
     }
     if (unioned->Get(1)->IsRange()) {
       return RangeType::New(unioned->Get(1)->AsRange()->Min(),
-                            unioned->Get(1)->AsRange()->Max(), unioned->Get(0),
-                            region);
+                            unioned->Get(1)->AsRange()->Max(),
+                            unioned->Get(0)->AsBitset(), zone);
     }
   }
   unioned->Shrink(size);
   SLOW_DCHECK(unioned->Wellformed());
-  return unioned;
+  return union_type;
 }
 
 
@@ -1083,26 +1021,21 @@
 // Component extraction
 
 // static
-template <class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Representation(
-    TypeHandle t, Region* region) {
-  return BitsetType::New(t->Representation(), region);
+Type* Type::Representation(Type* t, Zone* zone) {
+  return BitsetType::New(t->Representation());
 }
 
 
 // static
-template <class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Semantic(
-    TypeHandle t, Region* region) {
-  return Intersect(t, BitsetType::New(BitsetType::kSemantic, region), region);
+Type* Type::Semantic(Type* t, Zone* zone) {
+  return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone);
 }
 
 
 // -----------------------------------------------------------------------------
 // Iteration.
 
-template<class Config>
-int TypeImpl<Config>::NumClasses() {
+int Type::NumClasses() {
   DisallowHeapAllocation no_allocation;
   if (this->IsClass()) {
     return 1;
@@ -1117,9 +1050,7 @@
   }
 }
 
-
-template<class Config>
-int TypeImpl<Config>::NumConstants() {
+int Type::NumConstants() {
   DisallowHeapAllocation no_allocation;
   if (this->IsConstant()) {
     return 1;
@@ -1134,10 +1065,8 @@
   }
 }
 
-
-template<class Config> template<class T>
-typename TypeImpl<Config>::TypeHandle
-TypeImpl<Config>::Iterator<T>::get_type() {
+template <class T>
+Type* Type::Iterator<T>::get_type() {
   DCHECK(!Done());
   return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
 }
@@ -1145,46 +1074,40 @@
 
 // C++ cannot specialise nested templates, so we have to go through this
 // contortion with an auxiliary template to simulate it.
-template<class Config, class T>
+template <class T>
 struct TypeImplIteratorAux {
-  static bool matches(typename TypeImpl<Config>::TypeHandle type);
-  static i::Handle<T> current(typename TypeImpl<Config>::TypeHandle type);
+  static bool matches(Type* type);
+  static i::Handle<T> current(Type* type);
 };
 
-template<class Config>
-struct TypeImplIteratorAux<Config, i::Map> {
-  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
-    return type->IsClass();
-  }
-  static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
+template <>
+struct TypeImplIteratorAux<i::Map> {
+  static bool matches(Type* type) { return type->IsClass(); }
+  static i::Handle<i::Map> current(Type* type) {
     return type->AsClass()->Map();
   }
 };
 
-template<class Config>
-struct TypeImplIteratorAux<Config, i::Object> {
-  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
-    return type->IsConstant();
-  }
-  static i::Handle<i::Object> current(
-      typename TypeImpl<Config>::TypeHandle type) {
+template <>
+struct TypeImplIteratorAux<i::Object> {
+  static bool matches(Type* type) { return type->IsConstant(); }
+  static i::Handle<i::Object> current(Type* type) {
     return type->AsConstant()->Value();
   }
 };
 
-template<class Config> template<class T>
-bool TypeImpl<Config>::Iterator<T>::matches(TypeHandle type) {
-  return TypeImplIteratorAux<Config, T>::matches(type);
+template <class T>
+bool Type::Iterator<T>::matches(Type* type) {
+  return TypeImplIteratorAux<T>::matches(type);
 }
 
-template<class Config> template<class T>
-i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
-  return TypeImplIteratorAux<Config, T>::current(get_type());
+template <class T>
+i::Handle<T> Type::Iterator<T>::Current() {
+  return TypeImplIteratorAux<T>::current(get_type());
 }
 
-
-template<class Config> template<class T>
-void TypeImpl<Config>::Iterator<T>::Advance() {
+template <class T>
+void Type::Iterator<T>::Advance() {
   DisallowHeapAllocation no_allocation;
   ++index_;
   if (type_->IsUnion()) {
@@ -1199,59 +1122,9 @@
 
 
 // -----------------------------------------------------------------------------
-// Conversion between low-level representations.
-
-template<class Config>
-template<class OtherType>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
-    typename OtherType::TypeHandle type, Region* region) {
-  if (type->IsBitset()) {
-    return BitsetType::New(type->AsBitset(), region);
-  } else if (type->IsClass()) {
-    return ClassType::New(type->AsClass()->Map(), region);
-  } else if (type->IsConstant()) {
-    return ConstantType::New(type->AsConstant()->Value(), region);
-  } else if (type->IsRange()) {
-    return RangeType::New(
-        type->AsRange()->Min(), type->AsRange()->Max(),
-        BitsetType::New(REPRESENTATION(type->BitsetLub()), region), region);
-  } else if (type->IsContext()) {
-    TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region);
-    return ContextType::New(outer, region);
-  } else if (type->IsUnion()) {
-    int length = type->AsUnion()->Length();
-    UnionHandle unioned = UnionType::New(length, region);
-    for (int i = 0; i < length; ++i) {
-      TypeHandle t = Convert<OtherType>(type->AsUnion()->Get(i), region);
-      unioned->Set(i, t);
-    }
-    return unioned;
-  } else if (type->IsArray()) {
-    TypeHandle element = Convert<OtherType>(type->AsArray()->Element(), region);
-    return ArrayType::New(element, region);
-  } else if (type->IsFunction()) {
-    TypeHandle res = Convert<OtherType>(type->AsFunction()->Result(), region);
-    TypeHandle rcv = Convert<OtherType>(type->AsFunction()->Receiver(), region);
-    FunctionHandle function = FunctionType::New(
-        res, rcv, type->AsFunction()->Arity(), region);
-    for (int i = 0; i < function->Arity(); ++i) {
-      TypeHandle param = Convert<OtherType>(
-          type->AsFunction()->Parameter(i), region);
-      function->InitParameter(i, param);
-    }
-    return function;
-  } else {
-    UNREACHABLE();
-    return None(region);
-  }
-}
-
-
-// -----------------------------------------------------------------------------
 // Printing.
 
-template<class Config>
-const char* TypeImpl<Config>::BitsetType::Name(bitset bits) {
+const char* BitsetType::Name(bitset bits) {
   switch (bits) {
     case REPRESENTATION(kAny): return "Any";
     #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
@@ -1270,10 +1143,8 @@
   }
 }
 
-
-template <class Config>
-void TypeImpl<Config>::BitsetType::Print(std::ostream& os,  // NOLINT
-                                         bitset bits) {
+void BitsetType::Print(std::ostream& os,  // NOLINT
+                       bitset bits) {
   DisallowHeapAllocation no_allocation;
   const char* name = Name(bits);
   if (name != NULL) {
@@ -1309,9 +1180,7 @@
   os << ")";
 }
 
-
-template <class Config>
-void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
+void Type::PrintTo(std::ostream& os, PrintDimension dim) {
   DisallowHeapAllocation no_allocation;
   if (dim != REPRESENTATION_DIM) {
     if (this->IsBitset()) {
@@ -1336,7 +1205,7 @@
     } else if (this->IsUnion()) {
       os << "(";
       for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
-        TypeHandle type_i = this->AsUnion()->Get(i);
+        Type* type_i = this->AsUnion()->Get(i);
         if (i > 0) os << " | ";
         type_i->PrintTo(os, dim);
       }
@@ -1357,6 +1226,14 @@
       }
       os << ")->";
       this->AsFunction()->Result()->PrintTo(os, dim);
+    } else if (this->IsTuple()) {
+      os << "<";
+      for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
+        Type* type_i = this->AsTuple()->Element(i);
+        if (i > 0) os << ", ";
+        type_i->PrintTo(os, dim);
+      }
+      os << ">";
     } else {
       UNREACHABLE();
     }
@@ -1369,38 +1246,38 @@
 
 
 #ifdef DEBUG
-template <class Config>
-void TypeImpl<Config>::Print() {
+void Type::Print() {
   OFStream os(stdout);
   PrintTo(os);
   os << std::endl;
 }
-template <class Config>
-void TypeImpl<Config>::BitsetType::Print(bitset bits) {
+void BitsetType::Print(bitset bits) {
   OFStream os(stdout);
   Print(os, bits);
   os << std::endl;
 }
 #endif
 
+BitsetType::bitset BitsetType::SignedSmall() {
+  return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
+}
+
+BitsetType::bitset BitsetType::UnsignedSmall() {
+  return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
+}
+
+#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
+  Type* Type::Name(Isolate* isolate, Zone* zone) {                   \
+    return Class(i::handle(isolate->heap()->name##_map()), zone);    \
+  }
+SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
+#undef CONSTRUCT_SIMD_TYPE
 
 // -----------------------------------------------------------------------------
 // Instantiations.
 
-template class TypeImpl<ZoneTypeConfig>;
-template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
-template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
-
-template class TypeImpl<HeapTypeConfig>;
-template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
-template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
-
-template TypeImpl<ZoneTypeConfig>::TypeHandle
-  TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
-    TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
-template TypeImpl<HeapTypeConfig>::TypeHandle
-  TypeImpl<HeapTypeConfig>::Convert<Type>(
-    TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
+template class Type::Iterator<i::Map>;
+template class Type::Iterator<i::Object>;
 
 }  // namespace internal
 }  // namespace v8