| 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);
|
|
|