[turbofan] Use unboxed doubles in range types.
authorjarin <jarin@chromium.org>
Wed, 28 Jan 2015 13:55:35 +0000 (05:55 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 28 Jan 2015 13:55:45 +0000 (13:55 +0000)
BUG=
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/882063002

Cr-Commit-Position: refs/heads/master@{#26307}

12 files changed:
src/compiler/js-typed-lowering.cc
src/compiler/simplified-lowering.cc
src/compiler/typer.cc
src/compiler/typer.h
src/types-inl.h
src/types.cc
src/types.h
test/cctest/compiler/test-simplified-lowering.cc
test/cctest/compiler/test-typer.cc
test/cctest/test-types.cc
test/cctest/types-fuzz.h
test/unittests/compiler/js-typed-lowering-unittest.cc

index 8f8fb1c..35d4772 100644 (file)
@@ -30,26 +30,23 @@ static void RelaxEffects(Node* node) {
 
 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone)
     : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) {
-  Handle<Object> zero = factory()->NewNumber(0.0);
-  Handle<Object> one = factory()->NewNumber(1.0);
-  zero_range_ = Type::Range(zero, zero, graph()->zone());
-  one_range_ = Type::Range(one, one, graph()->zone());
-  Handle<Object> thirtyone = factory()->NewNumber(31.0);
-  zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone());
+  zero_range_ = Type::Range(0.0, 1.0, graph()->zone());
+  one_range_ = Type::Range(1.0, 1.0, graph()->zone());
+  zero_thirtyone_range_ = Type::Range(0.0, 31.0, graph()->zone());
   // TODO(jarin): Can we have a correctification of the stupid type system?
   // These stupid work-arounds are just stupid!
   shifted_int32_ranges_[0] = Type::Signed32();
   if (SmiValuesAre31Bits()) {
     shifted_int32_ranges_[1] = Type::SignedSmall();
     for (size_t k = 2; k < arraysize(shifted_int32_ranges_); ++k) {
-      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
-      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
+      double min = kMinInt / (1 << k);
+      double max = kMaxInt / (1 << k);
       shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
     }
   } else {
     for (size_t k = 1; k < arraysize(shifted_int32_ranges_); ++k) {
-      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
-      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
+      double min = kMinInt / (1 << k);
+      double max = kMaxInt / (1 << k);
       shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
     }
   }
index 2c1db33..d1f81d2 100644 (file)
@@ -75,10 +75,8 @@ class RepresentationSelector {
         queue_(zone) {
     memset(info_, 0, sizeof(NodeInfo) * count_);
 
-    Factory* f = jsgraph->isolate()->factory();
     safe_int_additive_range_ =
-        Type::Range(f->NewNumber(-std::pow(2.0, 52.0)),
-                    f->NewNumber(std::pow(2.0, 52.0)), zone);
+        Type::Range(-std::pow(2.0, 52.0), std::pow(2.0, 52.0), zone);
   }
 
   void Run(SimplifiedLowering* lowering) {
index 6bde0c0..39267c9 100644 (file)
@@ -129,8 +129,7 @@ class LazyTypeCache FINAL : public ZoneObject {
   }
 
   Type* CreateRange(double min, double max) const {
-    return Type::Range(factory()->NewNumber(min), factory()->NewNumber(max),
-                       zone());
+    return Type::Range(min, max, zone());
   }
 
   Factory* factory() const { return isolate()->factory(); }
@@ -164,8 +163,6 @@ Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context)
   Zone* zone = this->zone();
   Factory* f = isolate->factory();
 
-  Handle<Object> zero = f->NewNumber(0);
-  Handle<Object> one = f->NewNumber(1);
   Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
   Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
 
@@ -183,8 +180,8 @@ Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context)
   undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
   singleton_false = Type::Constant(f->false_value(), zone);
   singleton_true = Type::Constant(f->true_value(), zone);
-  singleton_zero = Type::Range(zero, zero, zone);
-  singleton_one = Type::Range(one, one, zone);
+  singleton_zero = Type::Range(0.0, 0.0, zone);
+  singleton_one = Type::Range(1.0, 1.0, zone);
   zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
   zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone);
   signed32ish = Type::Union(signed32, truncating_to_zero, zone);
@@ -196,7 +193,7 @@ Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context)
   truish = Type::Union(
       singleton_true,
       Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
-  integer = Type::Range(minusinfinity, infinity, zone);
+  integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone);
   weakint = Type::Union(integer, nan_or_minuszero, zone);
 
   number_fun0_ = Type::Function(number, zone);
@@ -212,11 +209,11 @@ Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context)
   weaken_max_limits_.reserve(limits_count + 1);
 
   double limit = 1 << 30;
-  weaken_min_limits_.push_back(f->NewNumber(0));
-  weaken_max_limits_.push_back(f->NewNumber(0));
+  weaken_min_limits_.push_back(0);
+  weaken_max_limits_.push_back(0);
   for (int i = 0; i < limits_count; i++) {
-    weaken_min_limits_.push_back(f->NewNumber(-limit));
-    weaken_max_limits_.push_back(f->NewNumber(limit - 1));
+    weaken_min_limits_.push_back(-limit);
+    weaken_max_limits_.push_back(limit - 1);
     limit *= 2;
   }
 
@@ -496,8 +493,7 @@ Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
     DCHECK(std::isnan(max));
     return type;
   }
-  Factory* f = t->isolate()->factory();
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
 }
 
 
@@ -610,8 +606,7 @@ Bounds Typer::Visitor::TypeOsrValue(Node* node) {
 
 
 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
-  Factory* f = isolate()->factory();
-  Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
+  double number = OpParameter<int32_t>(node);
   return Bounds(Type::Intersect(
       Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone()));
 }
