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

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

Issue 12330135: Make instance methods whose names collide with intercepted methods have the interceptor calling con… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 result.element = target; 310 result.element = target;
311 return result; 311 return result;
312 } 312 }
313 } else if (selector.isGetter()) { 313 } else if (selector.isGetter()) {
314 if (selector.applies(backend.jsArrayLength, compiler)) { 314 if (selector.applies(backend.jsArrayLength, compiler)) {
315 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); 315 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
316 if (optimized != null) return optimized; 316 if (optimized != null) return optimized;
317 } 317 }
318 } 318 }
319 319
320 // Check if this call does not need to be intercepted.
321 HType type = input.instructionType;
322 // TODO(kasperl): Get rid of this refinement once the receiver
323 // specialization phase takes care of it.
324 Selector refined = type.refine(selector, compiler);
325 Set<ClassElement> classes = backend.getInterceptedClassesOn(
326 refined, canBeNull: type.canBeNull());
327 if (classes == null) {
328 if (selector.isGetter()) {
329 // Change the call to a regular invoke dynamic call.
330 return new HInvokeDynamicGetter(selector, null, input, false);
331 } else if (selector.isSetter()) {
332 return new HInvokeDynamicSetter(
333 selector, null, input, node.inputs[2], false);
334 } else {
335 // Change the call to a regular invoke dynamic call.
336 return new HInvokeDynamicMethod(
337 selector, node.inputs.getRange(1, node.inputs.length - 1));
338 }
339 }
340
341 // If the intercepted call is through a constant interceptor, we 320 // If the intercepted call is through a constant interceptor, we
342 // know which element to call. 321 // know which element to call.
343 if (node is !HOneShotInterceptor 322 if (node is !HOneShotInterceptor
344 && interceptor.isConstant() 323 && interceptor.isConstant()
345 && selector.isCall()) { 324 && selector.isCall()) {
346 DartType type = interceptor.instructionType.computeType(compiler); 325 DartType type = interceptor.instructionType.computeType(compiler);
347 ClassElement cls = type.element; 326 ClassElement cls = type.element;
348 node.element = cls.lookupSelector(selector); 327 node.element = cls.lookupSelector(selector);
349 } 328 }
350 return node; 329 return node;
(...skipping 17 matching lines...) Expand all
368 } 347 }
369 348
370 HInstruction visitInvokeStatic(HInvokeStatic node) { 349 HInstruction visitInvokeStatic(HInvokeStatic node) {
371 if (isFixedSizeListConstructor(node)) { 350 if (isFixedSizeListConstructor(node)) {
372 node.instructionType = HType.FIXED_ARRAY; 351 node.instructionType = HType.FIXED_ARRAY;
373 } 352 }
374 return node; 353 return node;
375 } 354 }
376 355
377 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 356 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
378 if (node.isInterceptorCall) return handleInterceptorCall(node); 357 if (node.isCallOnInterceptor) return handleInterceptorCall(node);
379 HType receiverType = node.receiver.instructionType; 358 HType receiverType = node.receiver.instructionType;
380 Selector selector = receiverType.refine(node.selector, compiler); 359 Selector selector = receiverType.refine(node.selector, compiler);
381 Element element = compiler.world.locateSingleElement(selector); 360 Element element = compiler.world.locateSingleElement(selector);
382 // TODO(ngeoffray): Also fold if it's a getter or variable. 361 // TODO(ngeoffray): Also fold if it's a getter or variable.
383 if (element != null && element.isFunction()) { 362 if (element != null && element.isFunction()) {
384 FunctionElement method = element; 363 FunctionElement method = element;
385 FunctionSignature parameters = method.computeSignature(compiler); 364 FunctionSignature parameters = method.computeSignature(compiler);
386 // TODO(ngeoffray): If the method has optional parameters, 365 // TODO(ngeoffray): If the method has optional parameters,
387 // we should pass the default values. 366 // we should pass the default values.
388 if (parameters.optionalParameterCount == 0 367 if (parameters.optionalParameterCount == 0
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 HInvokeStatic call = node.receiver; 581 HInvokeStatic call = node.receiver;
603 if (isFixedSizeListConstructor(call)) { 582 if (isFixedSizeListConstructor(call)) {
604 return call.inputs[1]; 583 return call.inputs[1];
605 } 584 }
606 } 585 }
607 } 586 }
608 return node; 587 return node;
609 } 588 }
610 589
611 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 590 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
612 if (node.isInterceptorCall) return handleInterceptorCall(node); 591 if (node.isCallOnInterceptor) return handleInterceptorCall(node);
613 592
614 Element field = 593 Element field =
615 findConcreteFieldForDynamicAccess(node.receiver, node.selector); 594 findConcreteFieldForDynamicAccess(node.receiver, node.selector);
616 if (field == null) return node; 595 if (field == null) return node;
617 596
618 Modifiers modifiers = field.modifiers; 597 Modifiers modifiers = field.modifiers;
619 bool isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); 598 bool isFinalOrConst = modifiers.isFinal() || modifiers.isConst();
620 if (!compiler.resolverWorld.hasInvokedSetter(field, compiler)) { 599 if (!compiler.resolverWorld.hasInvokedSetter(field, compiler)) {
621 // If no setter is ever used for this field it is only initialized in the 600 // If no setter is ever used for this field it is only initialized in the
622 // initializer list. 601 // initializer list.
(...skipping 15 matching lines...) Expand all
638 } 617 }
639 } 618 }
640 if (type != null) { 619 if (type != null) {
641 result.instructionType = type; 620 result.instructionType = type;
642 } 621 }
643 } 622 }
644 return result; 623 return result;
645 } 624 }
646 625
647 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 626 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
648 if (node.isInterceptorCall) return handleInterceptorCall(node); 627 if (node.isCallOnInterceptor) return handleInterceptorCall(node);
649 628
650 Element field = 629 Element field =
651 findConcreteFieldForDynamicAccess(node.receiver, node.selector); 630 findConcreteFieldForDynamicAccess(node.receiver, node.selector);
652 if (field == null || !field.isAssignable()) return node; 631 if (field == null || !field.isAssignable()) return node;
653 HInstruction value = node.inputs[1]; 632 // Use [:node.inputs.last:] in case the call follows the
633 // interceptor calling convention, but is not a call on an
634 // interceptor.
635 HInstruction value = node.inputs.last;
654 if (compiler.enableTypeAssertions) { 636 if (compiler.enableTypeAssertions) {
655 HInstruction other = value.convertType( 637 HInstruction other = value.convertType(
656 compiler, 638 compiler,
657 field.computeType(compiler), 639 field.computeType(compiler),
658 HTypeConversion.CHECKED_MODE_CHECK); 640 HTypeConversion.CHECKED_MODE_CHECK);
659 if (other != value) { 641 if (other != value) {
660 node.block.addBefore(node, other); 642 node.block.addBefore(node, other);
661 value = other; 643 value = other;
662 } 644 }
663 } 645 }
664 return new HFieldSet(field, node.inputs[0], value); 646 return new HFieldSet(field, node.inputs[0], value);
665 } 647 }
666 648
667 HInstruction visitStringConcat(HStringConcat node) { 649 HInstruction visitStringConcat(HStringConcat node) {
668 DartString folded = const LiteralDartString(""); 650 DartString folded = const LiteralDartString("");
669 for (int i = 0; i < node.inputs.length; i++) { 651 for (int i = 0; i < node.inputs.length; i++) {
670 HInstruction part = node.inputs[i]; 652 HInstruction part = node.inputs[i];
671 if (!part.isConstant()) return node; 653 if (!part.isConstant()) return node;
672 HConstant constant = part; 654 HConstant constant = part;
673 if (!constant.constant.isPrimitive()) return node; 655 if (!constant.constant.isPrimitive()) return node;
674 PrimitiveConstant primitive = constant.constant; 656 PrimitiveConstant primitive = constant.constant;
675 folded = new DartString.concat(folded, primitive.toDartString()); 657 folded = new DartString.concat(folded, primitive.toDartString());
676 } 658 }
677 return graph.addConstant(constantSystem.createString(folded, node.node)); 659 return graph.addConstant(constantSystem.createString(folded, node.node));
678 } 660 }
679 661
680 HInstruction visitInterceptor(HInterceptor node) { 662 HInstruction visitInterceptor(HInterceptor node) {
681 if (node.isConstant()) return node; 663 if (node.isConstant()) return node;
664 // If the intercepted object does not need to be intercepted, just
665 // return the object (the [:getInterceptor:] method would have
666 // returned the object).
667 HType type = node.receiver.instructionType;
668 if (!type.canBePrimitive(compiler)) {
669 print('IN HERE BECAUSE OF $type');
670 if (!(type.canBeNull()
671 && node.interceptedClasses.contains(compiler.objectClass))) {
672 return node.receiver;
673 }
674 }
682 HInstruction constant = tryComputeConstantInterceptor( 675 HInstruction constant = tryComputeConstantInterceptor(
683 node.inputs[0], node.interceptedClasses); 676 node.inputs[0], node.interceptedClasses);
684 if (constant == null) return node; 677 if (constant == null) return node;
678
685 return constant; 679 return constant;
686 } 680 }
687 681
688 HInstruction tryComputeConstantInterceptor(HInstruction input, 682 HInstruction tryComputeConstantInterceptor(HInstruction input,
689 Set<ClassElement> intercepted) { 683 Set<ClassElement> intercepted) {
690 HType type = input.instructionType; 684 HType type = input.instructionType;
691 ClassElement constantInterceptor; 685 ClassElement constantInterceptor;
692 if (type.isInteger()) { 686 if (type.isInteger()) {
693 constantInterceptor = backend.jsIntClass; 687 constantInterceptor = backend.jsIntClass;
694 } else if (type.isDouble()) { 688 } else if (type.isDouble()) {
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 HBasicBlock block = user.block; 1529 HBasicBlock block = user.block;
1536 block.addAfter(user, interceptor); 1530 block.addAfter(user, interceptor);
1537 block.rewrite(user, interceptor); 1531 block.rewrite(user, interceptor);
1538 block.remove(user); 1532 block.remove(user);
1539 1533
1540 // The interceptor will be removed in the dead code elimination 1534 // The interceptor will be removed in the dead code elimination
1541 // phase. Note that removing it here would not work because of how 1535 // phase. Note that removing it here would not work because of how
1542 // the [visitBasicBlock] is implemented. 1536 // the [visitBasicBlock] is implemented.
1543 } 1537 }
1544 } 1538 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698