| OLD | NEW |
| 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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 } | 647 } |
| 648 } | 648 } |
| 649 | 649 |
| 650 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { | 650 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
| 651 final HTypeMap types; | 651 final HTypeMap types; |
| 652 final ConstantSystem constantSystem; | 652 final ConstantSystem constantSystem; |
| 653 final Set<HInstruction> boundsChecked; | 653 final Set<HInstruction> boundsChecked; |
| 654 final String name = "SsaCheckInserter"; | 654 final String name = "SsaCheckInserter"; |
| 655 HGraph graph; | 655 HGraph graph; |
| 656 Element lengthInterceptor; | 656 Element lengthInterceptor; |
| 657 Selector lengthSelector; |
| 657 | 658 |
| 658 SsaCheckInserter(JavaScriptBackend backend, this.types, this.boundsChecked) | 659 SsaCheckInserter(JavaScriptBackend backend, this.types, this.boundsChecked) |
| 659 : constantSystem = backend.constantSystem { | 660 : constantSystem = backend.constantSystem { |
| 660 SourceString lengthString = const SourceString('length'); | 661 SourceString lengthString = const SourceString('length'); |
| 662 lengthSelector = new Selector.getter( |
| 663 lengthString, |
| 664 backend.compiler.currentElement.getLibrary()); |
| 661 lengthInterceptor = | 665 lengthInterceptor = |
| 662 backend.builder.interceptors.getStaticGetInterceptor(lengthString); | 666 backend.builder.interceptors.getStaticInterceptor(lengthSelector); |
| 663 } | 667 } |
| 664 | 668 |
| 665 void visitGraph(HGraph graph) { | 669 void visitGraph(HGraph graph) { |
| 666 this.graph = graph; | 670 this.graph = graph; |
| 667 visitDominatorTree(graph); | 671 visitDominatorTree(graph); |
| 668 } | 672 } |
| 669 | 673 |
| 670 void visitBasicBlock(HBasicBlock block) { | 674 void visitBasicBlock(HBasicBlock block) { |
| 671 HInstruction instruction = block.first; | 675 HInstruction instruction = block.first; |
| 672 while (instruction != null) { | 676 while (instruction != null) { |
| 673 HInstruction next = instruction.next; | 677 HInstruction next = instruction.next; |
| 674 instruction = instruction.accept(this); | 678 instruction = instruction.accept(this); |
| 675 instruction = next; | 679 instruction = next; |
| 676 } | 680 } |
| 677 } | 681 } |
| 678 | 682 |
| 679 HBoundsCheck insertBoundsCheck(HInstruction node, | 683 HBoundsCheck insertBoundsCheck(HInstruction node, |
| 680 HInstruction receiver, | 684 HInstruction receiver, |
| 681 HInstruction index) { | 685 HInstruction index) { |
| 682 HStatic interceptor = new HStatic(lengthInterceptor); | 686 HStatic interceptor = new HStatic(lengthInterceptor); |
| 683 node.block.addBefore(node, interceptor); | 687 node.block.addBefore(node, interceptor); |
| 684 Selector selector = new Selector.getter( | |
| 685 const SourceString('length'), | |
| 686 lengthInterceptor.getLibrary()); // TODO(kasperl): Wrong. | |
| 687 HInvokeInterceptor length = new HInvokeInterceptor( | 688 HInvokeInterceptor length = new HInvokeInterceptor( |
| 688 selector, <HInstruction>[interceptor, receiver], true); | 689 lengthSelector, <HInstruction>[interceptor, receiver], true); |
| 689 types[length] = HType.INTEGER; | 690 types[length] = HType.INTEGER; |
| 690 node.block.addBefore(node, length); | 691 node.block.addBefore(node, length); |
| 691 | 692 |
| 692 HBoundsCheck check = new HBoundsCheck(index, length); | 693 HBoundsCheck check = new HBoundsCheck(index, length); |
| 693 node.block.addBefore(node, check); | 694 node.block.addBefore(node, check); |
| 694 boundsChecked.add(node); | 695 boundsChecked.add(node); |
| 695 return check; | 696 return check; |
| 696 } | 697 } |
| 697 | 698 |
| 698 HIntegerCheck insertIntegerCheck(HInstruction node, HInstruction value) { | 699 HIntegerCheck insertIntegerCheck(HInstruction node, HInstruction value) { |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 } | 1351 } |
| 1351 | 1352 |
| 1352 // For other fields having setters in the generative constructor body, set | 1353 // For other fields having setters in the generative constructor body, set |
| 1353 // the type to UNKNOWN to avoid relying on the type set in the initializer | 1354 // the type to UNKNOWN to avoid relying on the type set in the initializer |
| 1354 // list. | 1355 // list. |
| 1355 allSetters.forEach((Element element) { | 1356 allSetters.forEach((Element element) { |
| 1356 backend.registerFieldConstructor(element, HType.UNKNOWN); | 1357 backend.registerFieldConstructor(element, HType.UNKNOWN); |
| 1357 }); | 1358 }); |
| 1358 } | 1359 } |
| 1359 } | 1360 } |
| OLD | NEW |