Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| index 2c45b4a7cfb26310f3db12553878459ff31f7d63..b6cb9391c764f1f7afbd3827076f15bcbc5ea6ea 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| @@ -28,9 +28,13 @@ abstract class TypeInformation { |
| /// Initially empty. |
| TypeMask type = const TypeMask.nonNullEmpty(); |
| - /// We give up on inferencing for special elements, as well as for |
| - /// complicated cyclic dependencies. |
| + /// We abandon inference in certain cases (complex cyclic flow, native |
| + /// behaviours, etc.). In some case, we might resume inference in the |
| + /// closure tracer, which is handled by checking whether [assignments] has |
| + /// been set to [STOP_TRACKING_ASSIGNMENTS_MARKER]. |
| bool abandonInferencing = false; |
| + bool get mightResume => |
| + !identical(assignments, STOP_TRACKING_ASSIGNMENTS_MARKER); |
| /// Number of times this [TypeInformation] has changed type. |
| int refineCount = 0; |
| @@ -66,7 +70,10 @@ abstract class TypeInformation { |
| users.remove(user); |
| } |
| - static final STOP_TRACKING_ASSIGNMENTS_MARKER = const <TypeInformation>[]; |
| + // The below is not a compile time constant to make it differentiable |
| + // from other empty lists of [TypeInformation]. |
| + static final STOP_TRACKING_ASSIGNMENTS_MARKER = |
| + new List<TypeInformation>.from([], growable: false); |
|
floitsch
2014/04/14 15:39:37
new List<TypeInformation>(0);
herhut
2014/04/15 10:50:39
Done.
|
| bool areAssignmentsTracked() { |
| return assignments != STOP_TRACKING_ASSIGNMENTS_MARKER; |
| @@ -104,7 +111,7 @@ abstract class TypeInformation { |
| // Do not remove [this] as a user of nodes in [assignments], |
| // because our tracing analysis could be interested in tracing |
| // this node. |
| - if (clearAssignments) assignments = const <TypeInformation>[]; |
| + if (clearAssignments) assignments = STOP_TRACKING_ASSIGNMENTS_MARKER; |
| // Do not remove users because our tracing analysis could be |
| // interested in tracing the users of this node. |
| } |
| @@ -131,7 +138,7 @@ abstract class TypeInformation { |
| /// Returns whether the type cannot change after it has been |
| /// inferred. |
| bool hasStableType(TypeGraphInferrerEngine inferrer) { |
| - return !abandonInferencing && assignments.every((e) => e.isStable); |
| + return !mightResume && assignments.every((e) => e.isStable); |
| } |
| void removeAndClearReferences(TypeGraphInferrerEngine inferrer) { |
| @@ -147,6 +154,12 @@ abstract class TypeInformation { |
| } |
| } |
| +abstract class ApplyableTypeInformation extends TypeInformation { |
| + bool mightBePassedToFunctionApply = false; |
| + |
| + ApplyableTypeInformation([users, assignments]) : super(users, assignments); |
|
floitsch
2014/04/14 15:39:37
Add types.
herhut
2014/04/15 10:50:39
There is no good type for these. They would need t
|
| +} |
| + |
| /** |
| * Parameters of instance functions behave differently than other |
| * elements because the inferrer may remove assignments. This happens |
| @@ -212,7 +225,7 @@ class ParameterAssignments extends IterableBase<TypeInformation> { |
| * trust their type annotation. |
| * |
| */ |
| -class ElementTypeInformation extends TypeInformation { |
| +class ElementTypeInformation extends ApplyableTypeInformation { |
| final Element element; |
| // Marker to disable [handleSpecialCases]. For example, parameters |
| @@ -272,7 +285,9 @@ class ElementTypeInformation extends TypeInformation { |
| return count == 1; |
| } |
| - bool isClosurized() => closurizedCount > 0; |
| + bool get isClosurized => closurizedCount > 0; |
| + |
| + bool get isStable => super.isStable && !isClosurized; |
|
floitsch
2014/04/14 15:39:37
Add comment, why isClosurized has influence on isS
herhut
2014/04/15 10:50:39
Done.
|
| TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) { |
| if (abandonInferencing) return type; |
| @@ -397,7 +412,9 @@ class ElementTypeInformation extends TypeInformation { |
| } |
| // If the method is closurized, the closure tracing phase will go |
| // through the users. |
| - if (closurizedCount != 0) return false; |
| + if (isClosurized) return false; |
| + |
| + if (element.isFunction()) return false; |
| return super.hasStableType(inferrer); |
| } |
| @@ -413,7 +430,7 @@ class ElementTypeInformation extends TypeInformation { |
| * any assignment. They rely on the [caller] field for static calls, |
| * and [selector] and [receiver] fields for dynamic calls. |
| */ |
| -abstract class CallSiteTypeInformation extends TypeInformation { |
| +abstract class CallSiteTypeInformation extends ApplyableTypeInformation { |
| final Spannable call; |
| final Element caller; |
| final Selector selector; |
| @@ -1233,7 +1250,7 @@ class PhiElementTypeInformation extends TypeInformation { |
| } |
| } |
| -class ClosureTypeInformation extends TypeInformation { |
| +class ClosureTypeInformation extends ApplyableTypeInformation { |
| final ast.Node node; |
| final Element element; |