Split TypeSystem.typeInformations into member/parameter info

R=sigmund@google.com

Review-Url: https://codereview.chromium.org/2967003002 .
This commit is contained in:
Johnni Winther 2017-07-06 10:43:37 +02:00
parent 09c5828204
commit 4c172a3dd9
5 changed files with 87 additions and 82 deletions

View file

@ -621,7 +621,7 @@ class InferrerEngine {
}
void buildWorkQueue() {
workQueue.addAll(types.typeInformations.values);
workQueue.addAll(types.orderedTypeInformations);
workQueue.addAll(types.allocatedTypes);
workQueue.addAll(types.allocatedClosures);
workQueue.addAll(types.allocatedCalls);
@ -1037,7 +1037,8 @@ class InferrerEngine {
defaultTypeOfParameter.clear();
types.typeInformations.values.forEach(cleanup);
types.parameterTypeInformations.values.forEach(cleanup);
types.memberTypeInformations.values.forEach(cleanup);
types.allocatedTypes.forEach(cleanup);
types.allocatedTypes.clear();

View file

@ -151,13 +151,6 @@ class TypeGraphInferrer implements TypesInferrer {
return info.isCalledOnce();
}
bool isParameterCalledOnce(ParameterElement element) {
if (compiler.disableTypeInference) return false;
MemberTypeInformation info =
inferrer.types.getInferredTypeOfParameter(element);
return info.isCalledOnce();
}
void clear() {
inferrer.clear();
}

View file

@ -348,23 +348,10 @@ abstract class ElementTypeInformation extends TypeInformation {
/// Marker to disable inference for closures in [handleSpecialCases].
bool disableInferenceForClosures = true;
factory ElementTypeInformation(Element element, TypeSystem types) {
if (element.isParameter) {
ParameterElement parameter = element;
if (parameter.functionDeclaration.isLocal) {
return new ParameterTypeInformation._localFunction(element, types);
} else if (parameter.functionDeclaration.isInstanceMember) {
return new ParameterTypeInformation._instanceMember(element, types);
}
return new ParameterTypeInformation._static(element, types);
}
return new MemberTypeInformation(element);
}
ElementTypeInformation._internal(MemberTypeInformation context, this._element)
: super(context);
ElementTypeInformation._withAssignments(
MemberTypeInformation context, this._element, assignments)
ElementTypeInformation._withAssignments(MemberTypeInformation context,
this._element, ParameterAssignments assignments)
: super.withAssignments(context, assignments);
String getInferredSignature(TypeSystem types);
@ -602,40 +589,22 @@ class ParameterTypeInformation extends ElementTypeInformation {
final FunctionElement _declaration;
final MethodElement _method;
ParameterTypeInformation._internal(MemberTypeInformation context,
ParameterTypeInformation.localFunction(MemberTypeInformation context,
ParameterElement parameter, this._declaration, this._method)
: super._internal(context, parameter);
factory ParameterTypeInformation._static(
ParameterElement element, TypeSystem types) {
MethodElement method = element.functionDeclaration;
assert(!method.isInstanceMember);
return new ParameterTypeInformation._internal(
types.getInferredTypeOfMember(method), element, method, method);
}
ParameterTypeInformation.static(
MemberTypeInformation context, ParameterElement parameter, this._method)
: this._declaration = _method,
super._internal(context, parameter);
factory ParameterTypeInformation._localFunction(
ParameterElement element, TypeSystem types) {
LocalFunctionElement localFunction = element.functionDeclaration;
MethodElement callMethod = localFunction.callMethod;
return new ParameterTypeInformation._internal(
types.getInferredTypeOfMember(callMethod),
element,
localFunction,
callMethod);
}
ParameterTypeInformation._instanceMember(
ParameterElement element, TypeSystem types)
: _declaration = element.functionDeclaration,
_method = element.functionDeclaration,
super._withAssignments(
types.getInferredTypeOfMember(
element.functionDeclaration as MethodElement),
element,
new ParameterAssignments()) {
assert(element.functionDeclaration.isInstanceMember);
}
ParameterTypeInformation.instanceMember(
MemberTypeInformation context,
ParameterElement parameter,
this._method,
ParameterAssignments assignments)
: this._declaration = _method,
super._withAssignments(context, parameter, assignments);
MethodElement get method => _method;

View file

@ -19,9 +19,17 @@ import 'type_graph_nodes.dart';
class TypeSystem {
final ClosedWorld closedWorld;
/// [ElementTypeInformation]s for elements.
final Map<Element, TypeInformation> typeInformations =
new Map<Element, TypeInformation>();
/// [parameterTypeInformations] and [memberTypeInformations] ordered by
/// creation time. This is used as the inference enqueueing order.
final List<TypeInformation> _orderedTypeInformations = <TypeInformation>[];
/// [ParameterTypeInformation]s for parameters.
final Map<ParameterElement, TypeInformation> parameterTypeInformations =
new Map<ParameterElement, TypeInformation>();
/// [MemberTypeInformation]s for members.
final Map<MemberElement, TypeInformation> memberTypeInformations =
new Map<MemberElement, TypeInformation>();
/// [ListTypeInformation] for allocated lists.
final Map<ast.Node, TypeInformation> allocatedLists =
@ -46,8 +54,14 @@ class TypeSystem {
/// phis, and containers).
final List<TypeInformation> allocatedTypes = <TypeInformation>[];
/// [parameterTypeInformations] and [memberTypeInformations] ordered by
/// creation time. This is used as the inference enqueueing order.
Iterable<TypeInformation> get orderedTypeInformations =>
_orderedTypeInformations;
Iterable<TypeInformation> get allTypes => [
typeInformations.values,
parameterTypeInformations.values,
memberTypeInformations.values,
allocatedLists.values,
allocatedMaps.values,
allocatedClosures,
@ -322,20 +336,47 @@ class TypeSystem {
return newType;
}
ElementTypeInformation getInferredTypeOfParameter(ParameterElement element) {
return _getInferredTypeOf(element);
ParameterTypeInformation getInferredTypeOfParameter(
ParameterElement parameter) {
parameter = parameter.implementation;
ParameterTypeInformation createTypeInformation() {
if (parameter.functionDeclaration.isLocal) {
LocalFunctionElement localFunction = parameter.functionDeclaration;
MethodElement callMethod = localFunction.callMethod;
return new ParameterTypeInformation.localFunction(
getInferredTypeOfMember(callMethod),
parameter,
localFunction,
callMethod);
} else if (parameter.functionDeclaration.isInstanceMember) {
MethodElement method = parameter.functionDeclaration;
return new ParameterTypeInformation.instanceMember(
getInferredTypeOfMember(method),
parameter,
method,
new ParameterAssignments());
} else {
MethodElement method = parameter.functionDeclaration;
return new ParameterTypeInformation.static(
getInferredTypeOfMember(method), parameter, method);
}
}
return parameterTypeInformations.putIfAbsent(parameter, () {
ParameterTypeInformation typeInformation = createTypeInformation();
_orderedTypeInformations.add(typeInformation);
return typeInformation;
});
}
ElementTypeInformation getInferredTypeOfMember(MemberElement element) {
return _getInferredTypeOf(element);
}
@deprecated
ElementTypeInformation _getInferredTypeOf(Element element) {
element = element.implementation;
assert(element.isParameter || element is MemberElement);
return typeInformations[element] ??=
new ElementTypeInformation(element, this);
MemberTypeInformation getInferredTypeOfMember(MemberElement member) {
member = member.implementation;
return memberTypeInformations.putIfAbsent(member, () {
MemberTypeInformation typeInformation = new MemberTypeInformation(member);
_orderedTypeInformations.add(typeInformation);
return typeInformation;
});
}
/**

View file

@ -33,10 +33,6 @@ abstract class GlobalTypeInferenceElementResult {
/// Whether the method element associated with this result always throws.
bool get throwsAlways;
/// Whether the element associated with this result is only called once in one
/// location in the entire program.
bool get isCalledOnce;
/// The inferred type when this result belongs to a parameter or field
/// element, null otherwise.
TypeMask get type;
@ -71,6 +67,13 @@ abstract class GlobalTypeInferenceElementResult {
TypeMask typeOfIteratorCurrent(ForIn node);
}
abstract class GlobalTypeInferenceMemberResult
extends GlobalTypeInferenceElementResult {
/// Whether the member associated with this result is only called once in one
/// location in the entire program.
bool get isCalledOnce;
}
abstract class GlobalTypeInferenceElementResultImpl
implements GlobalTypeInferenceElementResult {
// TODO(sigmund): delete, store data directly here.
@ -108,9 +111,10 @@ abstract class GlobalTypeInferenceElementResultImpl
_data?.typeOfIteratorCurrent(node);
}
class GlobalTypeInferenceMemberResult
extends GlobalTypeInferenceElementResultImpl {
GlobalTypeInferenceMemberResult(
class GlobalTypeInferenceMemberResultImpl
extends GlobalTypeInferenceElementResultImpl
implements GlobalTypeInferenceMemberResult {
GlobalTypeInferenceMemberResultImpl(
MemberElement owner,
GlobalTypeInferenceElementData data,
TypesInferrer inferrer,
@ -133,8 +137,6 @@ class GlobalTypeInferenceParameterResult
ParameterElement owner, TypesInferrer inferrer, TypeMask _dynamic)
: super.internal(owner, null, inferrer, false, _dynamic);
bool get isCalledOnce => _inferrer.isParameterCalledOnce(_owner);
TypeMask get returnType =>
_isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner);
@ -205,7 +207,6 @@ abstract class TypesInferrer {
TypeMask getTypeOfSelector(Selector selector, TypeMask mask);
void clear();
bool isMemberCalledOnce(MemberElement element);
bool isParameterCalledOnce(ParameterElement element);
bool isFixedArrayCheckedForGrowable(Node node);
}
@ -227,7 +228,7 @@ class GlobalTypeInferenceResults {
// TODO(sigmund,johnniwinther): compute result objects eagerly and make it an
// error to query for results that don't exist.
GlobalTypeInferenceElementResult resultOfMember(MemberElement member) {
GlobalTypeInferenceMemberResult resultOfMember(MemberElement member) {
assert(
!member.isGenerativeConstructorBody,
failedAt(
@ -238,7 +239,7 @@ class GlobalTypeInferenceResults {
bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member);
return _memberResults.putIfAbsent(
member,
() => new GlobalTypeInferenceMemberResult(
() => new GlobalTypeInferenceMemberResultImpl(
member,
// We store data in the context of the enclosing method, even
// for closure elements.