Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (revision 31020) |
| +++ sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (working copy) |
| @@ -92,13 +92,13 @@ |
| return type; |
| } |
| - void giveUp(TypeGraphInferrerEngine inferrer) { |
| + void giveUp(TypeGraphInferrerEngine inferrer, {bool clearAssignments: true}) { |
| abandonInferencing = true; |
| type = inferrer.types.dynamicType.type; |
| // Do not remove [this] as a user of nodes in [assignments], |
| // because our tracing analysis could be interested in tracing |
| // this node. |
| - assignments = const <TypeInformation>[]; |
| + if (clearAssignments) assignments = const <TypeInformation>[]; |
| // Do not remove users because our tracing analysis could be |
| // interested in tracing the users of this node. |
| } |
| @@ -209,6 +209,10 @@ |
| class ElementTypeInformation extends TypeInformation { |
| final Element element; |
| + // Marker to disable [handleSpecialCases]. For example, parameters |
| + // of closured that are traced can be inferred. |
|
kasperl
2013/12/11 07:35:35
closured -> closures?
ngeoffray
2013/12/16 11:47:43
Done.
|
| + bool turnSpecialNonSpecial = false; |
|
kasperl
2013/12/11 07:35:35
disableHandleSpecialCases?
ngeoffray
2013/12/16 11:47:43
Done.
|
| + |
| /** |
| * This map contains the callers of [element]. It stores all unique call sites |
| * to enable counting the global number of call sites of [element]. |
| @@ -257,14 +261,16 @@ |
| } |
| TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) { |
| - if (abandonInferencing) { |
| - return type; |
| - } |
| + if (abandonInferencing) return type; |
| + if (turnSpecialNonSpecial) return null; |
| + |
| if (element.isParameter()) { |
| Element enclosing = element.enclosingElement; |
| if (Elements.isLocal(enclosing)) { |
| - // Do not infer types for parameters of closures. |
| - giveUp(inferrer); |
| + // Do not infer types for parameters of closures. We do not |
| + // clear the assignments in case the closure is successfully |
| + // traced. |
| + giveUp(inferrer, clearAssignments: false); |
| return type; |
| } else if (enclosing.isInstanceMember() |
| && (enclosing.name == Compiler.NO_SUCH_METHOD |
| @@ -433,7 +439,8 @@ |
| arguments.forEach((info) => info.addUser(this)); |
| } |
| inferrer.updateParameterAssignments( |
| - this, calledElement, arguments, selector, remove: false, init: true); |
| + this, calledElement, arguments, selector, remove: false, |
| + addToQueue: false); |
| } |
| bool get isSynthesized { |
| @@ -502,7 +509,8 @@ |
| callee.addCall(caller, call); |
| callee.addUser(this); |
| inferrer.updateParameterAssignments( |
| - this, element, arguments, typedSelector, remove: false, init: true); |
| + this, element, arguments, typedSelector, remove: false, |
| + addToQueue: false); |
| } |
| } |
| @@ -626,7 +634,8 @@ |
| callee.addCall(caller, call); |
| callee.addUser(this); |
| inferrer.updateParameterAssignments( |
| - this, element, arguments, typedSelector, remove: false); |
| + this, element, arguments, typedSelector, remove: false, |
| + addToQueue: true); |
| } |
| // If [canReachAll] is true, then we are iterating over all |
| @@ -658,7 +667,8 @@ |
| callee.removeCall(caller, call); |
| callee.removeUser(this); |
| inferrer.updateParameterAssignments( |
| - this, element, arguments, typedSelector, remove: true); |
| + this, element, arguments, typedSelector, remove: true, |
| + addToQueue: true); |
| } |
| }); |
| @@ -675,7 +685,8 @@ |
| inferrer.types.getInferredTypeOf(element); |
| callee.addCall(caller, call); |
| inferrer.updateParameterAssignments( |
| - this, element, arguments, selector, remove: false); |
| + this, element, arguments, selector, remove: false, |
| + addToQueue: true); |
| } |
| } |
| super.giveUp(inferrer); |
| @@ -720,6 +731,7 @@ |
| void addToGraph(TypeGraphInferrerEngine inferrer) { |
| arguments.forEach((info) => info.addUser(this)); |
| + closure.addUser(this); |
| } |
| TypeMask refine(TypeGraphInferrerEngine inferrer) { |
| @@ -975,6 +987,27 @@ |
| } |
| } |
| +class ClosureTypeInformation extends TypeInformation { |
| + final Node node; |
| + final Element element; |
| + |
| + ClosureTypeInformation(this.node, this.element); |
| + |
| + TypeMask refine(TypeGraphInferrerEngine inferrer) { |
| + return inferrer.types.functionType.type; |
| + } |
| + |
| + String toString() => 'Closure $element'; |
| + |
| + accept(TypeInformationVisitor visitor) { |
| + return visitor.visitClosureTypeInformation(this); |
| + } |
| + |
| + bool hasStableType(TypeGraphInferrerEngine inferrer) { |
| + return false; |
| + } |
| +} |
| + |
| abstract class TypeInformationVisitor<T> { |
| T visitNarrowTypeInformation(NarrowTypeInformation info); |
| T visitPhiElementTypeInformation(PhiElementTypeInformation info); |
| @@ -987,4 +1020,5 @@ |
| T visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info); |
| T visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info); |
| T visitElementTypeInformation(ElementTypeInformation info); |
| + T visitClosureTypeInformation(ClosureTypeInformation info); |
| } |