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

Unified Diff: sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.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/closure_tracer.dart
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
index 0814f6ef906b772ec09b1f9bdea0d1164814e048..07b0c958afc4165f02c97f91770ee140bec3547b 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
@@ -4,38 +4,50 @@
part of type_graph_inferrer;
-class ClosureTracerVisitor extends TracerVisitor {
- final FunctionElement tracedElement;
+class ClosureTracerVisitor extends TracerVisitor<ApplyableTypeInformation> {
+ final Iterable<FunctionElement> tracedElements;
- ClosureTracerVisitor(this.tracedElement, tracedType, inferrer)
+ ClosureTracerVisitor(this.tracedElements, tracedType, inferrer)
: super(tracedType, inferrer);
void run() {
- tracedElement.functionSignature.forEachParameter((Element parameter) {
- ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter);
- info.abandonInferencing = false;
+ tracedElements.forEach((FunctionElement e) {
floitsch 2014/04/14 15:39:37 minor nit: I prefer for (FunctionElement e in tra
herhut 2014/04/15 10:50:39 Parameters of closurized functions are abandoned d
+ e.functionSignature.forEachParameter((Element parameter) {
+ ElementTypeInformation info =
+ inferrer.types.getInferredTypeOf(parameter);
+ info.abandonInferencing = info.abandonInferencing &&
+ !info.mightResume;
+ });
});
analyze();
- tracedElement.functionSignature.forEachParameter((Element parameter) {
- ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter);
- if (continueAnalyzing) {
- info.disableHandleSpecialCases = true;
- } else {
- info.giveUp(inferrer);
- }
+ tracedElements.forEach((FunctionElement e) {
floitsch 2014/04/14 15:39:37 ditto.
herhut 2014/04/15 10:50:39 Done.
+ e.functionSignature.forEachParameter((Element parameter) {
+ ElementTypeInformation info =
+ inferrer.types.getInferredTypeOf(parameter);
+ if (continueAnalyzing) {
+ info.disableHandleSpecialCases = true;
+ } else {
+ info.giveUp(inferrer);
+ }
+ });
});
}
- visitMapTypeInformation(MapTypeInformation info) {
- bailout('Stored in a map');
+ void tagAsFunctionApplyTarget([String reason]) {
+ tracedType.mightBePassedToFunctionApply = true;
+ if (_VERBOSE) {
+ print("Closure $tracedType might be passed to apply: $reason");
+ }
}
void analyzeCall(CallSiteTypeInformation info) {
Selector selector = info.selector;
- if (!selector.signatureApplies(tracedElement, compiler)) return;
- inferrer.updateParameterAssignments(
- info, tracedElement, info.arguments, selector, remove: false,
- addToQueue: false);
+ tracedElements.forEach((FunctionElement e) {
floitsch 2014/04/14 15:39:37 s/e/functionElement/
herhut 2014/04/15 10:50:39 Done.
+ if (!selector.signatureApplies(e, compiler)) return;
+ inferrer.updateParameterAssignments(
+ info, e, info.arguments, selector, remove: false,
+ addToQueue: false);
+ });
}
visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
@@ -64,18 +76,29 @@ class ClosureTracerVisitor extends TracerVisitor {
// where `foo` is a getter.
analyzeCall(info);
}
+ if (checkIfFunctionApply(called) && info.arguments.contains(currentUser)) {
+ tagAsFunctionApplyTarget("static call");
+ }
}
bool checkIfCurrentUser(element) {
return inferrer.types.getInferredTypeOf(element) == currentUser;
}
+ bool checkIfFunctionApply(element) {
+ return compiler.functionApplyMethod == element;
+ }
+
visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
super.visitDynamicCallSiteTypeInformation(info);
if (info.selector.isCall()) {
- if (info.arguments.contains(currentUser)
- && !info.targets.every((element) => element.isFunction())) {
- bailout('Passed to a closure');
+ if (info.arguments.contains(currentUser)) {
+ if (!info.targets.every((element) => element.isFunction())) {
+ bailout('Passed to a closure');
+ }
+ if (info.targets.any(checkIfFunctionApply)) {
+ tagAsFunctionApplyTarget("dynamic call");
+ }
} else if (info.targets.any((element) => checkIfCurrentUser(element))) {
analyzeCall(info);
}
@@ -85,11 +108,11 @@ class ClosureTracerVisitor extends TracerVisitor {
class StaticTearOffClosureTracerVisitor extends ClosureTracerVisitor {
StaticTearOffClosureTracerVisitor(tracedElement, tracedType, inferrer)
- : super(tracedElement, tracedType, inferrer);
+ : super([tracedElement], tracedType, inferrer);
visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
super.visitStaticCallSiteTypeInformation(info);
- if (info.calledElement == tracedElement
+ if (info.calledElement == tracedElements.first
&& info.selector != null
&& info.selector.isGetter()) {
addNewEscapeInformation(info);

Powered by Google App Engine
This is Rietveld 408576698