Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(935)

Unified Diff: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart

Issue 61163005: Fix a bug in the type inferrer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart (revision 30389)
+++ sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart (working copy)
@@ -390,6 +390,7 @@
<CallSiteTypeInformation>[];
final WorkQueue workQueue = new WorkQueue();
final Element mainElement;
+ final Set<Element> analyzedElements = new Set<Element>();
/// The maximum number of times we allow a node in the graph to
/// change types. If a node reaches that limit, we give up
@@ -397,13 +398,13 @@
final int MAX_CHANGE_COUNT = 5;
int overallRefineCount = 0;
+ int addedInGraph = 0;
TypeGraphInferrerEngine(Compiler compiler, this.mainElement)
: super(compiler, new TypeInformationSystem(compiler));
void runOverAllElements() {
if (compiler.disableTypeInference) return;
- int addedInGraph = 0;
compiler.progress.reset();
sortResolvedElements().forEach((Element element) {
@@ -414,48 +415,7 @@
// Force the creation of the [ElementTypeInformation] to ensure it is
// in the graph.
types.getInferredTypeOf(element);
-
- SimpleTypeInferrerVisitor visitor =
- new SimpleTypeInferrerVisitor(element, compiler, this);
- TypeInformation type;
- compiler.withCurrentElement(element, () {
- type = visitor.run();
- });
- addedInGraph++;
-
- if (element.isField()) {
- Node node = element.parseNode(compiler);
- if (element.modifiers.isFinal() || element.modifiers.isConst()) {
- // If [element] is final and has an initializer, we record
- // the inferred type.
- if (node.asSendSet() != null) {
- recordType(element, type);
- } else if (!element.isInstanceMember()) {
- recordType(element, types.nullType);
- }
- } else if (node.asSendSet() == null) {
- // Only update types of static fields if there is no
- // assignment. Instance fields are dealt with in the constructor.
- if (Elements.isStaticOrTopLevelField(element)) {
- recordTypeOfNonFinalField(node, element, type);
- }
- } else {
- recordTypeOfNonFinalField(node, element, type);
- }
- if (Elements.isStaticOrTopLevelField(element)
- && node.asSendSet() != null
- && !element.modifiers.isConst()) {
- var argument = node.asSendSet().arguments.head;
- // TODO(13429): We could do better here by using the
- // constant handler to figure out if it's a lazy field or not.
- if (argument.asSend() != null
- || (argument.asNewExpression() != null && !argument.isConst())) {
- recordType(element, types.nullType);
- }
- }
- } else {
- recordReturnType(element, type);
- }
+ analyze(element);
});
compiler.log('Added $addedInGraph elements in inferencing graph.');
@@ -503,6 +463,54 @@
processLoopInformation();
}
+ void analyze(Element element) {
+ element = element.implementation;
+ if (analyzedElements.contains(element)) return;
+ analyzedElements.add(element);
+
+ SimpleTypeInferrerVisitor visitor =
+ new SimpleTypeInferrerVisitor(element, compiler, this);
+ TypeInformation type;
+ compiler.withCurrentElement(element, () {
+ type = visitor.run();
+ });
+ addedInGraph++;
+
+ if (element.isField()) {
+ Node node = element.parseNode(compiler);
+ if (element.modifiers.isFinal() || element.modifiers.isConst()) {
+ // If [element] is final and has an initializer, we record
+ // the inferred type.
+ if (node.asSendSet() != null) {
+ recordType(element, type);
+ } else if (!element.isInstanceMember()) {
+ recordType(element, types.nullType);
+ }
+ } else if (node.asSendSet() == null) {
+ // Only update types of static fields if there is no
+ // assignment. Instance fields are dealt with in the constructor.
+ if (Elements.isStaticOrTopLevelField(element)) {
+ recordTypeOfNonFinalField(node, element, type);
+ }
+ } else {
+ recordTypeOfNonFinalField(node, element, type);
+ }
+ if (Elements.isStaticOrTopLevelField(element)
+ && node.asSendSet() != null
+ && !element.modifiers.isConst()) {
+ var argument = node.asSendSet().arguments.head;
+ // TODO(13429): We could do better here by using the
+ // constant handler to figure out if it's a lazy field or not.
+ if (argument.asSend() != null
+ || (argument.asNewExpression() != null && !argument.isConst())) {
+ recordType(element, types.nullType);
+ }
+ }
+ } else {
+ recordReturnType(element, type);
+ }
+ }
+
void processLoopInformation() {
allocatedCalls.forEach((info) {
if (!info.inLoop) return;
@@ -790,6 +798,8 @@
types.typeInformations.values.forEach((info) => info.clear());
types.allocatedTypes.clear();
types.concreteTypes.clear();
+ analyzedElements.clear();
+ generativeConstructorsExposingThis.clear();
}
Iterable<Element> getCallersOf(Element element) {

Powered by Google App Engine
This is Rietveld 408576698