@@ -826,7 +821,6 @@ Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
 
 
 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
-  Factory* f = t->isolate()->factory();
   lhs = NumberToInt32(ToNumber(lhs, t), t);
   rhs = NumberToInt32(ToNumber(rhs, t), t);
   double lmin = lhs->Min();
@@ -854,13 +848,12 @@ Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
     // value.
     max = std::min(max, -1.0);
   }
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
   // TODO(neis): Be precise for singleton inputs, here and elsewhere.
 }
 
 
 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
-  Factory* f = t->isolate()->factory();
   lhs = NumberToInt32(ToNumber(lhs, t), t);
   rhs = NumberToInt32(ToNumber(rhs, t), t);
   double lmin = lhs->Min();
@@ -882,7 +875,7 @@ Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
     min = 0;
     max = std::min(max, rmax);
   }
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
 }
 
 
@@ -942,8 +935,7 @@ Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
   // TODO(jarin) Ideally, the following micro-optimization should be performed
   // by the type constructor.
   if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
-    Factory* f = t->isolate()->factory();
-    return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+    return Type::Range(min, max, t->zone());
   }
   return Type::Signed32();
 }
@@ -951,11 +943,8 @@ Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
 
 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
   lhs = NumberToUint32(ToNumber(lhs, t), t);
-  Factory* f = t->isolate()->factory();
   // Logical right-shifting any value cannot make it larger.
-  Handle<Object> min = f->NewNumber(0);
-  Handle<Object> max = f->NewNumber(lhs->Max());
-  return Type::Range(min, max, t->zone());
+  return Type::Range(0.0, lhs->Max(), t->zone());
 }
 
 
@@ -997,10 +986,10 @@ static double array_max(double a[], size_t n) {
 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
                                   Typer* t) {
   double results[4];
-  results[0] = lhs->Min()->Number() + rhs->Min()->Number();
-  results[1] = lhs->Min()->Number() + rhs->Max()->Number();
-  results[2] = lhs->Max()->Number() + rhs->Min()->Number();
-  results[3] = lhs->Max()->Number() + rhs->Max()->Number();
+  results[0] = lhs->Min() + rhs->Min();
+  results[1] = lhs->Min() + rhs->Max();
+  results[2] = lhs->Max() + rhs->Min();
+  results[3] = lhs->Max() + rhs->Max();
   // Since none of the inputs can be -0, the result cannot be -0 either.
   // However, it can be nan (the sum of two infinities of opposite sign).
   // On the other hand, if none of the "results" above is nan, then the actual
@@ -1010,9 +999,8 @@ Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
     if (std::isnan(results[i])) ++nans;
   }
   if (nans == 4) return Type::NaN();  // [-inf..-inf] + [inf..inf] or vice versa
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
   // Examples:
   //   [-inf, -inf] + [+inf, +inf] = NaN
@@ -1046,10 +1034,10 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
                                        Type::RangeType* rhs, Typer* t) {
   double results[4];
-  results[0] = lhs->Min()->Number() - rhs->Min()->Number();
-  results[1] = lhs->Min()->Number() - rhs->Max()->Number();
-  results[2] = lhs->Max()->Number() - rhs->Min()->Number();
-  results[3] = lhs->Max()->Number() - rhs->Max()->Number();
+  results[0] = lhs->Min() - rhs->Min();
+  results[1] = lhs->Min() - rhs->Max();
+  results[2] = lhs->Max() - rhs->Min();
+  results[3] = lhs->Max() - rhs->Max();
   // Since none of the inputs can be -0, the result cannot be -0.
   // However, it can be nan (the subtraction of two infinities of same sign).
   // On the other hand, if none of the "results" above is nan, then the actual
@@ -1059,9 +1047,8 @@ Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
     if (std::isnan(results[i])) ++nans;
   }
   if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
   // Examples:
   //   [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
@@ -1085,10 +1072,10 @@ Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
                                        Type::RangeType* rhs, Typer* t) {
   double results[4];
-  double lmin = lhs->Min()->Number();
-  double lmax = lhs->Max()->Number();
-  double rmin = rhs->Min()->Number();
-  double rmax = rhs->Max()->Number();
+  double lmin = lhs->Min();
+  double lmax = lhs->Max();
+  double rmin = rhs->Min();
+  double rmax = rhs->Max();
   results[0] = lmin * rmin;
   results[1] = lmin * rmax;
   results[2] = lmax * rmin;
@@ -1104,9 +1091,8 @@ Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
   if (maybe_nan) return t->weakint;  // Giving up.
   bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
                          (rhs->Maybe(t->singleton_zero) && lmin < 0);
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
                          : range;
 }
@@ -1139,10 +1125,10 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
 
 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
                                       Type::RangeType* rhs, Typer* t) {
-  double lmin = lhs->Min()->Number();
-  double lmax = lhs->Max()->Number();
-  double rmin = rhs->Min()->Number();
-  double rmax = rhs->Max()->Number();
+  double lmin = lhs->Min();
+  double lmax = lhs->Max();
+  double rmin = rhs->Min();
+  double rmax = rhs->Max();
 
   double labs = std::max(std::abs(lmin), std::abs(lmax));
   double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
@@ -1163,8 +1149,7 @@ Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
     maybe_minus_zero = true;
   }
 
-  Factory* f = t->isolate()->factory();
-  Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone());
+  Type* result = Type::Range(omin, omax, t->zone());
   if (maybe_minus_zero)
     result = Type::Union(result, Type::MinusZero(), t->zone());
   return result;
