| 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 interface OptimizationPhase { | 5 interface OptimizationPhase { |
| 6 String get name(); | 6 String get name(); |
| 7 void visitGraph(HGraph graph); | 7 void visitGraph(HGraph graph); |
| 8 } | 8 } |
| 9 | 9 |
| 10 class SsaOptimizerTask extends CompilerTask { | 10 class SsaOptimizerTask extends CompilerTask { |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 HInstruction value = node.inputs[0]; | 560 HInstruction value = node.inputs[0]; |
| 561 Type type = types[node].computeType(compiler); | 561 Type type = types[node].computeType(compiler); |
| 562 if (type.element === compiler.dynamicClass | 562 if (type.element === compiler.dynamicClass |
| 563 || type.element === compiler.objectClass) { | 563 || type.element === compiler.objectClass) { |
| 564 return value; | 564 return value; |
| 565 } | 565 } |
| 566 HType combinedType = types[value].intersection(types[node]); | 566 HType combinedType = types[value].intersection(types[node]); |
| 567 return (combinedType == types[value]) ? value : node; | 567 return (combinedType == types[value]) ? value : node; |
| 568 } | 568 } |
| 569 | 569 |
| 570 Element findConcreteFieldForDynamicAccess(HInstruction receiver, |
| 571 Selector selector) { |
| 572 HType receiverType = types[receiver]; |
| 573 if (!receiverType.isUseful()) return null; |
| 574 if (receiverType.canBeNull()) return null; |
| 575 Type type = receiverType.computeType(compiler); |
| 576 if (type === null) return null; |
| 577 return compiler.world.locateSingleField(type, selector); |
| 578 } |
| 579 |
| 570 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 580 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 571 HInstruction receiver = node.inputs[0]; | 581 Element field = |
| 572 HType receiverType = types[receiver]; | 582 findConcreteFieldForDynamicAccess(node.receiver, node.selector); |
| 573 if (!receiverType.isUseful()) return node; | 583 if (field == null) return node; |
| 574 if (receiverType.canBeNull()) return node; | 584 |
| 575 Type type = receiverType.computeType(compiler); | |
| 576 if (type === null) return node; | |
| 577 Element field = compiler.world.locateSingleField(type, node.name); | |
| 578 if (field === null) return node; | |
| 579 if (node.name.isPrivate() && | |
| 580 field.getLibrary() !== work.element.getLibrary()) { | |
| 581 return node; | |
| 582 } | |
| 583 Modifiers modifiers = field.modifiers; | 585 Modifiers modifiers = field.modifiers; |
| 584 bool isFinalOrConst = false; | 586 bool isFinalOrConst = false; |
| 585 if (modifiers != null) { | 587 if (modifiers != null) { |
| 586 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); | 588 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); |
| 587 } | 589 } |
| 588 if (!compiler.resolverWorld.hasInvokedSetter(field, compiler)) { | 590 if (!compiler.resolverWorld.hasInvokedSetter(field, compiler)) { |
| 589 // If no setter is ever used for this field it is only initialized in the | 591 // If no setter is ever used for this field it is only initialized in the |
| 590 // initializer list. | 592 // initializer list. |
| 591 isFinalOrConst = true; | 593 isFinalOrConst = true; |
| 592 } | 594 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 604 // un-initialized or initialized in the constructor initializer list. | 606 // un-initialized or initialized in the constructor initializer list. |
| 605 isFinalOrConst = true; | 607 isFinalOrConst = true; |
| 606 break; | 608 break; |
| 607 } | 609 } |
| 608 } | 610 } |
| 609 return new HFieldGet.withElement( | 611 return new HFieldGet.withElement( |
| 610 field, node.inputs[0], isFinalOrConst: isFinalOrConst); | 612 field, node.inputs[0], isFinalOrConst: isFinalOrConst); |
| 611 } | 613 } |
| 612 | 614 |
| 613 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 615 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 614 HInstruction receiver = node.inputs[0]; | 616 Element field = |
| 615 HType receiverType = types[receiver]; | 617 findConcreteFieldForDynamicAccess(node.receiver, node.selector); |
| 616 if (!receiverType.isUseful()) return node; | |
| 617 if (receiverType.canBeNull()) return node; | |
| 618 Type type = receiverType.computeType(compiler); | |
| 619 if (type === null) return node; | |
| 620 Element field = compiler.world.locateSingleField(type, node.name); | |
| 621 if (field === null) return node; | 618 if (field === null) return node; |
| 622 return new HFieldSet.withElement(field, node.inputs[0], node.inputs[1]); | 619 return new HFieldSet.withElement(field, node.inputs[0], node.inputs[1]); |
| 623 } | 620 } |
| 624 | 621 |
| 625 HInstruction visitStringConcat(HStringConcat node) { | 622 HInstruction visitStringConcat(HStringConcat node) { |
| 626 DartString folded = const LiteralDartString(""); | 623 DartString folded = const LiteralDartString(""); |
| 627 for (int i = 0; i < node.inputs.length; i++) { | 624 for (int i = 0; i < node.inputs.length; i++) { |
| 628 HInstruction part = node.inputs[i]; | 625 HInstruction part = node.inputs[i]; |
| 629 if (!part.isConstant()) return node; | 626 if (!part.isConstant()) return node; |
| 630 HConstant constant = part; | 627 HConstant constant = part; |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 // this type for the field is still a strong signal | 1330 // this type for the field is still a strong signal |
| 1334 // indicating the expected type of the field. | 1331 // indicating the expected type of the field. |
| 1335 types[field] = type; | 1332 types[field] = type; |
| 1336 } else { | 1333 } else { |
| 1337 // If there are no invoked setters we know the type of | 1334 // If there are no invoked setters we know the type of |
| 1338 // this field for sure. | 1335 // this field for sure. |
| 1339 field.guaranteedType = type; | 1336 field.guaranteedType = type; |
| 1340 } | 1337 } |
| 1341 } | 1338 } |
| 1342 } | 1339 } |
| OLD | NEW |