Introduce unsigned representation types

To make space in the type bitset, remove Function, RegExp, and Buffer
types for now, since they aren't really relied upon anyway.

R=bmeurer@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#25776}
This commit is contained in:
rossberg 2014-12-11 05:47:40 -08:00 committed by Commit bot
parent 732c8a0966
commit 7e9ca491a4
7 changed files with 85 additions and 79 deletions

View File

@ -40,21 +40,21 @@ FieldAccess AccessBuilder::ForJSFunctionContext() {
// static
FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() {
return {kTaggedBase, JSArrayBuffer::kBackingStoreOffset, MaybeHandle<Name>(),
Type::UntaggedPtr(), kMachPtr};
Type::UntaggedPointer(), kMachPtr};
}
// static
FieldAccess AccessBuilder::ForExternalArrayPointer() {
return {kTaggedBase, ExternalArray::kExternalPointerOffset,
MaybeHandle<Name>(), Type::UntaggedPtr(), kMachPtr};
MaybeHandle<Name>(), Type::UntaggedPointer(), kMachPtr};
}
// static
FieldAccess AccessBuilder::ForMapInstanceType() {
return {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
Type::UntaggedInt8(), kMachUint8};
Type::UntaggedUnsigned8(), kMachUint8};
}

View File

@ -59,17 +59,18 @@ class LazyTypeCache FINAL : public ZoneObject {
Type* Create(LazyCachedType type) {
switch (type) {
case kInt8:
return CreateNative(CreateRange<int8_t>(), Type::UntaggedInt8());
return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
case kUint8:
return CreateNative(CreateRange<uint8_t>(), Type::UntaggedInt8());
return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
case kInt16:
return CreateNative(CreateRange<int16_t>(), Type::UntaggedInt16());
return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
case kUint16:
return CreateNative(CreateRange<uint16_t>(), Type::UntaggedInt16());
return CreateNative(CreateRange<uint16_t>(),
Type::UntaggedUnsigned16());
case kInt32:
return CreateNative(Type::Signed32(), Type::UntaggedInt32());
return CreateNative(Type::Signed32(), Type::UntaggedSigned32());
case kUint32:
return CreateNative(Type::Unsigned32(), Type::UntaggedInt32());
return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
case kFloat32:
return CreateNative(Type::Number(), Type::UntaggedFloat32());
case kFloat64:
@ -87,7 +88,7 @@ class LazyTypeCache FINAL : public ZoneObject {
case kClz32Func:
return Type::Function(CreateRange(0, 32), Type::Number(), zone());
case kArrayBufferFunc:
return Type::Function(Type::Buffer(zone()), Type::Unsigned32(), zone());
return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
#define NATIVE_TYPE_CASE(Type) \
case k##Type##Array: \
return CreateArray(Get(k##Type)); \
@ -598,11 +599,12 @@ Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
Factory* f = isolate()->factory();
Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
return Bounds(Type::Intersect(
Type::Range(number, number, zone()), Type::UntaggedInt32(), zone()));
Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone()));
}
Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
// TODO(rossberg): This actually seems to be a PointerConstant so far...
return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type?
}
@ -1535,8 +1537,8 @@ Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
return Bounds(
ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
ChangeRepresentation(arg.lower, Type::UntaggedSigned32(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedSigned32(), zone()));
}
@ -1544,8 +1546,8 @@ Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
return Bounds(
ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
ChangeRepresentation(arg.lower, Type::UntaggedUnsigned32(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedUnsigned32(), zone()));
}
@ -1589,8 +1591,8 @@ Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
return Bounds(
ChangeRepresentation(arg.lower, Type::UntaggedInt1(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedInt1(), zone()));
ChangeRepresentation(arg.lower, Type::UntaggedBit(), zone()),
ChangeRepresentation(arg.upper, Type::UntaggedBit(), zone()));
}
@ -1598,8 +1600,8 @@ Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
return Bounds(
ChangeRepresentation(arg.lower, Type::TaggedPtr(), zone()),
ChangeRepresentation(arg.upper, Type::TaggedPtr(), zone()));
ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()),
ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone()));
}
@ -1884,13 +1886,13 @@ Bounds Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) {
Bounds Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) {
return Bounds(Type::Intersect(
Type::Signed32(), Type::UntaggedInt32(), zone()));
Type::Signed32(), Type::UntaggedSigned32(), zone()));
}
Bounds Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
return Bounds(Type::Intersect(
Type::Unsigned32(), Type::UntaggedInt32(), zone()));
Type::Unsigned32(), Type::UntaggedUnsigned32(), zone()));
}
@ -1924,13 +1926,13 @@ Bounds Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
Bounds Typer::Visitor::TypeTruncateFloat64ToInt32(Node* node) {
return Bounds(Type::Intersect(
Type::Signed32(), Type::UntaggedInt32(), zone()));
Type::Signed32(), Type::UntaggedSigned32(), zone()));
}
Bounds Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
return Bounds(Type::Intersect(
Type::Signed32(), Type::UntaggedInt32(), zone()));
Type::Signed32(), Type::UntaggedSigned32(), zone()));
}

View File