@@ -1287,29 +1272,28 @@ Type* Typer::Visitor::Weaken(Type* current_type, Type* previous_type) {
   Type::RangeType* previous = previous_number->AsRange();
   Type::RangeType* current = current_number->AsRange();
 
-  double current_min = current->Min()->Number();
-  Handle<Object> new_min = current->Min();
-
+  double current_min = current->Min();
+  double new_min = current_min;
   // Find the closest lower entry in the list of allowed
   // minima (or negative infinity if there is no such entry).
-  if (current_min != previous->Min()->Number()) {
+  if (current_min != previous->Min()) {
     new_min = typer_->integer->AsRange()->Min();
     for (const auto val : typer_->weaken_min_limits_) {
-      if (val->Number() <= current_min) {
+      if (val <= current_min) {
         new_min = val;
         break;
       }
     }
   }
 
-  double current_max = current->Max()->Number();
-  Handle<Object> new_max = current->Max();
+  double current_max = current->Max();
+  double new_max = current_max;
   // Find the closest greater entry in the list of allowed
   // maxima (or infinity if there is no such entry).
-  if (current_max != previous->Max()->Number()) {
+  if (current_max != previous->Max()) {
     new_max = typer_->integer->AsRange()->Max();
     for (const auto val : typer_->weaken_max_limits_) {
-      if (val->Number() >= current_max) {
+      if (val >= current_max) {
         new_max = val;
         break;
       }
index ad488af..87246ff 100644 (file)
@@ -65,8 +65,8 @@ class Typer {
   Type* random_fun_;
   LazyTypeCache* cache_;
 
-  ZoneVector<Handle<Object> > weaken_min_limits_;
-  ZoneVector<Handle<Object> > weaken_max_limits_;
+  ZoneVector<double> weaken_min_limits_;
+  ZoneVector<double> weaken_max_limits_;
   DISALLOW_COPY_AND_ASSIGN(Typer);
 };
 
index c22dfd4..762a11d 100644 (file)
@@ -96,7 +96,18 @@ bool ZoneTypeConfig::is_bitset(Type* type) {
 
 // static
 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
-  return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
+  DCHECK(tag != kRangeStructTag);
+  if (is_bitset(type)) return false;
+  int type_tag = struct_tag(as_struct(type));
+  return type_tag == tag;
+}
+
+
+// static
+bool ZoneTypeConfig::is_range(Type* type) {
+  if (is_bitset(type)) return false;
+  int type_tag = struct_tag(as_struct(type));
+  return type_tag == kRangeStructTag;
 }
 
 
@@ -121,6 +132,13 @@ ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
 
 
 // static
+ZoneTypeConfig::Range* ZoneTypeConfig::as_range(Type* type) {
+  DCHECK(!is_bitset(type));
+  return reinterpret_cast<Range*>(type);
+}
+
+
+// static
 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
   UNREACHABLE();
   return i::Handle<i::Map>();
@@ -147,6 +165,12 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
 
 
 // static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_range(Range* range) {
+  return reinterpret_cast<Type*>(range);
+}
+
+
+// static
 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
     i::Handle<i::Map> map, Zone* zone) {
   return from_bitset(0);
@@ -156,6 +180,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
 // static
 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
     int tag, int length, Zone* zone) {
+  DCHECK(tag != kRangeStructTag);
   Struct* structure = reinterpret_cast<Struct*>(
       zone->New(sizeof(void*) * (length + 2)));  // NOLINT
   structure[0] = reinterpret_cast<void*>(tag);
@@ -214,6 +239,45 @@ void ZoneTypeConfig::struct_set_value(
 }
 
 
+// static
+ZoneTypeConfig::Range* ZoneTypeConfig::range_create(Zone* zone) {
+  Range* range = reinterpret_cast<Range*>(zone->New(sizeof(Range)));  // NOLINT
+  range->tag = reinterpret_cast<void*>(kRangeStructTag);
+  range->bitset = 0;
+  range->limits[0] = 1;
+  range->limits[1] = 0;
+  return range;
+}
+
+
+// static
+int ZoneTypeConfig::range_get_bitset(ZoneTypeConfig::Range* range) {
+  return range->bitset;
+}
+
+
+// static
+void ZoneTypeConfig::range_set_bitset(ZoneTypeConfig::Range* range, int value) {
+  range->bitset = value;
+}
+
+
+// static
+double ZoneTypeConfig::range_get_double(ZoneTypeConfig::Range* range,
+                                        int index) {
+  DCHECK(index >= 0 && index < 2);
+  return range->limits[index];
+}
+
+
+// static
+void ZoneTypeConfig::range_set_double(ZoneTypeConfig::Range* range, int index,
+                                      double value, Zone*) {
+  DCHECK(index >= 0 && index < 2);
+  range->limits[index] = value;
+}
+
+
 // -----------------------------------------------------------------------------
 // HeapTypeConfig
 
@@ -252,11 +316,18 @@ bool HeapTypeConfig::is_class(Type* type) {
 
 // static
 bool HeapTypeConfig::is_struct(Type* type, int tag) {
+  DCHECK(tag != kRangeStructTag);
   return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
 }
 
 
 // static
+bool HeapTypeConfig::is_range(Type* type) {
+  return type->IsFixedArray() && struct_tag(as_struct(type)) == kRangeStructTag;
+}
+
+
+// static
 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
@@ -276,6 +347,12 @@ i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
 
 
 // static
+i::Handle<HeapTypeConfig::Range> HeapTypeConfig::as_range(Type* type) {
+  return i::handle(Range::cast(type));
+}
+
+
+// static
 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
@@ -304,6 +381,13 @@ i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
 
 
 // static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_range(
+    i::Handle<Range> range) {
+  return i::Handle<Type>::cast(i::Handle<Object>::cast(range));
+}
+
+
+// static
 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
     int tag, int length, Isolate* isolate) {
   i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
@@ -361,6 +445,46 @@ void HeapTypeConfig::struct_set_value(
   structure->set(i + 1, *x);
 }
 
+
+// static
+i::Handle<HeapTypeConfig::Range> HeapTypeConfig::range_create(
+    Isolate* isolate) {
+  i::Handle<Range> range = isolate->factory()->NewFixedArray(4);
+  range->set(0, i::Smi::FromInt(kRangeStructTag));
+  return range;
+}
+
+
+// static
+int HeapTypeConfig::range_get_bitset(i::Handle<HeapTypeConfig::Range> range) {
+  Type* v = static_cast<Type*>(range->get(1));
+  return as_bitset(v);
+}
+
+
+// static
+void HeapTypeConfig::range_set_bitset(i::Handle<HeapTypeConfig::Range> range,
+                                      int value) {
+  range->set(1, from_bitset(value));
+}
+
+
+// static
+double HeapTypeConfig::range_get_double(i::Handle<HeapTypeConfig::Range> range,
+                                        int index) {
+  DCHECK(index >= 0 && index < 2);
+  return range->get(index + 2)->Number();
+}
+
+
+// static
+void HeapTypeConfig::range_set_double(i::Handle<HeapTypeConfig::Range> range,
+                                      int index, double value,
+                                      Isolate* isolate) {
+  DCHECK(index >= 0 && index < 2);
+  i::Handle<Object> number = isolate->factory()->NewNumber(value);
+  range->set(index + 2, *number);
+}
 } }  // namespace v8::internal
 
 #endif  // V8_TYPES_INL_H_
index c2d4eaa..3413d34 100644 (file)
@@ -26,8 +26,8 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect(
     Limits lhs, Limits rhs) {
   DisallowHeapAllocation no_allocation;
   Limits result(lhs);
-  if (lhs.min->Number() < rhs.min->Number()) result.min = rhs.min;
-  if (lhs.max->Number() > rhs.max->Number()) result.max = rhs.max;
+  if (lhs.min < rhs.min) result.min = rhs.min;
+  if (lhs.max > rhs.max) result.max = rhs.max;
   result.representation = lhs.representation & rhs.representation;
   return result;
 }
@@ -35,7 +35,7 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect(
 
 template <class Config>
 bool TypeImpl<Config>::IsEmpty(Limits lim) {
-  return lim.min->Number() > lim.max->Number();
+  return lim.min > lim.max;
 }
 
 
@@ -44,8 +44,8 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs,
                                                           Limits rhs) {
   DisallowHeapAllocation no_allocation;
   Limits result(lhs);
-  if (lhs.min->Number() > rhs.min->Number()) result.min = rhs.min;
-  if (lhs.max->Number() < rhs.max->Number()) result.max = rhs.max;
+  if (lhs.min > rhs.min) result.min = rhs.min;
+  if (lhs.max < rhs.max) result.max = rhs.max;
   result.representation = lhs.representation | rhs.representation;
   return result;
 }
@@ -57,7 +57,7 @@ bool TypeImpl<Config>::Overlap(
     typename TypeImpl<Config>::RangeType* rhs) {
   DisallowHeapAllocation no_allocation;
   typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs));
-  return lim.min->Number() <= lim.max->Number();
+  return lim.min <= lim.max;
 }
 
 
@@ -66,9 +66,8 @@ bool TypeImpl<Config>::Contains(
     typename TypeImpl<Config>::RangeType* lhs,
     typename TypeImpl<Config>::RangeType* rhs) {
   DisallowHeapAllocation no_allocation;
-  return rhs->Bound()->Is(lhs->Bound()) &&
-         lhs->Min()->Number() <= rhs->Min()->Number() &&
-         rhs->Max()->Number() <= lhs->Max()->Number();
+  return BitsetType::Is(rhs->Bound(), lhs->Bound()) &&
+         lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
 }
 
 
@@ -76,9 +75,10 @@ template <class Config>
 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs,
                                 typename TypeImpl<Config>::ConstantType* rhs) {
   DisallowHeapAllocation no_allocation;
-  return IsInteger(*rhs->Value()) && rhs->Bound()->Is(lhs->Bound()) &&
-         lhs->Min()->Number() <= rhs->Value()->Number() &&
-         rhs->Value()->Number() <= lhs->Max()->Number();
+  return IsInteger(*rhs->Value()) &&
+         BitsetType::Is(rhs->Bound()->AsBitset(), lhs->Bound()) &&
+         lhs->Min() <= rhs->Value()->Number() &&
+         rhs->Value()->Number() <= lhs->Max();
 }
 
 
@@ -87,9 +87,8 @@ bool TypeImpl<Config>::Contains(
     typename TypeImpl<Config>::RangeType* range, i::Object* val) {
   DisallowHeapAllocation no_allocation;
   return IsInteger(val) &&
-         BitsetType::Is(BitsetType::Lub(val), range->Bound()->AsBitset()) &&
-         range->Min()->Number() <= val->Number() &&
-         val->Number() <= range->Max()->Number();
+         BitsetType::Is(BitsetType::Lub(val), range->Bound()) &&
+         range->Min() <= val->Number() && val->Number() <= range->Max();
 }
 
 
@@ -107,7 +106,7 @@ double TypeImpl<Config>::Min() {
     }
     return min;
   }
