boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone);
undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
- negative_signed32 = Type::Union(
- Type::SignedSmall(), Type::OtherSigned32(), zone);
- non_negative_signed32 = Type::Union(
- Type::UnsignedSmall(), Type::OtherUnsigned31(), zone);
singleton_false = Type::Constant(f->false_value(), zone);
singleton_true = Type::Constant(f->true_value(), zone);
singleton_zero = Type::Range(zero, zero, zone);
number_fun2_ = Type::Function(number, number, number, zone);
weakint_fun1_ = Type::Function(weakint, number, zone);
- random_fun_ = Type::Function(Type::Union(
- Type::UnsignedSmall(), Type::OtherNumber(), zone), zone);
+ random_fun_ = Type::Function(Type::OrderedNumber(), zone);
const int limits_count = 20;
double rmax = rhs->Max();
if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
// Xor-ing negative or non-negative values results in a non-negative value.
- return t->non_negative_signed32;
+ return Type::NonNegativeSigned32();
}
if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
// Xor-ing a negative and a non-negative value results in a negative value.
- return t->negative_signed32;
+ // TODO(jarin) Use a range here.
+ return Type::NegativeSigned32();
}
return Type::Signed32();
}
if (i::IsMinusZero(value)) return kMinusZero;
if (std::isnan(value)) return kNaN;
if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
- return kOtherNumber;
+ return kPlainNumber;
}
// Minimum values of regular numeric bitsets when SmiValuesAre31Bits.
-template<class Config>
+template <class Config>
const typename TypeImpl<Config>::BitsetType::BitsetMin
-TypeImpl<Config>::BitsetType::BitsetMins31[] = {
- {kOtherNumber, -V8_INFINITY},
- {kOtherSigned32, kMinInt},
- {kOtherSignedSmall, -0x40000000},
- {kUnsignedSmall, 0},
- {kOtherUnsigned31, 0x40000000},
- {kOtherUnsigned32, 0x80000000},
- {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
-};
+ TypeImpl<Config>::BitsetType::BitsetMins31[] = {
+ {kOtherNumber, -V8_INFINITY},
+ {kOtherSigned32, kMinInt},
+ {kNegativeSignedSmall, -0x40000000},
+ {kUnsignedSmall, 0},
+ {kOtherUnsigned31, 0x40000000},
+ {kOtherUnsigned32, 0x80000000},
+ {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}};
// Minimum values of regular numeric bitsets when SmiValuesAre32Bits.
// OtherSigned32 and OtherUnsigned31 are empty (see the diagrams in types.h).
-template<class Config>
+template <class Config>
const typename TypeImpl<Config>::BitsetType::BitsetMin
-TypeImpl<Config>::BitsetType::BitsetMins32[] = {
- {kOtherNumber, -V8_INFINITY},
- {kOtherSignedSmall, kMinInt},
- {kUnsignedSmall, 0},
- {kOtherUnsigned32, 0x80000000},
- {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
-};
+ TypeImpl<Config>::BitsetType::BitsetMins32[] = {
+ {kOtherNumber, -V8_INFINITY},
+ {kNegativeSignedSmall, kMinInt},
+ {kUnsignedSmall, 0},
+ {kOtherUnsigned32, 0x80000000},
+ {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}};
template<class Config>
int lub = kNone;
const BitsetMin* mins = BitsetMins();
+ // Make sure the min-max range touches 0, so we are guaranteed no holes
+ // in unions of valid bitsets.
+ if (max < -1) max = -1;
+ if (min > 0) min = 0;
+
for (size_t i = 1; i < BitsetMinsSize(); ++i) {
if (min < mins[i].min) {
lub |= mins[i-1].bits;
#undef BITSET_CONSTANT
#define BITSET_CONSTANT(type, value) SEMANTIC(k##type),
+ INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
#undef BITSET_CONSTANT
};
V(Untagged, kUntaggedNumber | kUntaggedPointer) \
V(Tagged, kTaggedSigned | kTaggedPointer)
+#define INTERNAL_BITSET_TYPE_LIST(V) \
+ V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
+
#define SEMANTIC_BITSET_TYPE_LIST(V) \
- V(Null, 1u << 1 | REPRESENTATION(kTaggedPointer)) \
- V(Undefined, 1u << 2 | REPRESENTATION(kTaggedPointer)) \
- V(Boolean, 1u << 3 | REPRESENTATION(kTaggedPointer)) \
- V(UnsignedSmall, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(OtherSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(OtherUnsigned31, 1u << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(OtherUnsigned32, 1u << 7 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(OtherSigned32, 1u << 8 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(MinusZero, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(NaN, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
- V(OtherNumber, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(NegativeSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \
+ V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \
+ V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \
+ V(UnsignedSmall, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
\
- V(SignedSmall, kUnsignedSmall | kOtherSignedSmall) \
+ V(SignedSmall, kUnsignedSmall | kNegativeSignedSmall) \
V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
+ V(NegativeSigned32, kNegativeSignedSmall | kOtherSigned32) \
+ V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \
V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \
V(Integral32, kSigned32 | kUnsigned32) \
- V(OrderedNumber, kIntegral32 | kMinusZero | kOtherNumber) \
+ V(PlainNumber, kIntegral32 | kOtherNumber) \
+ V(OrderedNumber, kPlainNumber | kMinusZero) \
V(Number, kOrderedNumber | kNaN) \
V(String, kInternalizedString | kOtherString) \
V(UniqueName, kSymbol | kInternalizedString) \
V(NonNumber, kUnique | kString | kInternal) \
V(Any, 0xfffffffeu)
+
/*
* The following diagrams show how integers (in the mathematical sense) are
* divided among the different atomic numerical types.
REPRESENTATION_BITSET_TYPE_LIST(V) \
SEMANTIC_BITSET_TYPE_LIST(V)
-#define BITSET_TYPE_LIST(V) \
- MASK_BITSET_TYPE_LIST(V) \
- PROPER_BITSET_TYPE_LIST(V)
+#define BITSET_TYPE_LIST(V) \
+ MASK_BITSET_TYPE_LIST(V) \
+ REPRESENTATION_BITSET_TYPE_LIST(V) \
+ INTERNAL_BITSET_TYPE_LIST(V) \
+ SEMANTIC_BITSET_TYPE_LIST(V)
// -----------------------------------------------------------------------------
static TypeImpl* New(bitset bits) {
DCHECK(bits == kNone || IsInhabited(bits));
+
+ if (FLAG_enable_slow_asserts) {
+ // Check that the bitset does not contain any holes in number ranges.
+ bitset mask = kSemantic;
+ if (!i::SmiValuesAre31Bits()) {
+ mask &= ~(kOtherUnsigned31 | kOtherSigned32);
+ }
+ bitset number_bits = bits & kPlainNumber & mask;
+ if (number_bits != 0) {
+ bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask;
+ CHECK(lub == number_bits);
+ }
+ }
+
return Config::from_bitset(bits);
}
static TypeHandle New(bitset bits, Region* region) {
static Type* kInt32Types[] = {
- Type::UnsignedSmall(), Type::OtherSignedSmall(), Type::OtherUnsigned31(),
- Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
- Type::Signed32(), Type::Unsigned32(), Type::Integral32()};
+ Type::UnsignedSmall(), Type::NegativeSigned32(),
+ Type::NonNegativeSigned32(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(),
+ Type::Integral32()};
static Type* kNumberTypes[] = {
- Type::UnsignedSmall(), Type::OtherSignedSmall(), Type::OtherUnsigned31(),
- Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
- Type::Signed32(), Type::Unsigned32(), Type::Integral32(),
- Type::MinusZero(), Type::NaN(), Type::OtherNumber(),
- Type::OrderedNumber(), Type::Number()};
+ Type::UnsignedSmall(), Type::NegativeSigned32(),
+ Type::NonNegativeSigned32(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(),
+ Type::Integral32(), Type::MinusZero(),
+ Type::NaN(), Type::OrderedNumber(),
+ Type::PlainNumber(), Type::Number()};
static Type* kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
TEST(Int32BitwiseShifts) {
JSBitwiseShiftTypedLoweringTester R;
- Type* types[] = {
- Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(),
- Type::Unsigned32(), Type::Signed32(), Type::MinusZero(),
- Type::NaN(), Type::OtherNumber(), Type::Undefined(),
- Type::Null(), Type::Boolean(), Type::Number(),
- Type::String()};
+ Type* types[] = {Type::SignedSmall(), Type::UnsignedSmall(),
+ Type::NegativeSigned32(), Type::NonNegativeSigned32(),
+ Type::Unsigned32(), Type::Signed32(),
+ Type::MinusZero(), Type::NaN(),
+ Type::Undefined(), Type::Null(),
+ Type::Boolean(), Type::Number(),
+ Type::PlainNumber(), Type::String()};
for (size_t i = 0; i < arraysize(types); ++i) {
Node* p0 = R.Parameter(types[i], 0);
JSBitwiseTypedLoweringTester R;
Type* types[] = {
- Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(),
- Type::Signed32(), Type::MinusZero(), Type::NaN(),
- Type::OtherNumber(), Type::Undefined(), Type::Null(),
- Type::Boolean(), Type::Number(), Type::String()};
+ Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(),
+ Type::Signed32(), Type::MinusZero(), Type::NaN(),
+ Type::OrderedNumber(), Type::PlainNumber(), Type::Undefined(),
+ Type::Null(), Type::Boolean(), Type::Number(),
+ Type::String()};
for (size_t i = 0; i < arraysize(types); ++i) {
Node* p0 = R.Parameter(types[i], 0);
CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
- CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
- CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
- CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-1))->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.NegativeSignedSmall));
if (SmiValuesAre31Bits()) {
- CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
- CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
- CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
- CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
- CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
+ CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32));
+ CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32));
+ CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32));
+ CHECK(
+ !T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32));
+ CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))
+ ->Is(T.NegativeSignedSmall));
} else {
CHECK(SmiValuesAre32Bits());
CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
- CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
- CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
- CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
- CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
- CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
- CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
- CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
- CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
- }
- CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
- CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
- CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
- CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
- CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
- CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
- CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32));
+ CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32));
+ CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))
+ ->Is(T.NegativeSignedSmall));
+ CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32));
+ CHECK(
+ T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.NegativeSigned32));
+ }
+ CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32));
+ CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.NonNegativeSigned32));
+ CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32));
+ CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.NonNegativeSigned32));
+ CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32));
+ CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32));
+ CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32));
+ CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32));
+ CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32));
CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
- CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
- CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
+ CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32));
+ CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber));
+ CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32));
}
void Range() {
if (type->IsRange()) {
TypeHandle lub = Rep::BitsetType::New(
Rep::BitsetType::Lub(type), T.region());
- CHECK(lub->Is(T.Union(T.Integral32, T.OtherNumber)));
+ CHECK(lub->Is(T.PlainNumber));
}
}
Types(Region* region, Isolate* isolate)
: region_(region), rng_(isolate->random_number_generator()) {
#define DECLARE_TYPE(name, value) \
- name = Type::name(region); \
- if (SmiValuesAre31Bits() || \
- (!Type::name(region)->Equals(Type::OtherSigned32()) && \
- !Type::name(region)->Equals(Type::OtherUnsigned31()))) { \
- /* Hack: Avoid generating those empty bitset types. */ \
- types.push_back(name); \
- }
+ name = Type::name(region); \
+ types.push_back(name);
PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
Handle<i::Oddball> uninitialized;
#define DECLARE_TYPE(name, value) TypeHandle name;
- BITSET_TYPE_LIST(DECLARE_TYPE)
+ PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
TypeHandle ObjectClass;
int j = rng_->NextInt(n);
#define PICK_BITSET_TYPE(type, value) \
if (j-- == 0) { \
- if (!SmiValuesAre31Bits() && \
- (Type::type(region_)->Equals(Type::OtherSigned32()) || \
- Type::type(region_)->Equals(Type::OtherUnsigned31()))) { \
- /* Hack: Avoid generating those empty bitset types. */ \
- continue; \
- } \
TypeHandle tmp = Type::Intersect( \
result, Type::type(region_), region_); \
if (tmp->Is(Type::None()) && i != 0) { \
// TODO(mstarzinger): Find a common place and unify with test-js-typed-lowering.
Type* const kNumberTypes[] = {
- Type::UnsignedSmall(), Type::OtherSignedSmall(), Type::OtherUnsigned31(),
- Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
- Type::Signed32(), Type::Unsigned32(), Type::Integral32(),
- Type::MinusZero(), Type::NaN(), Type::OtherNumber(),
- Type::OrderedNumber(), Type::Number()};
+ Type::UnsignedSmall(), Type::NegativeSigned32(),
+ Type::NonNegativeSigned32(), Type::SignedSmall(),
+ Type::Signed32(), Type::Unsigned32(),
+ Type::Integral32(), Type::MinusZero(),
+ Type::NaN(), Type::OrderedNumber(),
+ Type::PlainNumber(), Type::Number()};
} // namespace