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: pkg/compiler/lib/src/inferrer/closure_tracer.dart

Issue 2965223002: Change inference element invariants (Closed)
Patch Set: Updated cf. comments Created 3 years, 5 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
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 library compiler.src.inferrer.closure_tracer; 5 library compiler.src.inferrer.closure_tracer;
6 6
7 import '../common/names.dart' show Names; 7 import '../common/names.dart' show Names;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../elements/entities.dart';
9 import '../js_backend/backend.dart' show JavaScriptBackend; 10 import '../js_backend/backend.dart' show JavaScriptBackend;
10 import '../types/types.dart' show TypeMask; 11 import '../types/types.dart' show TypeMask;
11 import '../universe/selector.dart' show Selector; 12 import '../universe/selector.dart' show Selector;
12 import 'debug.dart' as debug; 13 import 'debug.dart' as debug;
13 import 'inferrer_engine.dart'; 14 import 'inferrer_engine.dart';
14 import 'node_tracer.dart'; 15 import 'node_tracer.dart';
15 import 'type_graph_nodes.dart'; 16 import 'type_graph_nodes.dart';
16 17
17 class ClosureTracerVisitor extends TracerVisitor { 18 class ClosureTracerVisitor extends TracerVisitor {
18 final Iterable<MethodElement> tracedElements; 19 final Iterable<FunctionEntity> tracedElements;
19 final List<CallSiteTypeInformation> _callsToAnalyze = 20 final List<CallSiteTypeInformation> _callsToAnalyze =
20 new List<CallSiteTypeInformation>(); 21 new List<CallSiteTypeInformation>();
21 22
22 ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType, 23 ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType,
23 InferrerEngine inferrer) 24 InferrerEngine inferrer)
24 : super(tracedType, inferrer); 25 : super(tracedType, inferrer);
25 26
26 ApplyableTypeInformation get tracedType => super.tracedType; 27 ApplyableTypeInformation get tracedType => super.tracedType;
27 28
28 void run() { 29 void run() {
29 analyze(); 30 analyze();
30 if (!continueAnalyzing) return; 31 if (!continueAnalyzing) return;
31 _callsToAnalyze.forEach(_analyzeCall); 32 _callsToAnalyze.forEach(_analyzeCall);
32 for (MethodElement e in tracedElements) { 33 for (MethodElement element in tracedElements) {
33 e.functionSignature.forEachParameter((Element parameter) { 34 MethodElement implementation = element.implementation;
35 implementation.functionSignature.forEachParameter((Element parameter) {
34 ElementTypeInformation info = 36 ElementTypeInformation info =
35 inferrer.types.getInferredTypeOfParameter(parameter); 37 inferrer.types.getInferredTypeOfParameter(parameter);
36 info.disableInferenceForClosures = false; 38 info.disableInferenceForClosures = false;
37 }); 39 });
38 } 40 }
39 } 41 }
40 42
41 void _tagAsFunctionApplyTarget([String reason]) { 43 void _tagAsFunctionApplyTarget([String reason]) {
42 tracedType.mightBePassedToFunctionApply = true; 44 tracedType.mightBePassedToFunctionApply = true;
43 if (debug.VERBOSE) { 45 if (debug.VERBOSE) {
44 print("Closure $tracedType might be passed to apply: $reason"); 46 print("Closure $tracedType might be passed to apply: $reason");
45 } 47 }
46 } 48 }
47 49
48 void _registerCallForLaterAnalysis(CallSiteTypeInformation info) { 50 void _registerCallForLaterAnalysis(CallSiteTypeInformation info) {
49 _callsToAnalyze.add(info); 51 _callsToAnalyze.add(info);
50 } 52 }
51 53
52 void _analyzeCall(CallSiteTypeInformation info) { 54 void _analyzeCall(CallSiteTypeInformation info) {
53 Selector selector = info.selector; 55 Selector selector = info.selector;
54 TypeMask mask = info.mask; 56 TypeMask mask = info.mask;
55 tracedElements.forEach((MethodElement functionElement) { 57 tracedElements.forEach((FunctionEntity functionElement) {
56 if (!selector.callStructure 58 if (!selector.callStructure
57 .signatureApplies(functionElement.parameterStructure)) { 59 .signatureApplies(functionElement.parameterStructure)) {
58 return; 60 return;
59 } 61 }
60 inferrer.updateParameterAssignments( 62 inferrer.updateParameterAssignments(
61 info, functionElement, info.arguments, selector, mask, 63 info, functionElement, info.arguments, selector, mask,
62 remove: false, addToQueue: false); 64 remove: false, addToQueue: false);
63 }); 65 });
64 } 66 }
65 67
66 @override 68 @override
67 visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) { 69 visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
68 super.visitClosureCallSiteTypeInformation(info); 70 super.visitClosureCallSiteTypeInformation(info);
69 if (info.closure == currentUser) { 71 if (info.closure == currentUser) {
70 _registerCallForLaterAnalysis(info); 72 _registerCallForLaterAnalysis(info);
71 } else { 73 } else {
72 bailout('Passed to a closure'); 74 bailout('Passed to a closure');
73 } 75 }
74 } 76 }
75 77
76 @override 78 @override
77 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { 79 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
78 super.visitStaticCallSiteTypeInformation(info); 80 super.visitStaticCallSiteTypeInformation(info);
79 Element called = info.calledElement; 81 MemberEntity called = info.calledElement;
80 if (compiler.backend 82 if (inferrer.closedWorld.commonElements.isForeign(called)) {
81 .isForeign(inferrer.closedWorld.commonElements, called)) {
82 String name = called.name; 83 String name = called.name;
83 if (name == JavaScriptBackend.JS || name == 'DART_CLOSURE_TO_JS') { 84 if (name == JavaScriptBackend.JS || name == 'DART_CLOSURE_TO_JS') {
84 bailout('Used in JS ${info.call}'); 85 bailout('Used in JS ${info.call}');
85 } 86 }
86 } 87 }
87 if (called.isGetter && 88 if (called.isGetter &&
88 info.selector != null && 89 info.selector != null &&
89 info.selector.isCall && 90 info.selector.isCall &&
90 inferrer.types.getInferredTypeOfMember(called) == currentUser) { 91 inferrer.types.getInferredTypeOfMember(called) == currentUser) {
91 // This node can be a closure call as well. For example, `foo()` 92 // This node can be a closure call as well. For example, `foo()`
92 // where `foo` is a getter. 93 // where `foo` is a getter.
93 _registerCallForLaterAnalysis(info); 94 _registerCallForLaterAnalysis(info);
94 } 95 }
95 if (called is MemberElement && 96 if (_checkIfFunctionApply(called) &&
96 _checkIfFunctionApply(called) &&
97 info.arguments != null && 97 info.arguments != null &&
98 info.arguments.contains(currentUser)) { 98 info.arguments.contains(currentUser)) {
99 _tagAsFunctionApplyTarget("static call"); 99 _tagAsFunctionApplyTarget("static call");
100 } 100 }
101 } 101 }
102 102
103 bool _checkIfCurrentUser(MemberElement element) => 103 bool _checkIfCurrentUser(MemberEntity element) =>
104 inferrer.types.getInferredTypeOfMember(element) == currentUser; 104 inferrer.types.getInferredTypeOfMember(element) == currentUser;
105 105
106 bool _checkIfFunctionApply(MemberElement element) { 106 bool _checkIfFunctionApply(MemberEntity element) {
107 return inferrer.closedWorld.commonElements.isFunctionApplyMethod(element); 107 return inferrer.closedWorld.commonElements.isFunctionApplyMethod(element);
108 } 108 }
109 109
110 @override 110 @override
111 visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) { 111 visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
112 super.visitDynamicCallSiteTypeInformation(info); 112 super.visitDynamicCallSiteTypeInformation(info);
113 if (info.selector.isCall) { 113 if (info.selector.isCall) {
114 if (info.arguments.contains(currentUser)) { 114 if (info.arguments.contains(currentUser)) {
115 if (!info.targets.every((element) => element.isFunction)) { 115 if (!info.targets.every((element) => element.isFunction)) {
116 bailout('Passed to a closure'); 116 bailout('Passed to a closure');
(...skipping 20 matching lines...) Expand all
137 @override 137 @override
138 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { 138 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
139 super.visitStaticCallSiteTypeInformation(info); 139 super.visitStaticCallSiteTypeInformation(info);
140 if (info.calledElement == tracedElements.first && 140 if (info.calledElement == tracedElements.first &&
141 info.selector != null && 141 info.selector != null &&
142 info.selector.isGetter) { 142 info.selector.isGetter) {
143 addNewEscapeInformation(info); 143 addNewEscapeInformation(info);
144 } 144 }
145 } 145 }
146 } 146 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/builder.dart ('k') | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698