-  if (this->IsRange()) return this->AsRange()->Min()->Number();
+  if (this->IsRange()) return this->AsRange()->Min();
   if (this->IsConstant()) return this->AsConstant()->Value()->Number();
   UNREACHABLE();
   return 0;
@@ -125,7 +124,7 @@ double TypeImpl<Config>::Max() {
     }
     return max;
   }
-  if (this->IsRange()) return this->AsRange()->Max()->Number();
+  if (this->IsRange()) return this->AsRange()->Max();
   if (this->IsConstant()) return this->AsConstant()->Value()->Number();
   UNREACHABLE();
   return 0;
@@ -148,8 +147,8 @@ TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
     return type->AsUnion()->Get(0)->BitsetGlb() |
            type->AsUnion()->Get(1)->BitsetGlb();  // Shortcut.
   } else if (type->IsRange()) {
-    bitset glb = SEMANTIC(BitsetType::Glb(type->AsRange()->Min()->Number(),
-                                          type->AsRange()->Max()->Number()));
+    bitset glb = SEMANTIC(
+        BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
     if (glb == 0) {
       return kNone;
     } else {
@@ -181,7 +180,7 @@ TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
         type->AsClass()->Bound(NULL)->AsBitset();
   }
   if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
-  if (type->IsRange()) return type->AsRange()->Bound()->AsBitset();
+  if (type->IsRange()) return type->AsRange()->Bound();
   if (type->IsContext()) return kInternal & kTaggedPointer;
   if (type->IsArray()) return kArray;
   if (type->IsFunction()) return kOtherObject;  // TODO(rossberg): kFunction
@@ -765,13 +764,7 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits,
     return Limits::Empty(region);
   }
 
-  double bitset_min = BitsetType::Min(number_bits);
-  double bitset_max = BitsetType::Max(number_bits);
-
-  // TODO(jarin) Get rid of the heap numbers.
-  i::Factory* f = i::Isolate::Current()->factory();
-
-  return Limits(f->NewNumber(bitset_min), f->NewNumber(bitset_max),
+  return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits),
                 representation);
 }
 