@ -289,7 +289,7 @@ void Verifier::Visitor::Pre(Node* node) {
// Constants have no inputs.
CHECK_EQ(0, input_count);
// Type can be anything represented as a heap pointer.
CheckUpperIs(node, Type::TaggedPtr());
CheckUpperIs(node, Type::TaggedPointer());
break;
case IrOpcode::kExternalConstant:
// Constants have no inputs.

View File

@ -153,9 +153,9 @@ TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
}
if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
if (type->IsRange()) return type->AsRange()->BitsetLub();
if (type->IsContext()) return kInternal & kTaggedPtr;
if (type->IsContext()) return kInternal & kTaggedPointer;
if (type->IsArray()) return kArray;
if (type->IsFunction()) return kFunction;
if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction
UNREACHABLE();
return kNone;
}
@ -200,10 +200,10 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
map == heap->no_interceptor_result_sentinel_map() ||
map == heap->termination_exception_map() ||
map == heap->arguments_marker_map());
return kInternal & kTaggedPtr;
return kInternal & kTaggedPointer;
}
case HEAP_NUMBER_TYPE:
return kNumber & kTaggedPtr;
return kNumber & kTaggedPointer;
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_OBJECT_TYPE:
@ -227,9 +227,9 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case JS_ARRAY_TYPE:
return kArray;
case JS_FUNCTION_TYPE:
return kFunction;
return kOtherObject; // TODO(rossberg): there should be a Function type.
case JS_REGEXP_TYPE:
return kRegExp;
return kOtherObject; // TODO(rossberg): there should be a RegExp type.
case JS_PROXY_TYPE:
case JS_FUNCTION_PROXY_TYPE:
return kProxy;
@ -252,7 +252,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case BYTE_ARRAY_TYPE:
case FOREIGN_TYPE:
case CODE_TYPE:
return kInternal & kTaggedPtr;
return kInternal & kTaggedPointer;
default:
UNREACHABLE();
return kNone;
@ -265,7 +265,8 @@ typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
DisallowHeapAllocation no_allocation;
if (value->IsNumber()) {
return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr);
return Lub(value->Number()) &
(value->IsSmi() ? kTaggedSigned : kTaggedPointer);
}
return Lub(i::HeapObject::cast(value)->map());
}

View File

