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

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

Issue 223403003: Use closure tracer to identify closures that are not passed to Function.apply (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix regression in emitted meta data Created 6 years, 9 months 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
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index cfe1661b5c587ef5a65b2e33b4179fbf00db2786..d8bb12ebe0d64359b7f1382d71d7925d346e5d47 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -27,6 +27,7 @@ part 'node_tracer.dart';
part 'map_tracer.dart';
bool _VERBOSE = false;
+bool _PRINT_SUMMARY = false;
/**
* A set of selector names that [List] implements, that we know return
@@ -569,16 +570,42 @@ class TypeGraphInferrerEngine
analyzeMapAndEnqueue(info);
});
+ // Trace closures to potentially infer argument types.
types.allocatedClosures.forEach((info) {
- ClosureTracerVisitor tracer = info is ClosureTypeInformation
- ? new ClosureTracerVisitor(info.element, info, this)
- : new StaticTearOffClosureTracerVisitor(info.element, info, this);
- tracer.run();
- if (!tracer.continueAnalyzing) return;
- FunctionElement element = info.element;
- element.functionSignature.forEachParameter((parameter) {
- workQueue.add(types.getInferredTypeOf(parameter));
- });
+ void trace(Iterable<FunctionElement> elements,
+ ClosureTracerVisitor tracer) {
+ tracer.run();
+ if (!tracer.continueAnalyzing) {
+ elements.forEach((FunctionElement e) {
+ compiler.world.registerMightBePassedToApply(e);
+ if (_VERBOSE) print("traced closure $e as ${true} (bail)");
+ });
+ return;
+ }
+ elements.forEach((FunctionElement e) {
+ e.functionSignature.forEachParameter((parameter) {
+ workQueue.add(types.getInferredTypeOf(parameter));
+ });
+ if (tracer.tracedType.mightBePassedToFunctionApply) {
+ compiler.world.registerMightBePassedToApply(e);
+ };
+ if (_VERBOSE) {
+ print("traced closure $e as "
+ "${compiler.world.getMightBePassedToApply(e)}");
+ }
+ });
+ }
+ if (info is ClosureTypeInformation) {
+ Iterable<FunctionElement> elements = [info.element];
+ trace(elements, new ClosureTracerVisitor(elements, info, this));
+ } else if (info is CallSiteTypeInformation) {
+ Iterable<FunctionElement> elements =
+ info.callees.where((e) => e.isFunction() && !e.isSynthesized);
floitsch 2014/04/14 15:39:37 You probably want to cache the computation (unless
herhut 2014/04/15 10:50:39 Done.
+ trace(elements, new ClosureTracerVisitor(elements, info, this));
floitsch 2014/04/14 15:39:37 Can it happen (frequently) that the elements list
herhut 2014/04/15 10:50:39 The situation where the target is not a function i
+ } else {
+ trace([info.element],
floitsch 2014/04/14 15:39:37 add assert to make sure you have the right type. A
herhut 2014/04/15 10:50:39 Done.
+ new StaticTearOffClosureTracerVisitor(info.element, info, this));
+ }
});
// Reset all nodes that use lists/maps that have been inferred, as well
@@ -596,7 +623,7 @@ class TypeGraphInferrerEngine
workQueue.addAll(seenTypes);
refine();
- if (_VERBOSE) {
+ if (_PRINT_SUMMARY) {
types.allocatedLists.values.forEach((ListTypeInformation info) {
print('${info.type} '
'for ${info.originalContainerType.allocationNode} '
@@ -752,6 +779,7 @@ class TypeGraphInferrerEngine
} else if (callee.isGetter()) {
return;
} else if (selector != null && selector.isGetter()) {
+ // We are tearing a function off and thus create a closure.
floitsch 2014/04/14 15:39:37 also add assert for that. assert(callee.isMethod()
herhut 2014/04/15 10:50:39 Done.
ElementTypeInformation info = types.getInferredTypeOf(callee);
if (remove) {
info.closurizedCount--;
@@ -759,6 +787,10 @@ class TypeGraphInferrerEngine
info.closurizedCount++;
if (Elements.isStaticOrTopLevel(callee)) {
types.allocatedClosures.add(info);
+ } else {
+ // We add the call-site type information here so that we
+ // can benefit from further refinement of the selector.
+ types.allocatedClosures.add(caller);
}
FunctionElement function = callee.implementation;
FunctionSignature signature = function.functionSignature;

Powered by Google App Engine
This is Rietveld 408576698