@@ -874,10 +867,8 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
   double bitset_min = BitsetType::Min(number_bits);
   double bitset_max = BitsetType::Max(number_bits);
 
-  i::Handle<i::Object> range_min_obj = range->Min();
-  i::Handle<i::Object> range_max_obj = range->Max();
-  double range_min = range_min_obj->Number();
-  double range_max = range_max_obj->Number();
+  double range_min = range->Min();
+  double range_max = range->Max();
 
   bitset range_representation = REPRESENTATION(range->BitsetLub());
   bitset bits_representation = REPRESENTATION(*bits);
@@ -897,14 +888,12 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
   }
 
   if (bitset_min < range_min) {
-    // TODO(jarin) Get rid of the heap numbers.
-    range_min_obj = i::Isolate::Current()->factory()->NewNumber(bitset_min);
+    range_min = bitset_min;
   }
   if (bitset_max > range_max) {
-    // TODO(jarin) Get rid of the heap numbers.
-    range_max_obj = i::Isolate::Current()->factory()->NewNumber(bitset_max);
+    range_max = bitset_max;
   }
-  return RangeType::New(range_min_obj, range_max_obj,
+  return RangeType::New(range_min, range_max,
                         BitsetType::New(representation, region), region);
 }
 
@@ -1227,8 +1216,8 @@ void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
     } else if (this->IsRange()) {
       std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
       std::streamsize saved_precision = os.precision(0);
-      os << "Range(" << this->AsRange()->Min()->Number() << ", "
-         << this->AsRange()->Max()->Number() << ")";
+      os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
+         << ")";
       os.flags(saved_flags);
       os.precision(saved_precision);
     } else if (this->IsContext()) {
index 0f59c0c..55c7e6c 100644 (file)
@@ -270,21 +270,29 @@ namespace internal {
 //   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);
@@ -295,6 +303,12 @@ namespace internal {
 //   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 {
@@ -354,8 +368,7 @@ class TypeImpl : public Config::Base {
   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) {
+  static TypeHandle Range(double min, double max, Region* region) {
     return RangeType::New(
         min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged |
                                                  BitsetType::kUntaggedNumber),
@@ -453,6 +466,7 @@ class TypeImpl : public Config::Base {
 
   // Inspection.
 
+  bool IsRange() { return Config::is_range(this); }
   bool IsClass() {
     return Config::is_class(this)
         || Config::is_struct(this, StructuralType::kClassTag);
@@ -460,9 +474,6 @@ class TypeImpl : public Config::Base {
   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);
   }
@@ -523,6 +534,8 @@ class TypeImpl : public Config::Base {
   void Print();
 #endif
 
+  bool IsUnionForTesting() { return IsUnion(); }
+
  protected:
   // Friends.
 
@@ -565,22 +578,17 @@ class TypeImpl : public Config::Base {
   }
 
   struct Limits {
-    i::Handle<i::Object> min;
-    i::Handle<i::Object> max;
+    double min;
+    double max;
     bitset representation;
-    Limits(i::Handle<i::Object> min, i::Handle<i::Object> max,
-           bitset representation)
+    Limits(double min, double max, bitset representation)
         : min(min), max(max), representation(representation) {}
     explicit Limits(RangeType* range)
         : min(range->Min()),
           max(range->Max()),
-          representation(REPRESENTATION(range->Bound()->AsBitset())) {}
+          representation(REPRESENTATION(range->Bound())) {}
     static Limits Empty(Region* region) {
-      // TODO(jarin) Get rid of the heap numbers.
-      i::Factory* f = i::Isolate::Current()->factory();
-      i::Handle<i::Object> min = f->NewNumber(1);
-      i::Handle<i::Object> max = f->NewNumber(0);
-      return Limits(min, max, BitsetType::kNone);
+      return Limits(1, 0, BitsetType::kNone);
     }
   };
 
@@ -698,7 +706,6 @@ class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
   enum Tag {
     kClassTag,
     kConstantTag,
-    kRangeTag,
     kContextTag,
     kArrayTag,
     kFunctionTag,
@@ -824,29 +831,28 @@ class TypeImpl<Config>::ConstantType : public StructuralType {
 // -----------------------------------------------------------------------------
 // Range types.
 
-template<class Config>
-class TypeImpl<Config>::RangeType : public StructuralType {
+template <class Config>
+class TypeImpl<Config>::RangeType : public TypeImpl<Config> {
  public:
-  TypeHandle Bound() { return this->Get(0); }
-  i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); }
-  i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); }
-
-  static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max,
-                         TypeHandle representation, Region* region) {
-    DCHECK(IsInteger(min->Number()) && IsInteger(max->Number()));
-    DCHECK(min->Number() <= max->Number());
+  bitset Bound() { return Config::range_get_bitset(Config::as_range(this)); }
+  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(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);
 
-    RangeHandle type = Config::template cast<RangeType>(
-        StructuralType::New(StructuralType::kRangeTag, 3, region));
+    typename Config::template Handle<typename Config::Range>::type range =
+        Config::range_create(region);
 
-    bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) |
-                  representation_bits;
-    type->Set(0, BitsetType::New(bits, region));
-    type->SetValue(1, min);
-    type->SetValue(2, max);
-    return type;
+    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) {
@@ -970,9 +976,19 @@ struct ZoneTypeConfig {
   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; };
 
+  static const int kRangeStructTag = 0x1000;
+
   template<class T> static inline T* null_handle();
   template<class T> static inline T* handle(T* type);
   template<class T> static inline T* cast(Type* type);
@@ -980,15 +996,18 @@ struct ZoneTypeConfig {
   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);
@@ -1000,6 +1019,12 @@ struct ZoneTypeConfig {
   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;
@@ -1013,9 +1038,12 @@ struct HeapTypeConfig {
   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; };
 
+  static const int kRangeStructTag = 0xffff;
+
   template<class T> static inline i::Handle<T> null_handle();
   template<class T> static inline i::Handle<T> handle(T* type);
   template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
@@ -1023,16 +1051,19 @@ struct HeapTypeConfig {
   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);
@@ -1048,6 +1079,13 @@ struct HeapTypeConfig {
   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;
index d770aa3..96acf2e 100644 (file)
@@ -972,11 +972,8 @@ TEST(LowerNumberCmp_to_float64) {
 
 TEST(LowerNumberAddSub_to_int32) {
   HandleAndZoneScope scope;
-  Factory* f = scope.main_isolate()->factory();
-  Type* small_range =
-      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
-  Type* large_range =
-      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  Type* small_range = Type::Range(1, 10, scope.main_zone());
+  Type* large_range = Type::Range(-1e+13, 1e+14, scope.main_zone());
   static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
                           large_range};
 
@@ -996,11 +993,8 @@ TEST(LowerNumberAddSub_to_int32) {
 
 TEST(LowerNumberAddSub_to_uint32) {
   HandleAndZoneScope scope;
-  Factory* f = scope.main_isolate()->factory();
-  Type* small_range =
-      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
-  Type* large_range =
-      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  Type* small_range = Type::Range(1, 10, scope.main_zone());
+  Type* large_range = Type::Range(-1e+13, 1e+14, scope.main_zone());
   static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
                           large_range};
 
index eb5e540..d6aaba5 100644 (file)
@@ -87,11 +87,8 @@ class TyperTester : public HandleAndZoneScope, public GraphAndBuilders {
   }
 
   Type* NewRange(double i, double j) {
-    Factory* f = isolate()->factory();
-    i::Handle<i::Object> min = f->NewNumber(i);
-    i::Handle<i::Object> max = f->NewNumber(j);
-    if (min->Number() > max->Number()) std::swap(min, max);
-    return Type::Range(min, max, main_zone());
+    if (i > j) std::swap(i, j);
+    return Type::Range(i, j, main_zone());
   }
 
   double RandomInt(double min, double max) {
@@ -113,7 +110,7 @@ class TyperTester : public HandleAndZoneScope, public GraphAndBuilders {
   }
 
   double RandomInt(Type::RangeType* range) {
-    return RandomInt(range->Min()->Number(), range->Max()->Number());
+    return RandomInt(range->Min(), range->Max());
   }
 
   // Careful, this function runs O(max_width^5) trials.
index 5853e95..34592d8 100644 (file)
@@ -36,7 +36,8 @@ struct ZoneRep {
     return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
   }
   static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
-  static bool IsUnion(Type* t) { return IsStruct(t, 6); }
+  // HACK: the number 5 below is the value of StructuralType::kUnionTag.
+  static bool IsUnion(Type* t) { return t->IsUnionForTesting(); }
 
   static Struct* AsStruct(Type* t) {
     return reinterpret_cast<Struct*>(t);
@@ -69,7 +70,8 @@ struct HeapRep {
     return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
   }
   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
-  static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
+  // HACK: the number 5 below is the value of StructuralType::kUnionTag.
+  static bool IsUnion(Handle<HeapType> t) { return t->IsUnionForTesting(); }
 
   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
   static bitset AsBitset(Handle<HeapType> t) {
@@ -351,9 +353,9 @@ struct Tests : Rep {
     // Constructor
     for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
       for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
-        i::Handle<i::Object> min = *i;
-        i::Handle<i::Object> max = *j;
-        if (min->Number() > max->Number()) std::swap(min, max);
+        double min = (*i)->Number();
+        double max = (*j)->Number();
+        if (min > max) std::swap(min, max);
         TypeHandle type = T.Range(min, max);
         CHECK(type->IsRange());
       }
@@ -362,12 +364,12 @@ struct Tests : Rep {
     // Range attributes
     for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
       for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
-        i::Handle<i::Object> min = *i;
-        i::Handle<i::Object> max = *j;
-        if (min->Number() > max->Number()) std::swap(min, max);
+        double min = (*i)->Number();
+        double max = (*j)->Number();
+        if (min > max) std::swap(min, max);
         TypeHandle type = T.Range(min, max);
-        CHECK(*min == *type->AsRange()->Min());
-        CHECK(*max == *type->AsRange()->Max());
+        CHECK(min == type->AsRange()->Min());
+        CHECK(max == type->AsRange()->Max());
       }
     }
 
@@ -381,15 +383,15 @@ struct Tests : Rep {
             i2 != T.integers.end(); ++i2) {
           for (ValueIterator j2 = i2;
               j2 != T.integers.end(); ++j2) {
-            i::Handle<i::Object> min1 = *i1;
-            i::Handle<i::Object> max1 = *j1;
-            i::Handle<i::Object> min2 = *i2;
-            i::Handle<i::Object> max2 = *j2;
-            if (min1->Number() > max1->Number()) std::swap(min1, max1);
-            if (min2->Number() > max2->Number()) std::swap(min2, max2);
+            double min1 = (*i1)->Number();
+            double max1 = (*j1)->Number();
+            double min2 = (*i2)->Number();
+            double max2 = (*j2)->Number();
+            if (min1 > max1) std::swap(min1, max1);
+            if (min2 > max2) std::swap(min2, max2);
             TypeHandle type1 = T.Range(min1, max1);
             TypeHandle type2 = T.Range(min2, max2);
-            CHECK(Equal(type1, type2) == (*min1 == *min2 && *max1 == *max2));
+            CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2));
           }
         }
       }
@@ -608,8 +610,6 @@ struct Tests : Rep {
   }
 
   void MinMax() {
-    Factory* fac = isolate->factory();
-
     // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b).
     // TODO(neis): Need to ignore representation for this to be true.
     /*
@@ -662,8 +662,7 @@ struct Tests : Rep {
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
       TypeHandle type = *it;
       CHECK(!(type->Is(T.Integer) && !type->Is(T.None)) ||
-            type->Is(T.Range(fac->NewNumber(type->Min()),
-                             fac->NewNumber(type->Max()))));
+            type->Is(T.Range(type->Min(), type->Max())));
     }
   }
 
@@ -828,17 +827,15 @@ struct Tests : Rep {
              i2 != T.integers.end(); ++i2) {
           for (ValueIterator j2 = i2;
                j2 != T.integers.end(); ++j2) {
-            i::Handle<i::Object> min1 = *i1;
-            i::Handle<i::Object> max1 = *j1;
-            i::Handle<i::Object> min2 = *i2;
-            i::Handle<i::Object> max2 = *j2;
-            if (min1->Number() > max1->Number()) std::swap(min1, max1);
-            if (min2->Number() > max2->Number()) std::swap(min2, max2);
+            double min1 = (*i1)->Number();
+            double max1 = (*j1)->Number();
+            double min2 = (*i2)->Number();
+            double max2 = (*j2)->Number();
+            if (min1 > max1) std::swap(min1, max1);
+            if (min2 > max2) std::swap(min2, max2);
             TypeHandle type1 = T.Range(min1, max1);
             TypeHandle type2 = T.Range(min2, max2);
-            CHECK(type1->Is(type2) ==
-                (min1->Number() >= min2->Number() &&
-                 max1->Number() <= max2->Number()));
+            CHECK(type1->Is(type2) == (min1 >= min2 && max1 <= max2));
           }
         }
       }
@@ -898,8 +895,8 @@ struct Tests : Rep {
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
       TypeHandle type = *it;
       if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) {
-        CHECK(type->Is(
-            T.Range(type->AsConstant()->Value(), type->AsConstant()->Value())));
+        CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(),
+                               type->AsConstant()->Value()->Number())));
       }
     }
 
@@ -910,8 +907,8 @@ struct Tests : Rep {
         TypeHandle type2 = *it2;
         if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) {
           double x = type1->AsConstant()->Value()->Number();
-          double min = type2->AsRange()->Min()->Number();
-          double max = type2->AsRange()->Max()->Number();
+          double min = type2->AsRange()->Min();
+          double max = type2->AsRange()->Max();
           CHECK(IsInteger(x) && min <= x && x <= max);
         }
       }
@@ -1848,8 +1845,8 @@ struct Tests : Rep {
       TypeHandle type1 = *it1;
       if (type1->IsRange()) {
         typename Type::RangeType* range = type1->GetRange();
-        CHECK(type1->Min() == range->Min()->Number());
-        CHECK(type1->Max() == range->Max()->Number());
+        CHECK(type1->Min() == range->Min());
+        CHECK(type1->Max() == range->Max());
       }
     }
 
@@ -1861,8 +1858,8 @@ struct Tests : Rep {
         if (type1->IsConstant() && type2->IsRange()) {
           TypeHandle u = T.Union(type1, type2);
 
-          CHECK(type2->Min() == u->GetRange()->Min()->Number());
-          CHECK(type2->Max() == u->GetRange()->Max()->Number());
+          CHECK(type2->Min() == u->GetRange()->Min());
+          CHECK(type2->Max() == u->GetRange()->Max());
         }
       }
     }
index 7bf7512..425011d 100644 (file)
@@ -101,8 +101,7 @@ class Types {
       if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
     }
 
-    Integer = Type::Range(isolate->factory()->NewNumber(-V8_INFINITY),
-                          isolate->factory()->NewNumber(+V8_INFINITY), region);
+    Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, region);
 
     NumberArray = Type::Array(Number, region);
     StringArray = Type::Array(String, region);
@@ -184,7 +183,7 @@ class Types {
     return Type::Constant(value, region_);
   }
 
-  TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
+  TypeHandle Range(double min, double max) {
     return Type::Range(min, max, region_);
   }
 
@@ -263,9 +262,9 @@ class Types {
       case 3: {  // range
         int i = rng_->NextInt(static_cast<int>(integers.size()));
         int j = rng_->NextInt(static_cast<int>(integers.size()));
-        i::Handle<i::Object> min = integers[i];
-        i::Handle<i::Object> max = integers[j];
-        if (min->Number() > max->Number()) std::swap(min, max);
+        double min = integers[i]->Number();
+        double max = integers[j]->Number();
+        if (min > max) std::swap(min, max);
         return Type::Range(min, max, region_);
       }
       case 4: {  // context
index 57ed6fd..fb7575c 100644 (file)
@@ -119,7 +119,6 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithBoolean) {
 
 
 TEST_F(JSTypedLoweringTest, JSUnaryNotWithFalsish) {
-  Handle<Object> zero = factory()->NewNumber(0);
   Node* input = Parameter(
       Type::Union(
           Type::MinusZero(),
@@ -133,7 +132,7 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithFalsish) {
                           Type::Undetectable(),
                           Type::Union(
                               Type::Constant(factory()->false_value(), zone()),
-                              Type::Range(zero, zero, zone()), zone()),
+                              Type::Range(0.0, 0.0, zone()), zone()),
                           zone()),
                       zone()),
                   zone()),
@@ -164,9 +163,7 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithTruish) {
 
 
 TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
-  Node* input = Parameter(
-      Type::Range(factory()->NewNumber(1), factory()->NewNumber(42), zone()),
-      0);
+  Node* input = Parameter(Type::Range(1.0, 42.0, zone()), 0);
   Node* context = Parameter(Type::Any(), 1);
   Reduction r =
       Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
@@ -259,8 +256,7 @@ TEST_F(JSTypedLoweringTest, ParameterWithPlainNumber) {
     EXPECT_THAT(r.replacement(), IsNumberConstant(value));
   }
   TRACED_FOREACH(double, value, kIntegerValues) {
-    Handle<Object> constant = factory()->NewNumber(value);
-    Reduction r = Reduce(Parameter(Type::Range(constant, constant, zone())));
+    Reduction r = Reduce(Parameter(Type::Range(value, value, zone())));
     ASSERT_TRUE(r.Changed());
     EXPECT_THAT(r.replacement(), IsNumberConstant(value));
   }
@@ -299,7 +295,6 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
 
 
 TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
-  Handle<Object> zero = factory()->NewNumber(0);
   Node* input = Parameter(
       Type::Union(
           Type::MinusZero(),
@@ -313,7 +308,7 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
                           Type::Undetectable(),
                           Type::Union(
                               Type::Constant(factory()->false_value(), zone()),
-                              Type::Range(zero, zero, zone()), zone()),
+                              Type::Range(0.0, 0.0, zone()), zone()),
                           zone()),
                       zone()),
                   zone()),
@@ -344,10 +339,7 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
 
 
 TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
-  Node* input =
-      Parameter(Type::Range(factory()->NewNumber(1),
-                            factory()->NewNumber(V8_INFINITY), zone()),
-                0);
+  Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
   Node* context = Parameter(Type::Any(), 1);
   Reduction r =
       Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
@@ -593,8 +585,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
     int const element_size = static_cast<int>(array->element_size());
 
     Node* key = Parameter(
-        Type::Range(factory()->NewNumber(kMinInt / element_size),
-                    factory()->NewNumber(kMaxInt / element_size), zone()));
+        Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
     Node* base = HeapConstant(array);
     Node* context = UndefinedConstant();
     Node* effect = graph()->start();
@@ -640,8 +631,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
     int min = random_number_generator()->NextInt(static_cast<int>(kLength));
     int max = random_number_generator()->NextInt(static_cast<int>(kLength));
     if (min > max) std::swap(min, max);
-    Node* key = Parameter(Type::Range(factory()->NewNumber(min),
-                                      factory()->NewNumber(max), zone()));
+    Node* key = Parameter(Type::Range(min, max, zone()));
     Node* base = HeapConstant(array);
     Node* context = UndefinedConstant();
     Node* effect = graph()->start();
@@ -681,8 +671,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
       int const element_size = static_cast<int>(array->element_size());
 
       Node* key = Parameter(
-          Type::Range(factory()->NewNumber(kMinInt / element_size),
-                      factory()->NewNumber(kMaxInt / element_size), zone()));
+          Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
       Node* base = HeapConstant(array);
       Node* value =
           Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
@@ -728,8 +717,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
       int const element_size = static_cast<int>(array->element_size());
 
       Node* key = Parameter(
-          Type::Range(factory()->NewNumber(kMinInt / element_size),
-                      factory()->NewNumber(kMaxInt / element_size), zone()));
+          Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
       Node* base = HeapConstant(array);
       Node* value = Parameter(Type::Any());
       Node* context = UndefinedConstant();
@@ -787,8 +775,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
       int min = random_number_generator()->NextInt(static_cast<int>(kLength));
       int max = random_number_generator()->NextInt(static_cast<int>(kLength));
       if (min > max) std::swap(min, max);
-      Node* key = Parameter(Type::Range(factory()->NewNumber(min),
-                                        factory()->NewNumber(max), zone()));
+      Node* key = Parameter(Type::Range(min, max, zone()));
       Node* base = HeapConstant(array);
       Node* value = Parameter(access.type);
       Node* context = UndefinedConstant();