@ -154,35 +154,44 @@ namespace internal {
// Values for bitset types
#define MASK_BITSET_TYPE_LIST(V) \
V(Representation, 0xff800000u) \
V(Semantic, 0x007ffffeu)
V(Representation, 0xfff00000u) \
V(Semantic, 0x000ffffeu)
#define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
#define SEMANTIC(k) ((k) & BitsetType::kSemantic)
#define REPRESENTATION_BITSET_TYPE_LIST(V) \
V(None, 0) \
V(UntaggedInt1, 1u << 23 | kSemantic) \
V(UntaggedInt8, 1u << 24 | kSemantic) \
V(UntaggedInt16, 1u << 25 | kSemantic) \
V(UntaggedInt32, 1u << 26 | kSemantic) \
V(UntaggedFloat32, 1u << 27 | kSemantic) \
V(UntaggedFloat64, 1u << 28 | kSemantic) \
V(UntaggedPtr, 1u << 29 | kSemantic) \
V(TaggedInt, 1u << 30 | kSemantic) \
V(TaggedPtr, 1u << 31 | kSemantic) \
#define REPRESENTATION_BITSET_TYPE_LIST(V) \
V(None, 0) \
V(UntaggedBit, 1u << 20 | kSemantic) \
V(UntaggedSigned8, 1u << 21 | kSemantic) \
V(UntaggedSigned16, 1u << 22 | kSemantic) \
V(UntaggedSigned32, 1u << 23 | kSemantic) \
V(UntaggedUnsigned8, 1u << 24 | kSemantic) \
V(UntaggedUnsigned16, 1u << 25 | kSemantic) \
V(UntaggedUnsigned32, 1u << 26 | kSemantic) \
V(UntaggedFloat32, 1u << 27 | kSemantic) \
V(UntaggedFloat64, 1u << 28 | kSemantic) \
V(UntaggedPointer, 1u << 29 | kSemantic) \
V(TaggedSigned, 1u << 30 | kSemantic) \
V(TaggedPointer, 1u << 31 | kSemantic) \
\
V(UntaggedInt, kUntaggedInt1 | kUntaggedInt8 | \
kUntaggedInt16 | kUntaggedInt32) \
V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
V(UntaggedNumber, kUntaggedInt | kUntaggedFloat) \
V(Untagged, kUntaggedNumber | kUntaggedPtr) \
V(Tagged, kTaggedInt | kTaggedPtr)
V(UntaggedSigned, kUntaggedSigned8 | kUntaggedSigned16 | \
kUntaggedSigned32) \
V(UntaggedUnsigned, kUntaggedUnsigned8 | kUntaggedUnsigned16 | \
kUntaggedUnsigned32) \
V(UntaggedIntegral8, kUntaggedSigned8 | kUntaggedUnsigned8) \
V(UntaggedIntegral16, kUntaggedSigned16 | kUntaggedUnsigned16) \
V(UntaggedIntegral32, kUntaggedSigned32 | kUntaggedUnsigned32) \
V(UntaggedIntegral, kUntaggedBit | kUntaggedSigned | kUntaggedUnsigned) \
V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
V(UntaggedNumber, kUntaggedIntegral | kUntaggedFloat) \
V(Untagged, kUntaggedNumber | kUntaggedPointer) \
V(Tagged, kTaggedSigned | kTaggedPointer)
#define SEMANTIC_BITSET_TYPE_LIST(V) \
V(Null, 1u << 1 | REPRESENTATION(kTaggedPtr)) \
V(Undefined, 1u << 2 | REPRESENTATION(kTaggedPtr)) \
V(Boolean, 1u << 3 | REPRESENTATION(kTaggedPtr)) \
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)) \
@ -191,17 +200,14 @@ namespace internal {
V(MinusZero, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(NaN, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherNumber, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPtr)) \
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPtr)) \
V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPtr)) \
V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPtr)) \
V(Array, 1u << 16 | REPRESENTATION(kTaggedPtr)) \
V(Buffer, 1u << 17 | REPRESENTATION(kTaggedPtr)) \
V(Function, 1u << 18 | REPRESENTATION(kTaggedPtr)) \
V(RegExp, 1u << 19 | REPRESENTATION(kTaggedPtr)) \
V(OtherObject, 1u << 20 | REPRESENTATION(kTaggedPtr)) \
V(Proxy, 1u << 21 | REPRESENTATION(kTaggedPtr)) \
V(Internal, 1u << 22 | REPRESENTATION(kTagged | kUntagged)) \
V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \
V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \
V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \
V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
\
V(SignedSmall, kUnsignedSmall | kOtherSignedSmall) \
V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
@ -215,7 +221,7 @@ namespace internal {
V(NumberOrString, kNumber | kString) \
V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \
V(Primitive, kSymbol | kPlainPrimitive) \
V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
V(DetectableObject, kArray | kOtherObject) \
V(DetectableReceiver, kDetectableObject | kProxy) \
V(Detectable, kDetectableReceiver | kNumber | kName) \
V(Object, kDetectableObject | kUndetectable) \

View File

@ -394,7 +394,8 @@ void AstTyper::VisitLiteral(Literal* expr) {
void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
NarrowType(expr, Bounds(Type::RegExp(zone())));
// TODO(rossberg): Reintroduce RegExp type.
NarrowType(expr, Bounds(Type::Object(zone())));
}

View File

@ -934,10 +934,8 @@ struct Tests : Rep {
CheckSub(T.Object, T.Receiver);
CheckSub(T.Array, T.Object);
CheckSub(T.Function, T.Object);
CheckSub(T.Proxy, T.Receiver);
CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.Array, T.Function);
// Subtyping between concrete structural types
@ -973,7 +971,7 @@ struct Tests : Rep {
CheckSub(T.NumberArray, T.Object);
CheckUnordered(T.StringArray, T.AnyArray);
CheckSub(T.MethodFunction, T.Function);
CheckSub(T.MethodFunction, T.Object);
CheckSub(T.NumberFunction1, T.Object);
CheckUnordered(T.SignedFunction1, T.NumberFunction1);
CheckUnordered(T.NumberFunction1, T.NumberFunction2);
@ -1259,10 +1257,8 @@ struct Tests : Rep {
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.Array, T.Object);
CheckOverlap(T.Function, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
CheckDisjoint(T.Array, T.Function);
// Structural types
CheckOverlap(T.ObjectClass, T.Object);
@ -1286,7 +1282,7 @@ struct Tests : Rep {
CheckOverlap(T.NumberArray, T.Array);
CheckDisjoint(T.NumberArray, T.AnyArray);
CheckDisjoint(T.NumberArray, T.StringArray);
CheckOverlap(T.MethodFunction, T.Function);
CheckOverlap(T.MethodFunction, T.Object);
CheckDisjoint(T.SignedFunction1, T.NumberFunction1);
CheckDisjoint(T.SignedFunction1, T.NumberFunction2);
CheckDisjoint(T.NumberFunction1, T.NumberFunction2);
@ -1456,11 +1452,11 @@ struct Tests : Rep {
CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number);
// Bitset-function
CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object)));
CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object);
CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object);
CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object);
CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number);
@ -1528,7 +1524,7 @@ struct Tests : Rep {
CheckEqual(
T.Union(T.NumberFunction1, T.NumberFunction2),
T.Union(T.NumberFunction2, T.NumberFunction1));
CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object);
// Union-union
CheckEqual(
@ -1689,11 +1685,11 @@ struct Tests : Rep {
// Bitset-array
CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None);
CheckEqual(T.Intersect(T.AnyArray, T.Proxy), T.None);
// Bitset-function
CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
CheckEqual(T.Intersect(T.NumberFunction1, T.Array), T.None);
CheckEqual(T.Intersect(T.NumberFunction1, T.Proxy), T.None);
// Bitset-union
CheckEqual(