Index: src/compiler/types.cc |
diff --git a/src/compiler/types.cc b/src/compiler/types.cc |
index 43d2f804837b1ce596b0c8a7235e63dc11b18b49..3827cccd9f599ebfe916f01280b62a9fa7455c2f 100644 |
--- a/src/compiler/types.cc |
+++ b/src/compiler/types.cc |
@@ -56,12 +56,6 @@ bool Type::Contains(RangeType* lhs, RangeType* rhs) { |
return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); |
} |
-bool Type::Contains(RangeType* lhs, ConstantType* rhs) { |
- DisallowHeapAllocation no_allocation; |
- return IsInteger(*rhs->Value()) && lhs->Min() <= rhs->Value()->Number() && |
- rhs->Value()->Number() <= lhs->Max(); |
-} |
- |
bool Type::Contains(RangeType* range, i::Object* val) { |
DisallowHeapAllocation no_allocation; |
return IsInteger(val) && range->Min() <= val->Number() && |
@@ -82,7 +76,8 @@ double Type::Min() { |
return min; |
} |
if (this->IsRange()) return this->AsRange()->Min(); |
- if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
+ if (this->IsOtherNumberConstant()) |
+ return this->AsOtherNumberConstant()->Value(); |
UNREACHABLE(); |
return 0; |
} |
@@ -98,7 +93,8 @@ double Type::Max() { |
return max; |
} |
if (this->IsRange()) return this->AsRange()->Max(); |
- if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
+ if (this->IsOtherNumberConstant()) |
+ return this->AsOtherNumberConstant()->Value(); |
UNREACHABLE(); |
return 0; |
} |
@@ -139,7 +135,9 @@ Type::bitset BitsetType::Lub(Type* type) { |
} |
return bitset; |
} |
- if (type->IsConstant()) return type->AsConstant()->Lub(); |
+ if (type->IsHeapConstant()) return type->AsHeapConstant()->Lub(); |
+ if (type->IsOtherNumberConstant()) |
+ return type->AsOtherNumberConstant()->Lub(); |
if (type->IsRange()) return type->AsRange()->Lub(); |
if (type->IsTuple()) return kOtherInternal; |
UNREACHABLE(); |
@@ -390,14 +388,43 @@ double BitsetType::Max(bitset bits) { |
return std::numeric_limits<double>::quiet_NaN(); |
} |
+// static |
+bool OtherNumberConstantType::IsOtherNumberConstant(double value) { |
+ // Not an integer, not NaN, and not -0. |
+ return !std::isnan(value) && !Type::IsInteger(value) && |
+ !i::IsMinusZero(value); |
+} |
+ |
+// static |
+bool OtherNumberConstantType::IsOtherNumberConstant(Object* value) { |
+ return value->IsHeapNumber() && |
+ IsOtherNumberConstant(HeapNumber::cast(value)->value()); |
+} |
+ |
+HeapConstantType::HeapConstantType(BitsetType::bitset bitset, |
+ i::Handle<i::Object> object) |
+ : TypeBase(kHeapConstant), bitset_(bitset), object_(object) { |
+ // All number types should be expressed as Ranges, OtherNumberConstants, |
+ // or bitsets (nan, negative-zero). |
+ DCHECK(!object->IsSmi() && !object->IsHeapNumber()); |
+} |
+ |
// ----------------------------------------------------------------------------- |
// Predicates. |
bool Type::SimplyEquals(Type* that) { |
DisallowHeapAllocation no_allocation; |
- if (this->IsConstant()) { |
- return that->IsConstant() && |
- *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
+ if (this->IsHeapConstant()) { |
+ return that->IsHeapConstant() && |
+ *this->AsHeapConstant()->Value() == *that->AsHeapConstant()->Value(); |
+ } |
+ if (this->IsOtherNumberConstant()) { |
+ return that->IsOtherNumberConstant() && |
+ this->AsOtherNumberConstant()->Value() == |
+ that->AsOtherNumberConstant()->Value(); |
+ } |
+ if (this->IsRange()) { |
+ if (that->IsHeapConstant() || that->IsOtherNumberConstant()) return false; |
} |
if (this->IsTuple()) { |
if (!that->IsTuple()) return false; |
@@ -446,9 +473,7 @@ bool Type::SlowIs(Type* that) { |
} |
if (that->IsRange()) { |
- return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || |
- (this->IsConstant() && |
- Contains(that->AsRange(), this->AsConstant())); |
+ return (this->IsRange() && Contains(that->AsRange(), this->AsRange())); |
} |
if (this->IsRange()) return false; |
@@ -481,9 +506,6 @@ bool Type::Maybe(Type* that) { |
if (this->IsBitset() && that->IsBitset()) return true; |
if (this->IsRange()) { |
- if (that->IsConstant()) { |
- return Contains(this->AsRange(), that->AsConstant()); |
- } |
if (that->IsRange()) { |
return Overlap(this->AsRange(), that->AsRange()); |
} |
@@ -673,9 +695,6 @@ int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size, |
} |
return size; |
} |
- if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) { |
- return AddToUnion(rhs, result, size, zone); |
- } |
if (rhs->IsRange()) { |
RangeType::Limits lim = RangeType::Limits::Intersect( |
RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange())); |
@@ -743,6 +762,29 @@ Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { |
return RangeType::New(range_min, range_max, zone); |
} |
+Type* Type::NewConstant(double value, Zone* zone) { |
+ if (IsInteger(value)) { |
+ return Range(value, value, zone); |
+ } else if (i::IsMinusZero(value)) { |
+ return Type::MinusZero(); |
+ } else if (std::isnan(value)) { |
+ return Type::NaN(); |
+ } |
+ |
+ DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value)); |
+ return OtherNumberConstant(value, zone); |
+} |
+ |
+Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) { |
+ if (IsInteger(*value)) { |
+ double v = value->Number(); |
+ return Range(v, v, zone); |
+ } else if (value->IsHeapNumber()) { |
+ return NewConstant(value->Number(), zone); |
+ } |
+ return HeapConstant(value, zone); |
+} |
+ |
Type* Type::Union(Type* type1, Type* type2, Zone* zone) { |
// Fast case: bit sets. |
if (type1->IsBitset() && type2->IsBitset()) { |
@@ -833,17 +875,14 @@ Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) { |
return union_type; |
} |
-// ----------------------------------------------------------------------------- |
-// Iteration. |
- |
int Type::NumConstants() { |
DisallowHeapAllocation no_allocation; |
- if (this->IsConstant()) { |
+ if (this->IsHeapConstant() || this->IsOtherNumberConstant()) { |
return 1; |
} else if (this->IsUnion()) { |
int result = 0; |
for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
- if (this->AsUnion()->Get(i)->IsConstant()) ++result; |
+ if (this->AsUnion()->Get(i)->IsHeapConstant()) ++result; |
} |
return result; |
} else { |
@@ -905,8 +944,11 @@ void Type::PrintTo(std::ostream& os) { |
DisallowHeapAllocation no_allocation; |
if (this->IsBitset()) { |
BitsetType::Print(os, this->AsBitset()); |
- } else if (this->IsConstant()) { |
- os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; |
+ } else if (this->IsHeapConstant()) { |
+ os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")"; |
+ } else if (this->IsOtherNumberConstant()) { |
+ os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value() |
+ << ")"; |
} else if (this->IsRange()) { |
std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); |
std::streamsize saved_precision = os.precision(0); |