Chromium Code Reviews| 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); |