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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart

Issue 1761903002: dart2js cps: Keep interceptors in a separate field. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 dart2js.cps_ir.optimize_interceptors; 5 library dart2js.cps_ir.optimize_interceptors;
6 6
7 import 'optimizers.dart'; 7 import 'optimizers.dart';
8 import 'cps_ir_nodes.dart'; 8 import 'cps_ir_nodes.dart';
9 import 'loop_hierarchy.dart'; 9 import 'loop_hierarchy.dart';
10 import 'cps_fragment.dart'; 10 import 'cps_fragment.dart';
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 97 }
98 return prim; 98 return prim;
99 } 99 }
100 100
101 void computeInterceptedClasses(Interceptor interceptor) { 101 void computeInterceptedClasses(Interceptor interceptor) {
102 Set<ClassElement> intercepted = interceptor.interceptedClasses; 102 Set<ClassElement> intercepted = interceptor.interceptedClasses;
103 intercepted.clear(); 103 intercepted.clear();
104 for (Reference ref = interceptor.firstRef; ref != null; ref = ref.next) { 104 for (Reference ref = interceptor.firstRef; ref != null; ref = ref.next) {
105 Node use = ref.parent; 105 Node use = ref.parent;
106 if (use is InvokeMethod) { 106 if (use is InvokeMethod) {
107 TypeMask type = use.dartReceiver.type; 107 TypeMask type = use.receiver.type;
108 bool canOccurAsReceiver(ClassElement elem) { 108 bool canOccurAsReceiver(ClassElement elem) {
109 return classWorld.isInstantiated(elem) && 109 return classWorld.isInstantiated(elem) &&
110 !typeSystem.areDisjoint(type, 110 !typeSystem.areDisjoint(type,
111 typeSystem.getInterceptorSubtypes(elem)); 111 typeSystem.getInterceptorSubtypes(elem));
112 } 112 }
113 Iterable<ClassElement> classes = 113 Iterable<ClassElement> classes =
114 backend.getInterceptedClassesOn(use.selector.name); 114 backend.getInterceptedClassesOn(use.selector.name);
115 intercepted.addAll(classes.where(canOccurAsReceiver)); 115 intercepted.addAll(classes.where(canOccurAsReceiver));
116 } else { 116 } else {
117 intercepted.clear(); 117 intercepted.clear();
(...skipping 12 matching lines...) Expand all
130 130
131 /// True if [node] may return [JSNumber] instead of [JSInt] or [JSDouble]. 131 /// True if [node] may return [JSNumber] instead of [JSInt] or [JSDouble].
132 bool jsNumberClassSuffices(Interceptor node) { 132 bool jsNumberClassSuffices(Interceptor node) {
133 // No methods on JSNumber call 'down' to methods on JSInt or JSDouble. If 133 // No methods on JSNumber call 'down' to methods on JSInt or JSDouble. If
134 // all uses of the interceptor are for methods is defined only on JSNumber 134 // all uses of the interceptor are for methods is defined only on JSNumber
135 // then JSNumber will suffice in place of choosing between JSInt or 135 // then JSNumber will suffice in place of choosing between JSInt or
136 // JSDouble. 136 // JSDouble.
137 for (Reference ref = node.firstRef; ref != null; ref = ref.next) { 137 for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
138 if (ref.parent is InvokeMethod) { 138 if (ref.parent is InvokeMethod) {
139 InvokeMethod invoke = ref.parent; 139 InvokeMethod invoke = ref.parent;
140 if (invoke.receiverRef != ref) return false; 140 if (invoke.interceptorRef != ref) return false;
141 var interceptedClasses = 141 var interceptedClasses =
142 backend.getInterceptedClassesOn(invoke.selector.name); 142 backend.getInterceptedClassesOn(invoke.selector.name);
143 if (interceptedClasses.contains(helpers.jsDoubleClass)) return false; 143 if (interceptedClasses.contains(helpers.jsDoubleClass)) return false;
144 if (interceptedClasses.contains(helpers.jsIntClass)) return false; 144 if (interceptedClasses.contains(helpers.jsIntClass)) return false;
145 continue; 145 continue;
146 } 146 }
147 // Other uses need full distinction. 147 // Other uses need full distinction.
148 return false; 148 return false;
149 } 149 }
150 return true; 150 return true;
151 } 151 }
152 152
153 /// True if [node] can intercept a `null` value and return the [JSNull] 153 /// True if [node] can intercept a `null` value and return the [JSNull]
154 /// interceptor. 154 /// interceptor.
155 bool canInterceptNull(Interceptor node) { 155 bool canInterceptNull(Interceptor node) {
156 for (Reference ref = node.firstRef; ref != null; ref = ref.next) { 156 for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
157 Node use = ref.parent; 157 Node use = ref.parent;
158 if (use is InvokeMethod) { 158 if (use is InvokeMethod) {
159 if (selectorsOnNull.contains(use.selector) && 159 if (selectorsOnNull.contains(use.selector) &&
160 use.dartReceiver.type.isNullable) { 160 use.receiver.type.isNullable) {
161 return true; 161 return true;
162 } 162 }
163 } else { 163 } else {
164 return true; 164 return true;
165 } 165 }
166 } 166 }
167 return false; 167 return false;
168 } 168 }
169 169
170 /// Returns the only interceptor class that may be returned by [node], or 170 /// Returns the only interceptor class that may be returned by [node], or
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 if (node.hasExactlyOneUse) { 254 if (node.hasExactlyOneUse) {
255 // Set the loop header on single-use interceptors so [visitInvokeMethod] 255 // Set the loop header on single-use interceptors so [visitInvokeMethod]
256 // can determine if it should become a one-shot interceptor. 256 // can determine if it should become a one-shot interceptor.
257 loopHeaderFor[node] = currentLoopHeader; 257 loopHeaderFor[node] = currentLoopHeader;
258 } 258 }
259 } 259 }
260 260
261 @override 261 @override
262 void visitInvokeMethod(InvokeMethod node) { 262 void visitInvokeMethod(InvokeMethod node) {
263 if (node.callingConvention != CallingConvention.Intercepted) return; 263 if (node.callingConvention != CallingConvention.Intercepted) return;
264 Primitive interceptor = node.receiver; 264 Primitive interceptor = node.interceptor;
265 if (interceptor is! Interceptor || 265 if (interceptor is! Interceptor ||
266 interceptor.hasMultipleUses || 266 interceptor.hasMultipleUses ||
267 loopHeaderFor[interceptor] != currentLoopHeader) { 267 loopHeaderFor[interceptor] != currentLoopHeader) {
268 return; 268 return;
269 } 269 }
270 // TODO(asgerf): Consider heuristics for when to use one-shot interceptors. 270 // TODO(asgerf): Consider heuristics for when to use one-shot interceptors.
271 // E.g. using only one-shot interceptors with a fast path. 271 // E.g. using only one-shot interceptors with a fast path.
272 node.callingConvention = CallingConvention.OneShotIntercepted; 272 node.makeOneShotIntercepted();
273 node..receiverRef.unlink()..receiverRef = node.argumentRefs.removeAt(0);
274 } 273 }
275 274
276 @override 275 @override
277 void visitTypeTestViaFlag(TypeTestViaFlag node) { 276 void visitTypeTestViaFlag(TypeTestViaFlag node) {
278 Primitive interceptor = node.interceptor; 277 Primitive interceptor = node.interceptor;
279 if (interceptor is! Interceptor || 278 if (interceptor is! Interceptor ||
280 interceptor.hasMultipleUses || 279 interceptor.hasMultipleUses ||
281 loopHeaderFor[interceptor] != currentLoopHeader || 280 loopHeaderFor[interceptor] != currentLoopHeader ||
282 !backend.mayGenerateInstanceofCheck(node.dartType)) { 281 !backend.mayGenerateInstanceofCheck(node.dartType)) {
283 return; 282 return;
(...skipping 30 matching lines...) Expand all
314 sharedConstantFor.remove(prim.value); 313 sharedConstantFor.remove(prim.value);
315 }); 314 });
316 } 315 }
317 return next; 316 return next;
318 } 317 }
319 318
320 bool shouldShareConstant(Constant constant) { 319 bool shouldShareConstant(Constant constant) {
321 return constant.value.isInterceptor; 320 return constant.value.isInterceptor;
322 } 321 }
323 } 322 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/insert_refinements.dart ('k') | pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698