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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 11316354: Re-apply "Move the handling of operator[] into the new interceptors." (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 HInstruction operand = node.operand; 200 HInstruction operand = node.operand;
201 if (operand is HConstant) { 201 if (operand is HConstant) {
202 UnaryOperation operation = node.operation(constantSystem); 202 UnaryOperation operation = node.operation(constantSystem);
203 HConstant receiver = operand; 203 HConstant receiver = operand;
204 Constant folded = operation.fold(receiver.constant); 204 Constant folded = operation.fold(receiver.constant);
205 if (folded != null) return graph.addConstant(folded); 205 if (folded != null) return graph.addConstant(folded);
206 } 206 }
207 return node; 207 return node;
208 } 208 }
209 209
210 HInstruction handleInterceptorCall(HInvokeDynamic node) { 210 HInstruction handleInterceptorCall(HInvokeDynamicMethod node) {
211 if (node is !HInvokeDynamicMethod) return null;
212 HInstruction input = node.inputs[1]; 211 HInstruction input = node.inputs[1];
213 if (input.isString(types) 212 if (input.isString(types)
214 && node.selector.name == const SourceString('toString')) { 213 && node.selector.name == const SourceString('toString')) {
215 return node.inputs[1]; 214 return node.inputs[1];
216 } 215 }
217 // Check if this call does not need to be intercepted. 216 // Check if this call does not need to be intercepted.
218 HType type = types[input]; 217 HType type = types[input];
219 var interceptor = node.inputs[0]; 218 var interceptor = node.inputs[0];
220 if (interceptor is !HThis && !type.canBePrimitive()) { 219 if (interceptor is !HThis && !type.canBePrimitive()) {
221 // If the type can be null, and the intercepted method can be in 220 // If the type can be null, and the intercepted method can be in
222 // the object class, keep the interceptor. 221 // the object class, keep the interceptor.
223 if (type.canBeNull() 222 if (type.canBeNull()
224 && interceptor.interceptedClasses.contains(compiler.objectClass)) { 223 && interceptor.interceptedClasses.contains(compiler.objectClass)) {
225 return node; 224 return node;
226 } 225 }
227 // Change the call to a regular invoke dynamic call. 226 // Change the call to a regular invoke dynamic call.
228 return new HInvokeDynamicMethod( 227 return new HInvokeDynamicMethod(
229 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); 228 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
230 } 229 }
231 230
232 Selector selector = node.selector; 231 Selector selector = node.selector;
232
233 if (node.isIndexOperatorOnIndexablePrimitive(types)) {
234 return new HIndex(node.inputs[1], node.inputs[2]);
235 }
236
233 SourceString selectorName = selector.name; 237 SourceString selectorName = selector.name;
234 Element target; 238 Element target;
235 if (input.isExtendableArray(types)) { 239 if (input.isExtendableArray(types)) {
236 if (selectorName == backend.jsArrayRemoveLast.name 240 if (selectorName == backend.jsArrayRemoveLast.name
237 && selector.argumentCount == 0) { 241 && selector.argumentCount == 0) {
238 target = backend.jsArrayRemoveLast; 242 target = backend.jsArrayRemoveLast;
239 } else if (selectorName == backend.jsArrayAdd.name 243 } else if (selectorName == backend.jsArrayAdd.name
240 && selector.argumentCount == 1 244 && selector.argumentCount == 1
241 && selector.namedArgumentCount == 0 245 && selector.namedArgumentCount == 0
242 && !compiler.enableTypeAssertions) { 246 && !compiler.enableTypeAssertions) {
(...skipping 28 matching lines...) Expand all
271 && node.inputs[1].isInteger(types); 275 && node.inputs[1].isInteger(types);
272 } 276 }
273 277
274 HInstruction visitInvokeStatic(HInvokeStatic node) { 278 HInstruction visitInvokeStatic(HInvokeStatic node) {
275 if (isFixedSizeListConstructor(node)) { 279 if (isFixedSizeListConstructor(node)) {
276 node.guaranteedType = HType.FIXED_ARRAY; 280 node.guaranteedType = HType.FIXED_ARRAY;
277 } 281 }
278 return node; 282 return node;
279 } 283 }
280 284
281 HInstruction visitInvokeDynamic(HInvokeDynamic node) { 285 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
282 if (node.isInterceptorCall) return handleInterceptorCall(node); 286 if (node.isInterceptorCall) return handleInterceptorCall(node);
283 HType receiverType = types[node.receiver]; 287 HType receiverType = types[node.receiver];
284 if (receiverType.isExact()) { 288 if (receiverType.isExact()) {
285 HBoundedType type = receiverType; 289 HBoundedType type = receiverType;
286 Element element = type.lookupMember(node.selector.name); 290 Element element = type.lookupMember(node.selector.name);
287 // TODO(ngeoffray): Also fold if it's a getter or variable. 291 // TODO(ngeoffray): Also fold if it's a getter or variable.
288 if (element != null && element.isFunction()) { 292 if (element != null && element.isFunction()) {
289 if (node.selector.applies(element, compiler)) { 293 if (node.selector.applies(element, compiler)) {
290 FunctionElement method = element; 294 FunctionElement method = element;
291 FunctionSignature parameters = method.computeSignature(compiler); 295 FunctionSignature parameters = method.computeSignature(compiler);
292 if (parameters.optionalParameterCount == 0) { 296 if (parameters.optionalParameterCount == 0) {
293 node.element = element; 297 node.element = element;
294 } 298 }
295 // TODO(ngeoffray): If the method has optional parameters, 299 // TODO(ngeoffray): If the method has optional parameters,
296 // we should pass the default values here. 300 // we should pass the default values here.
297 } 301 }
298 } 302 }
299 } 303 }
300 return node; 304 return node;
301 } 305 }
302 306
303 /** 307 /**
304 * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a 308 * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a
305 * [HInvokeDynamic] because we know the receiver is not a JS 309 * [HInvokeDynamic] because we know the receiver is not a JS
306 * primitive object. 310 * primitive object.
307 */ 311 */
308 HInstruction fromPrimitiveInstructionToDynamicInvocation(HInvokeStatic node, 312 HInstruction fromPrimitiveInstructionToDynamicInvocation(HInstruction node,
309 Selector selector) { 313 Selector selector) {
310 HBoundedType type = types[node.inputs[1]]; 314 HBoundedType type = types[node.inputs[1]];
311 HInvokeDynamicMethod result = new HInvokeDynamicMethod( 315 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
312 selector, 316 selector,
313 node.inputs.getRange(1, node.inputs.length - 1)); 317 node.inputs.getRange(1, node.inputs.length - 1));
314 if (type.isExact()) { 318 if (type.isExact()) {
315 HBoundedType concrete = type; 319 HBoundedType concrete = type;
316 result.element = concrete.lookupMember(selector.name); 320 result.element = concrete.lookupMember(selector.name);
317 } 321 }
318 return result; 322 return result;
319 } 323 }
320 324
321 HInstruction visitIntegerCheck(HIntegerCheck node) { 325 HInstruction visitIntegerCheck(HIntegerCheck node) {
322 HInstruction value = node.value; 326 HInstruction value = node.value;
323 if (value.isInteger(types)) return value; 327 if (value.isInteger(types)) return value;
324 if (value.isConstant()) { 328 if (value.isConstant()) {
325 HConstant constantInstruction = value; 329 HConstant constantInstruction = value;
326 assert(!constantInstruction.constant.isInt()); 330 assert(!constantInstruction.constant.isInt());
327 if (!constantSystem.isInt(constantInstruction.constant)) { 331 if (!constantSystem.isInt(constantInstruction.constant)) {
328 // -0.0 is a double but will pass the runtime integer check. 332 // -0.0 is a double but will pass the runtime integer check.
329 node.alwaysFalse = true; 333 node.alwaysFalse = true;
330 } 334 }
331 } 335 }
332 return node; 336 return node;
333 } 337 }
334 338
335
336 HInstruction visitIndex(HIndex node) {
337 if (!node.receiver.canBePrimitive(types)) {
338 Selector selector = new Selector.index();
339 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
340 }
341 return node;
342 }
343
344 HInstruction visitIndexAssign(HIndexAssign node) { 339 HInstruction visitIndexAssign(HIndexAssign node) {
345 if (!node.receiver.canBePrimitive(types)) { 340 if (!node.receiver.canBePrimitive(types)) {
346 Selector selector = new Selector.indexSet(); 341 Selector selector = new Selector.indexSet();
347 return fromPrimitiveInstructionToDynamicInvocation(node, selector); 342 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
348 } 343 }
349 return node; 344 return node;
350 } 345 }
351 346
352 HInstruction visitInvokeBinary(HInvokeBinary node) { 347 HInstruction visitInvokeBinary(HInvokeBinary node) {
353 HInstruction left = node.left; 348 HInstruction left = node.left;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 HIntegerCheck check = new HIntegerCheck(value); 792 HIntegerCheck check = new HIntegerCheck(value);
798 node.block.addBefore(node, check); 793 node.block.addBefore(node, check);
799 Set<HInstruction> dominatedUsers = value.dominatedUsers(node); 794 Set<HInstruction> dominatedUsers = value.dominatedUsers(node);
800 for (HInstruction user in dominatedUsers) { 795 for (HInstruction user in dominatedUsers) {
801 user.changeUse(value, check); 796 user.changeUse(value, check);
802 } 797 }
803 return check; 798 return check;
804 } 799 }
805 800
806 void visitIndex(HIndex node) { 801 void visitIndex(HIndex node) {
807 if (!node.receiver.isIndexablePrimitive(types)) return;
808 if (boundsChecked.contains(node)) return; 802 if (boundsChecked.contains(node)) return;
809 HInstruction index = node.index; 803 HInstruction index = node.index;
810 if (!node.index.isInteger(types)) { 804 if (!node.index.isInteger(types)) {
811 index = insertIntegerCheck(node, index); 805 index = insertIntegerCheck(node, index);
812 } 806 }
813 index = insertBoundsCheck(node, node.receiver, index); 807 index = insertBoundsCheck(node, node.receiver, index);
814 node.changeUse(node.index, index); 808 node.changeUse(node.index, index);
815 assert(node.isBuiltin(types));
816 } 809 }
817 810
818 void visitIndexAssign(HIndexAssign node) { 811 void visitIndexAssign(HIndexAssign node) {
819 if (!node.receiver.isMutableArray(types)) return; 812 if (!node.receiver.isMutableArray(types)) return;
820 if (boundsChecked.contains(node)) return; 813 if (boundsChecked.contains(node)) return;
821 HInstruction index = node.index; 814 HInstruction index = node.index;
822 if (!node.index.isInteger(types)) { 815 if (!node.index.isInteger(types)) {
823 index = insertIntegerCheck(node, index); 816 index = insertIntegerCheck(node, index);
824 } 817 }
825 index = insertBoundsCheck(node, node.receiver, index); 818 index = insertBoundsCheck(node, node.receiver, index);
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 HInstruction receiver = interceptor.receiver; 1471 HInstruction receiver = interceptor.receiver;
1479 for (var user in receiver.usedBy) { 1472 for (var user in receiver.usedBy) {
1480 if (user is HInterceptor && interceptor.dominates(user)) { 1473 if (user is HInterceptor && interceptor.dominates(user)) {
1481 user.interceptedClasses = interceptor.interceptedClasses; 1474 user.interceptedClasses = interceptor.interceptedClasses;
1482 } 1475 }
1483 } 1476 }
1484 } 1477 }
1485 1478
1486 // TODO(ngeoffray): Also implement it for non-intercepted calls. 1479 // TODO(ngeoffray): Also implement it for non-intercepted calls.
1487 } 1480 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698