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

Side by Side 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, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of type_graph_inferrer; 5 part of type_graph_inferrer;
6 6
7 class ClosureTracerVisitor extends TracerVisitor { 7 class ClosureTracerVisitor extends TracerVisitor<ApplyableTypeInformation> {
8 final FunctionElement tracedElement; 8 final Iterable<FunctionElement> tracedElements;
9 9
10 ClosureTracerVisitor(this.tracedElement, tracedType, inferrer) 10 ClosureTracerVisitor(this.tracedElements, tracedType, inferrer)
11 : super(tracedType, inferrer); 11 : super(tracedType, inferrer);
12 12
13 void run() { 13 void run() {
14 tracedElement.functionSignature.forEachParameter((Element parameter) { 14 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
15 ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter); 15 e.functionSignature.forEachParameter((Element parameter) {
16 info.abandonInferencing = false; 16 ElementTypeInformation info =
17 inferrer.types.getInferredTypeOf(parameter);
18 info.abandonInferencing = info.abandonInferencing &&
19 !info.mightResume;
20 });
17 }); 21 });
18 analyze(); 22 analyze();
19 tracedElement.functionSignature.forEachParameter((Element parameter) { 23 tracedElements.forEach((FunctionElement e) {
floitsch 2014/04/14 15:39:37 ditto.
herhut 2014/04/15 10:50:39 Done.
20 ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter); 24 e.functionSignature.forEachParameter((Element parameter) {
21 if (continueAnalyzing) { 25 ElementTypeInformation info =
22 info.disableHandleSpecialCases = true; 26 inferrer.types.getInferredTypeOf(parameter);
23 } else { 27 if (continueAnalyzing) {
24 info.giveUp(inferrer); 28 info.disableHandleSpecialCases = true;
25 } 29 } else {
30 info.giveUp(inferrer);
31 }
32 });
26 }); 33 });
27 } 34 }
28 35
29 visitMapTypeInformation(MapTypeInformation info) { 36 void tagAsFunctionApplyTarget([String reason]) {
30 bailout('Stored in a map'); 37 tracedType.mightBePassedToFunctionApply = true;
38 if (_VERBOSE) {
39 print("Closure $tracedType might be passed to apply: $reason");
40 }
31 } 41 }
32 42
33 void analyzeCall(CallSiteTypeInformation info) { 43 void analyzeCall(CallSiteTypeInformation info) {
34 Selector selector = info.selector; 44 Selector selector = info.selector;
35 if (!selector.signatureApplies(tracedElement, compiler)) return; 45 tracedElements.forEach((FunctionElement e) {
floitsch 2014/04/14 15:39:37 s/e/functionElement/
herhut 2014/04/15 10:50:39 Done.
36 inferrer.updateParameterAssignments( 46 if (!selector.signatureApplies(e, compiler)) return;
37 info, tracedElement, info.arguments, selector, remove: false, 47 inferrer.updateParameterAssignments(
38 addToQueue: false); 48 info, e, info.arguments, selector, remove: false,
49 addToQueue: false);
50 });
39 } 51 }
40 52
41 visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) { 53 visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
42 super.visitClosureCallSiteTypeInformation(info); 54 super.visitClosureCallSiteTypeInformation(info);
43 if (info.closure == currentUser) { 55 if (info.closure == currentUser) {
44 analyzeCall(info); 56 analyzeCall(info);
45 } else { 57 } else {
46 bailout('Passed to a closure'); 58 bailout('Passed to a closure');
47 } 59 }
48 } 60 }
49 61
50 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { 62 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
51 super.visitStaticCallSiteTypeInformation(info); 63 super.visitStaticCallSiteTypeInformation(info);
52 Element called = info.calledElement; 64 Element called = info.calledElement;
53 if (called.isForeign(compiler)) { 65 if (called.isForeign(compiler)) {
54 String name = called.name; 66 String name = called.name;
55 if (name == 'JS' || name == 'DART_CLOSURE_TO_JS') { 67 if (name == 'JS' || name == 'DART_CLOSURE_TO_JS') {
56 bailout('Used in JS ${info.call}'); 68 bailout('Used in JS ${info.call}');
57 } 69 }
58 } 70 }
59 if (called.isGetter() 71 if (called.isGetter()
60 && info.selector != null 72 && info.selector != null
61 && info.selector.isCall() 73 && info.selector.isCall()
62 && inferrer.types.getInferredTypeOf(called) == currentUser) { 74 && inferrer.types.getInferredTypeOf(called) == currentUser) {
63 // This node can be a closure call as well. For example, `foo()` 75 // This node can be a closure call as well. For example, `foo()`
64 // where `foo` is a getter. 76 // where `foo` is a getter.
65 analyzeCall(info); 77 analyzeCall(info);
66 } 78 }
79 if (checkIfFunctionApply(called) && info.arguments.contains(currentUser)) {
80 tagAsFunctionApplyTarget("static call");
81 }
67 } 82 }
68 83
69 bool checkIfCurrentUser(element) { 84 bool checkIfCurrentUser(element) {
70 return inferrer.types.getInferredTypeOf(element) == currentUser; 85 return inferrer.types.getInferredTypeOf(element) == currentUser;
71 } 86 }
72 87
88 bool checkIfFunctionApply(element) {
89 return compiler.functionApplyMethod == element;
90 }
91
73 visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) { 92 visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
74 super.visitDynamicCallSiteTypeInformation(info); 93 super.visitDynamicCallSiteTypeInformation(info);
75 if (info.selector.isCall()) { 94 if (info.selector.isCall()) {
76 if (info.arguments.contains(currentUser) 95 if (info.arguments.contains(currentUser)) {
77 && !info.targets.every((element) => element.isFunction())) { 96 if (!info.targets.every((element) => element.isFunction())) {
78 bailout('Passed to a closure'); 97 bailout('Passed to a closure');
98 }
99 if (info.targets.any(checkIfFunctionApply)) {
100 tagAsFunctionApplyTarget("dynamic call");
101 }
79 } else if (info.targets.any((element) => checkIfCurrentUser(element))) { 102 } else if (info.targets.any((element) => checkIfCurrentUser(element))) {
80 analyzeCall(info); 103 analyzeCall(info);
81 } 104 }
82 } 105 }
83 } 106 }
84 } 107 }
85 108
86 class StaticTearOffClosureTracerVisitor extends ClosureTracerVisitor { 109 class StaticTearOffClosureTracerVisitor extends ClosureTracerVisitor {
87 StaticTearOffClosureTracerVisitor(tracedElement, tracedType, inferrer) 110 StaticTearOffClosureTracerVisitor(tracedElement, tracedType, inferrer)
88 : super(tracedElement, tracedType, inferrer); 111 : super([tracedElement], tracedType, inferrer);
89 112
90 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { 113 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
91 super.visitStaticCallSiteTypeInformation(info); 114 super.visitStaticCallSiteTypeInformation(info);
92 if (info.calledElement == tracedElement 115 if (info.calledElement == tracedElements.first
93 && info.selector != null 116 && info.selector != null
94 && info.selector.isGetter()) { 117 && info.selector.isGetter()) {
95 addNewEscapeInformation(info); 118 addNewEscapeInformation(info);
96 } 119 }
97 } 120 }
98 } 121 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698