mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Add typeinfo for sets and their elements and start tracing them in the inferrer.
Change-Id: Ib9a4e46b77a15ab17396d519166969a221b63da4 Reviewed-on: https://dart-review.googlesource.com/c/92168 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
61ab8e7816
commit
d11dd982dd
3 changed files with 91 additions and 8 deletions
|
@ -81,17 +81,23 @@ abstract class TracerVisitor implements TypeInformationVisitor {
|
||||||
|
|
||||||
TracerVisitor(this.tracedType, this.inferrer);
|
TracerVisitor(this.tracedType, this.inferrer);
|
||||||
|
|
||||||
// Work list that gets populated with [TypeInformation] that could
|
/// Work list that gets populated with [TypeInformation] that could
|
||||||
// contain the container.
|
/// contain the container.
|
||||||
final List<TypeInformation> workList = <TypeInformation>[];
|
final List<TypeInformation> workList = <TypeInformation>[];
|
||||||
|
|
||||||
// Work list of lists to analyze after analyzing the users of a
|
/// Work list of lists to analyze after analyzing the users of a
|
||||||
// [TypeInformation]. We know the [tracedType] has been stored in these
|
/// [TypeInformation]. We know the [tracedType] has been stored in these
|
||||||
// lists and we must check how it escapes from these lists.
|
/// lists and we must check how it escapes from these lists.
|
||||||
final List<ListTypeInformation> listsToAnalyze = <ListTypeInformation>[];
|
final List<ListTypeInformation> listsToAnalyze = <ListTypeInformation>[];
|
||||||
// Work list of maps to analyze after analyzing the users of a
|
|
||||||
// [TypeInformation]. We know the [tracedType] has been stored in these
|
/// Work list of sets to analyze after analyzing the users of a
|
||||||
// maps and we must check how it escapes from these maps.
|
/// [TypeInformation]. We know the [tracedType] has been stored in these sets
|
||||||
|
/// and we must check how it escapes from these sets.
|
||||||
|
final List<SetTypeInformation> setsToAnalyze = <SetTypeInformation>[];
|
||||||
|
|
||||||
|
/// Work list of maps to analyze after analyzing the users of a
|
||||||
|
/// [TypeInformation]. We know the [tracedType] has been stored in these
|
||||||
|
/// maps and we must check how it escapes from these maps.
|
||||||
final List<MapTypeInformation> mapsToAnalyze = <MapTypeInformation>[];
|
final List<MapTypeInformation> mapsToAnalyze = <MapTypeInformation>[];
|
||||||
|
|
||||||
final Setlet<TypeInformation> flowsInto = new Setlet<TypeInformation>();
|
final Setlet<TypeInformation> flowsInto = new Setlet<TypeInformation>();
|
||||||
|
@ -175,6 +181,10 @@ abstract class TracerVisitor implements TypeInformationVisitor {
|
||||||
addNewEscapeInformation(info);
|
addNewEscapeInformation(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitElementInSetTypeInformation(ElementInSetTypeInformation info) {
|
||||||
|
addNewEscapeInformation(info);
|
||||||
|
}
|
||||||
|
|
||||||
void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
|
void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
|
||||||
// We do not track the use of keys from a map, so we have to bail.
|
// We do not track the use of keys from a map, so we have to bail.
|
||||||
bailout('Used as key in Map');
|
bailout('Used as key in Map');
|
||||||
|
@ -188,6 +198,10 @@ abstract class TracerVisitor implements TypeInformationVisitor {
|
||||||
listsToAnalyze.add(info);
|
listsToAnalyze.add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitSetTypeInformation(SetTypeInformation info) {
|
||||||
|
setsToAnalyze.add(info);
|
||||||
|
}
|
||||||
|
|
||||||
void visitMapTypeInformation(MapTypeInformation info) {
|
void visitMapTypeInformation(MapTypeInformation info) {
|
||||||
mapsToAnalyze.add(info);
|
mapsToAnalyze.add(info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,6 +335,10 @@ class _GraphGenerator extends TypeInformationVisitor {
|
||||||
addNode(info, 'ElementInContainer');
|
addNode(info, 'ElementInContainer');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitElementInSetTypeInformation(ElementInSetTypeInformation info) {
|
||||||
|
addNode(info, 'ElementInSet');
|
||||||
|
}
|
||||||
|
|
||||||
void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
|
void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
|
||||||
addNode(info, 'KeyInMap');
|
addNode(info, 'KeyInMap');
|
||||||
}
|
}
|
||||||
|
@ -347,6 +351,10 @@ class _GraphGenerator extends TypeInformationVisitor {
|
||||||
addNode(info, 'List');
|
addNode(info, 'List');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitSetTypeInformation(SetTypeInformation info) {
|
||||||
|
addNode(info, 'Set');
|
||||||
|
}
|
||||||
|
|
||||||
void visitMapTypeInformation(MapTypeInformation info) {
|
void visitMapTypeInformation(MapTypeInformation info) {
|
||||||
addNode(info, 'Map');
|
addNode(info, 'Map');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1580,6 +1580,65 @@ class ElementInContainerTypeInformation extends InferredTypeInformation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [SetTypeInformation] is a [TypeInformation] created for sets.
|
||||||
|
class SetTypeInformation extends TypeInformation with TracedTypeInformation {
|
||||||
|
final ElementInSetTypeInformation elementType;
|
||||||
|
|
||||||
|
final AbstractValue originalType;
|
||||||
|
|
||||||
|
SetTypeInformation(
|
||||||
|
MemberTypeInformation context, this.originalType, this.elementType)
|
||||||
|
: super(originalType, context) {
|
||||||
|
elementType.addUser(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toString() => 'Set type $type';
|
||||||
|
|
||||||
|
accept(TypeInformationVisitor visitor) {
|
||||||
|
return visitor.visitSetTypeInformation(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractValue computeType(InferrerEngine inferrer) {
|
||||||
|
AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
|
||||||
|
AbstractValue mask = type;
|
||||||
|
if (!abstractValueDomain.isSet(type) ||
|
||||||
|
abstractValueDomain.getSetElementType(type) != elementType.type) {
|
||||||
|
return abstractValueDomain.createSetValue(
|
||||||
|
abstractValueDomain.getGeneralization(originalType),
|
||||||
|
abstractValueDomain.getAllocationNode(originalType),
|
||||||
|
abstractValueDomain.getAllocationElement(originalType),
|
||||||
|
elementType.type);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractValue safeType(InferrerEngine inferrer) => originalType;
|
||||||
|
|
||||||
|
bool hasStableType(InferrerEngine inferrer) {
|
||||||
|
return elementType.isStable && super.hasStableType(inferrer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
super.cleanup();
|
||||||
|
elementType.cleanup();
|
||||||
|
_flowsInto = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An [ElementInSetTypeInformation] holds the common type of the elements in a
|
||||||
|
/// [SetTypeInformation].
|
||||||
|
class ElementInSetTypeInformation extends InferredTypeInformation {
|
||||||
|
ElementInSetTypeInformation(AbstractValueDomain abstractValueDomain,
|
||||||
|
MemberTypeInformation context, elementType)
|
||||||
|
: super(abstractValueDomain, context, elementType);
|
||||||
|
|
||||||
|
String toString() => 'Element in set $type';
|
||||||
|
|
||||||
|
accept(TypeInformationVisitor visitor) {
|
||||||
|
return visitor.visitElementInSetTypeInformation(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A [MapTypeInformation] is a [TypeInformation] created
|
/// A [MapTypeInformation] is a [TypeInformation] created
|
||||||
/// for maps.
|
/// for maps.
|
||||||
class MapTypeInformation extends TypeInformation with TracedTypeInformation {
|
class MapTypeInformation extends TypeInformation with TracedTypeInformation {
|
||||||
|
@ -1920,9 +1979,11 @@ abstract class TypeInformationVisitor<T> {
|
||||||
T visitPhiElementTypeInformation(PhiElementTypeInformation info);
|
T visitPhiElementTypeInformation(PhiElementTypeInformation info);
|
||||||
T visitElementInContainerTypeInformation(
|
T visitElementInContainerTypeInformation(
|
||||||
ElementInContainerTypeInformation info);
|
ElementInContainerTypeInformation info);
|
||||||
|
T visitElementInSetTypeInformation(ElementInSetTypeInformation info);
|
||||||
T visitKeyInMapTypeInformation(KeyInMapTypeInformation info);
|
T visitKeyInMapTypeInformation(KeyInMapTypeInformation info);
|
||||||
T visitValueInMapTypeInformation(ValueInMapTypeInformation info);
|
T visitValueInMapTypeInformation(ValueInMapTypeInformation info);
|
||||||
T visitListTypeInformation(ListTypeInformation info);
|
T visitListTypeInformation(ListTypeInformation info);
|
||||||
|
T visitSetTypeInformation(SetTypeInformation info);
|
||||||
T visitMapTypeInformation(MapTypeInformation info);
|
T visitMapTypeInformation(MapTypeInformation info);
|
||||||
T visitConcreteTypeInformation(ConcreteTypeInformation info);
|
T visitConcreteTypeInformation(ConcreteTypeInformation info);
|
||||||
T visitStringLiteralTypeInformation(StringLiteralTypeInformation info);
|
T visitStringLiteralTypeInformation(StringLiteralTypeInformation info);
|
||||||
|
|
Loading…
Reference in a new issue