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 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 5612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5623 add(result); | 5623 add(result); |
5624 return result; | 5624 return result; |
5625 } | 5625 } |
5626 | 5626 |
5627 void buildConcurrentModificationErrorCheck() { | 5627 void buildConcurrentModificationErrorCheck() { |
5628 if (originalLength == null) return; | 5628 if (originalLength == null) return; |
5629 // Generate shortcircuit expression: | 5629 // Generate shortcircuit expression: |
5630 // | 5630 // |
5631 // array.length == _end || throwConcurrentModificationError(array) | 5631 // array.length == _end || throwConcurrentModificationError(array) |
5632 // | 5632 // |
5633 /* | |
5633 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); | 5634 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
5634 branchBuilder.handleLogicalAndOr( | 5635 branchBuilder.handleLogicalAndOr( |
5635 () { | 5636 () { |
5636 HInstruction length = buildGetLength(); | 5637 HInstruction length = buildGetLength(); |
5637 push(new HIdentity(length, originalLength, null, boolType)); | 5638 push(new HIdentity(length, originalLength, null, boolType)); |
5638 }, | 5639 }, |
5639 () { | 5640 () { |
5640 pushInvokeStatic(node, | 5641 pushInvokeStatic(node, |
5641 backend.getThrowConcurrentModificationError(), | 5642 backend.getThrowConcurrentModificationError(), |
5642 [array]); | 5643 [array]); |
5643 }, | 5644 }, |
5644 isAnd: false); | 5645 isAnd: false); |
5645 pop(); | 5646 pop(); |
5647 */ | |
5648 HInstruction length = buildGetLength(); | |
5649 push(new HIdentity(length, originalLength, null, boolType)); | |
5650 pushInvokeStatic(node, | |
5651 backend.getThrowConcurrentModificationError(), | |
5652 [pop(), array]); | |
5653 pop(); | |
5646 } | 5654 } |
5647 | 5655 |
5648 void buildInitializer() { | 5656 void buildInitializer() { |
5649 visit(node.expression); | 5657 visit(node.expression); |
5650 array = pop(); | 5658 array = pop(); |
5651 isFixed = isFixedLength(array.instructionType, compiler); | 5659 isFixed = isFixedLength(array.instructionType, compiler); |
5652 localsHandler.updateLocal(indexVariable, | 5660 localsHandler.updateLocal(indexVariable, |
5653 graph.addConstantInt(0, compiler)); | 5661 graph.addConstantInt(0, compiler)); |
5654 if (!isFixed) { | 5662 //if (!isFixed) { |
sra1
2015/04/16 19:27:09
This will be changed back, was just for debugging
| |
5655 originalLength = buildGetLength(); | 5663 originalLength = buildGetLength(); |
5656 } | 5664 //} |
5657 } | 5665 } |
5658 | 5666 |
5659 HInstruction buildCondition() { | 5667 HInstruction buildCondition() { |
5660 HInstruction index = localsHandler.readLocal(indexVariable); | 5668 HInstruction index = localsHandler.readLocal(indexVariable); |
5661 HInstruction length = buildGetLength(); | 5669 HInstruction length = buildGetLength(); |
5662 HInstruction compare = new HLess(index, length, null, boolType); | 5670 HInstruction compare = new HLess(index, length, null, boolType); |
5663 add(compare); | 5671 add(compare); |
5664 return compare; | 5672 return compare; |
5665 } | 5673 } |
5666 | 5674 |
5667 void buildBody() { | 5675 void buildBody() { |
5668 // If we had inlined ArrayIterator.moveNext(), it would have done the | 5676 // If we had inlined ArrayIterator.moveNext(), it would have done the |
5669 // ConcurrentModificationError check as part of the condition. Putting | 5677 // ConcurrentModificationError check as part of the condition. Putting |
5670 // the check in the condition or in the update generates terrible code | 5678 // the check in the condition or in the update generates terrible code |
5671 // because we don't manage to reconstruct the short-circuit expression | 5679 // because we don't manage to reconstruct the short-circuit expression |
5672 // which forces the for(;;) to be generated as a while loop. | 5680 // which forces the for(;;) to be generated as a while loop. |
5673 // | 5681 // |
5674 // For now we will put the check in the body, which will miss a | 5682 // For now we will put the check in the body, which will miss a |
5675 // modification on the last iteration. | 5683 // modification on the last iteration. |
5676 buildConcurrentModificationErrorCheck(); | 5684 //buildConcurrentModificationErrorCheck(); |
5677 | 5685 |
5678 // Find a type for the element. | 5686 // Find a type for the element. |
5679 // Use the element type of the indexer into the array. | 5687 // Use the element type of the indexer into the array. |
5680 // TODO(sra): The array type can be better, e.g. a container type. | 5688 // TODO(sra): The array type can be better, e.g. a container type. |
5681 | 5689 |
5682 Selector selector = new Selector.index(); | 5690 Selector selector = new Selector.index(); |
5683 Selector refined = new TypedSelector(arrayType, selector, compiler.world); | 5691 Selector refined = new TypedSelector(arrayType, selector, compiler.world); |
5684 TypeMask type = | 5692 TypeMask type = |
5685 TypeMaskFactory.inferredTypeForSelector(refined, compiler); | 5693 TypeMaskFactory.inferredTypeForSelector(refined, compiler); |
5686 | 5694 |
(...skipping 19 matching lines...) Expand all Loading... | |
5706 location: identifier); | 5714 location: identifier); |
5707 } else { | 5715 } else { |
5708 generateNonInstanceSetter( | 5716 generateNonInstanceSetter( |
5709 null, loopVariable, value, location: identifier); | 5717 null, loopVariable, value, location: identifier); |
5710 } | 5718 } |
5711 pop(); // Pop the value pushed by the setter call. | 5719 pop(); // Pop the value pushed by the setter call. |
5712 | 5720 |
5713 visit(node.body); | 5721 visit(node.body); |
5714 } | 5722 } |
5715 void buildUpdate() { | 5723 void buildUpdate() { |
5724 buildConcurrentModificationErrorCheck(); | |
5716 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the | 5725 // TODO(sra): It would be slightly shorter to generate `a[i++]` in the |
5717 // body (and that more closely follows what an inlined iterator would do) | 5726 // body (and that more closely follows what an inlined iterator would do) |
5718 // but the code is horrible as `i+1` is carried around the loop in an | 5727 // but the code is horrible as `i+1` is carried around the loop in an |
5719 // additional variable. | 5728 // additional variable. |
5720 HInstruction index = localsHandler.readLocal(indexVariable); | 5729 HInstruction index = localsHandler.readLocal(indexVariable); |
5721 HInstruction one = graph.addConstantInt(1, compiler); | 5730 HInstruction one = graph.addConstantInt(1, compiler); |
5722 HInstruction addInstruction = | 5731 HInstruction addInstruction = |
5723 new HAdd(index, one, null, backend.positiveIntType); | 5732 new HAdd(index, one, null, backend.positiveIntType); |
5724 add(addInstruction); | 5733 add(addInstruction); |
5725 localsHandler.updateLocal(indexVariable, addInstruction); | 5734 localsHandler.updateLocal(indexVariable, addInstruction); |
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7156 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7165 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
7157 unaliased.accept(this, builder); | 7166 unaliased.accept(this, builder); |
7158 } | 7167 } |
7159 | 7168 |
7160 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7169 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
7161 JavaScriptBackend backend = builder.compiler.backend; | 7170 JavaScriptBackend backend = builder.compiler.backend; |
7162 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7171 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
7163 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7172 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
7164 } | 7173 } |
7165 } | 7174 } |
OLD | NEW |