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

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

Issue 12082054: Fix crash in compiler when we are generating a bailout method where a loop contains continue/break/… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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
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 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 jsNode.endSourcePosition = endSourcePosition; 330 jsNode.endSourcePosition = endSourcePosition;
331 return jsNode; 331 return jsNode;
332 } 332 }
333 333
334 visitTypeGuard(HTypeGuard node); 334 visitTypeGuard(HTypeGuard node);
335 visitBailoutTarget(HBailoutTarget node); 335 visitBailoutTarget(HBailoutTarget node);
336 336
337 beginGraph(HGraph graph); 337 beginGraph(HGraph graph);
338 endGraph(HGraph graph); 338 endGraph(HGraph graph);
339 339
340 beginLoop(HBasicBlock block);
341 endLoop(HBasicBlock block);
342 handleLoopCondition(HLoopBranch node);
343
344 preLabeledBlock(HLabeledBlockInformation labeledBlockInfo); 340 preLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
345 startLabeledBlock(HLabeledBlockInformation labeledBlockInfo); 341 startLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
346 endLabeledBlock(HLabeledBlockInformation labeledBlockInfo); 342 endLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
347 343
348 void preGenerateMethod(HGraph graph) { 344 void preGenerateMethod(HGraph graph) {
349 new SsaInstructionMerger(types, generateAtUseSite).visitGraph(graph); 345 new SsaInstructionMerger(types, generateAtUseSite).visitGraph(graph);
350 new SsaConditionMerger( 346 new SsaConditionMerger(
351 types, generateAtUseSite, controlFlowOperators).visitGraph(graph); 347 types, generateAtUseSite, controlFlowOperators).visitGraph(graph);
352 SsaLiveIntervalBuilder intervalBuilder = 348 SsaLiveIntervalBuilder intervalBuilder =
353 new SsaLiveIntervalBuilder(compiler, generateAtUseSite); 349 new SsaLiveIntervalBuilder(compiler, generateAtUseSite);
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 // } else { 948 // } else {
953 // break; 949 // break;
954 // } 950 // }
955 // } while (true); 951 // } while (true);
956 HBasicBlock avoidEdge = info.end.successors[0]; 952 HBasicBlock avoidEdge = info.end.successors[0];
957 js.Block updateBody = new js.Block.empty(); 953 js.Block updateBody = new js.Block.empty();
958 currentContainer = updateBody; 954 currentContainer = updateBody;
959 assignPhisOfSuccessors(avoidEdge); 955 assignPhisOfSuccessors(avoidEdge);
960 bool hasPhiUpdates = !updateBody.statements.isEmpty; 956 bool hasPhiUpdates = !updateBody.statements.isEmpty;
961 currentContainer = body; 957 currentContainer = body;
962 if (hasPhiUpdates || !isConditionExpression || info.updates != null) { 958 visitBodyIgnoreLabels(info);
963 wrapLoopBodyForContinue(info);
964 } else {
965 visitBodyIgnoreLabels(info);
966 }
967 if (info.updates != null) { 959 if (info.updates != null) {
968 generateStatements(info.updates); 960 generateStatements(info.updates);
969 } 961 }
970 if (isConditionExpression) { 962 if (isConditionExpression) {
971 push(generateExpression(condition)); 963 push(generateExpression(condition));
972 } else { 964 } else {
973 generateStatements(condition); 965 generateStatements(condition);
974 use(condition.conditionExpression); 966 use(condition.conditionExpression);
975 } 967 }
976 js.Expression jsCondition = pop(); 968 js.Expression jsCondition = pop();
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 return success; 1110 return success;
1119 } 1111 }
1120 1112
1121 void visitBasicBlock(HBasicBlock node) { 1113 void visitBasicBlock(HBasicBlock node) {
1122 // Abort traversal if we are leaving the currently active sub-graph. 1114 // Abort traversal if we are leaving the currently active sub-graph.
1123 if (!subGraph.contains(node)) return; 1115 if (!subGraph.contains(node)) return;
1124 1116
1125 currentBlock = node; 1117 currentBlock = node;
1126 // If this node has block-structure based information attached, 1118 // If this node has block-structure based information attached,
1127 // try using that to traverse from here. 1119 // try using that to traverse from here.
1128 if (node.blockFlow != null && 1120 if (node.blockFlow != null && handleBlockFlow(node.blockFlow)) {
1129 handleBlockFlow(node.blockFlow)) {
1130 return; 1121 return;
1131 } 1122 }
1132 // Flow based traversal.
1133 if (node.isLoopHeader() &&
1134 !identical(node.loopInformation.loopBlockInformation, currentBlockInform ation)) {
1135 beginLoop(node);
1136 }
1137 iterateBasicBlock(node); 1123 iterateBasicBlock(node);
1138 } 1124 }
1139 1125
1140 void emitAssignment(String destination, String source) { 1126 void emitAssignment(String destination, String source) {
1141 assignVariable(destination, new js.VariableUse(source)); 1127 assignVariable(destination, new js.VariableUse(source));
1142 } 1128 }
1143 1129
1144 /** 1130 /**
1145 * Sequentialize a list of conceptually parallel copies. Parallel 1131 * Sequentialize a list of conceptually parallel copies. Parallel
1146 * copies may contain cycles, that this method breaks. 1132 * copies may contain cycles, that this method breaks.
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 assert(isGenerateAtUseSite(node)); 1812 assert(isGenerateAtUseSite(node));
1827 generateConstant(node.constant); 1813 generateConstant(node.constant);
1828 DartType type = node.constant.computeType(compiler); 1814 DartType type = node.constant.computeType(compiler);
1829 if (node.constant is ConstructedConstant) { 1815 if (node.constant is ConstructedConstant) {
1830 ConstantHandler handler = compiler.constantHandler; 1816 ConstantHandler handler = compiler.constantHandler;
1831 handler.registerCompileTimeConstant(node.constant); 1817 handler.registerCompileTimeConstant(node.constant);
1832 } 1818 }
1833 world.registerInstantiatedClass(type.element); 1819 world.registerInstantiatedClass(type.element);
1834 } 1820 }
1835 1821
1836 visitLoopBranch(HLoopBranch node) {
1837 if (subGraph != null && identical(node.block, subGraph.end)) {
1838 // We are generating code for a loop condition.
1839 // If doing this as part of a SubGraph traversal, the
1840 // calling code will handle the control flow logic.
1841
1842 // If we are generating the subgraph as an expression, the
1843 // condition will be generated as the expression.
1844 // Otherwise, we don't generate the expression, and leave that
1845 // to the code that called [visitSubGraph].
1846 if (isGeneratingExpression) {
1847 use(node.inputs[0]);
1848 }
1849 return;
1850 }
1851 HBasicBlock branchBlock = currentBlock;
1852 handleLoopCondition(node);
1853 List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
1854 if (!node.isDoWhile()) {
1855 // For a do while loop, the body has already been visited.
1856 visitBasicBlock(dominated[0]);
1857 }
1858 endLoop(node.block);
1859
1860 // If the branch does not dominate the code after the loop, the
1861 // dominator will visit it.
1862 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
1863
1864 visitBasicBlock(branchBlock.successors[1]);
1865 // With labeled breaks we can have more dominated blocks.
1866 if (dominated.length >= 3) {
1867 for (int i = 2; i < dominated.length; i++) {
1868 visitBasicBlock(dominated[i]);
1869 }
1870 }
1871 }
1872
1873 visitNot(HNot node) { 1822 visitNot(HNot node) {
1874 assert(node.inputs.length == 1); 1823 assert(node.inputs.length == 1);
1875 generateNot(node.inputs[0]); 1824 generateNot(node.inputs[0]);
1876 attachLocationToLast(node); 1825 attachLocationToLast(node);
1877 } 1826 }
1878 1827
1879 void generateNot(HInstruction input) { 1828 void generateNot(HInstruction input) {
1880 bool canGenerateOptimizedComparison(HInstruction instruction) { 1829 bool canGenerateOptimizedComparison(HInstruction instruction) {
1881 if (instruction is !HRelational) return false; 1830 if (instruction is !HRelational) return false;
1882 HRelational relational = instruction; 1831 HRelational relational = instruction;
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 pushStatement(new js.If.noElse(test, then), node); 2597 pushStatement(new js.If.noElse(test, then), node);
2649 } else { 2598 } else {
2650 compiler.internalError('Unexpected type guard', instruction: input); 2599 compiler.internalError('Unexpected type guard', instruction: input);
2651 } 2600 }
2652 } 2601 }
2653 2602
2654 void visitBailoutTarget(HBailoutTarget target) { 2603 void visitBailoutTarget(HBailoutTarget target) {
2655 // Do nothing. Bailout targets are only used in the non-optimized version. 2604 // Do nothing. Bailout targets are only used in the non-optimized version.
2656 } 2605 }
2657 2606
2658 void beginLoop(HBasicBlock block) { 2607 visitLoopBranch(HLoopBranch node) {
2659 oldContainerStack.add(currentContainer); 2608 if (node.block == subGraph.end) {
2660 currentContainer = new js.Block.empty(); 2609 // We are generating code for a loop condition.
2610 // If we are generating the subgraph as an expression, the
2611 // condition will be generated as the expression.
2612 // Otherwise, we don't generate the expression, and leave that
2613 // to the code that called [visitSubGraph].
2614 if (isGeneratingExpression) {
2615 use(node.inputs[0]);
2616 }
2617 return;
2618 }
2619 if (!node.isDoWhile()) {
2620 // For a do while loop, the body has already been visited.
2621 visitBasicBlock(node.block.dominatedBlocks[0]);
2622 }
2623 // The exit block will be visited by the subgraph traversal.
2661 } 2624 }
2662 2625
2663 void endLoop(HBasicBlock block) {
2664 js.Statement body = currentContainer;
2665 currentContainer = oldContainerStack.removeLast();
2666 body = unwrapStatement(body);
2667 js.While loop = new js.While(newLiteralBool(true), body);
2668
2669 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader;
2670 HLoopInformation info = header.loopInformation;
2671 attachLocationRange(loop,
2672 info.loopBlockInformation.sourcePosition,
2673 info.loopBlockInformation.endSourcePosition);
2674 pushStatement(wrapIntoLabels(loop, info.labels));
2675 }
2676
2677 void handleLoopCondition(HLoopBranch node) {
2678 use(node.inputs[0]);
2679 js.Expression test = new js.Prefix('!', pop());
2680 js.Statement then = new js.Break(null);
2681 pushStatement(new js.If.noElse(test, then), node);
2682 }
2683
2684
2685 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2626 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2686 } 2627 }
2687 2628
2688 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2629 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2689 } 2630 }
2690 2631
2691 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2632 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2692 } 2633 }
2693 } 2634 }
2694 2635
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 } 2729 }
2789 } 2730 }
2790 2731
2791 visitParameterValue(HParameterValue node) { 2732 visitParameterValue(HParameterValue node) {
2792 // Nothing to do, parameters are dealt with specially in a bailout 2733 // Nothing to do, parameters are dealt with specially in a bailout
2793 // method. 2734 // method.
2794 } 2735 }
2795 2736
2796 bool visitAndOrInfo(HAndOrBlockInformation info) => false; 2737 bool visitAndOrInfo(HAndOrBlockInformation info) => false;
2797 2738
2739
2740 visitLoopBranch(HLoopBranch node) {
2741 HBasicBlock header = node.isDoWhile()
2742 ? node.block.successors[0]
2743 : node.block;
2744 if (header.hasBailoutTargets()) {
2745 // The graph visitor in [visitLoopInfo] does not handle the
2746 // condition. We must instead manually emit it here.
2747 handleLoopCondition(node);
2748 } else if (node.block == subGraph.end) {
kasperl 2013/01/29 18:35:04 Share this code with the equivalent code above?
ngeoffray 2013/01/30 09:58:53 Actually I was able to cleanup both visitLoopBranc
2749 // We are generating code for a loop condition as part
2750 // of a SubGraph traversal, the
kasperl 2013/01/29 18:35:04 Reflow comment. SubGraph -> subgraph?
ngeoffray 2013/01/30 09:58:53 Done.
2751 // calling code will handle the control flow logic.
2752
2753 // If we are generating the subgraph as an expression, the
2754 // condition will be generated as the expression.
2755 // Otherwise, we don't generate the expression, and leave that
2756 // to the code that called [visitSubGraph].
2757 if (isGeneratingExpression) {
2758 use(node.inputs[0]);
2759 }
2760 return;
2761 }
2762 if (!node.isDoWhile()) {
2763 // For a do while loop, the body has already been visited.
2764 visitBasicBlock(node.block.dominatedBlocks[0]);
2765 }
2766 }
2767
2768
2798 bool visitIfInfo(HIfBlockInformation info) { 2769 bool visitIfInfo(HIfBlockInformation info) {
2799 if (info.thenGraph.start.hasBailoutTargets()) return false; 2770 if (info.thenGraph.start.hasBailoutTargets()) return false;
2800 if (info.elseGraph.start.hasBailoutTargets()) return false; 2771 if (info.elseGraph.start.hasBailoutTargets()) return false;
2801 return super.visitIfInfo(info); 2772 return super.visitIfInfo(info);
2802 } 2773 }
2803 2774
2804 bool visitLoopInfo(HLoopBlockInformation info) { 2775 bool visitLoopInfo(HLoopBlockInformation info) {
2805 if (info.start.hasBailoutTargets()) return false; 2776 // Always emit with block flow traversal.
2806 if (info.loopHeader.hasBailoutTargets()) return false; 2777 if (info.loopHeader.hasBailoutTargets()) {
2778 // If there are any bailout targets in the loop, we cannot use
2779 // the pretty [SsaCodeGenerator.visitLoopInfo] printer.
2780 if (info.initializer != null) {
2781 generateStatements(info.initializer);
2782 }
2783 beginLoop(info.loopHeader);
2784 generateStatements(info.condition);
2785 generateStatements(info.body);
2786 if (info.updates != null) {
2787 generateStatements(info.updates);
2788 }
2789 endLoop(info.end);
2790 return true;
2791 }
2807 return super.visitLoopInfo(info); 2792 return super.visitLoopInfo(info);
2808 } 2793 }
2809 2794
2810 bool visitTryInfo(HTryBlockInformation info) => false; 2795 bool visitTryInfo(HTryBlockInformation info) => false;
2811 bool visitSequenceInfo(HStatementSequenceInformation info) => false; 2796 bool visitSequenceInfo(HStatementSequenceInformation info) => false;
2812 2797
2813 void visitTypeGuard(HTypeGuard node) { 2798 void visitTypeGuard(HTypeGuard node) {
2814 // Do nothing. Type guards are only used in the optimized version. 2799 // Do nothing. Type guards are only used in the optimized version.
2815 } 2800 }
2816 2801
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 if (leftType.canBeNull() && rightType.canBeNull()) { 3013 if (leftType.canBeNull() && rightType.canBeNull()) {
3029 if (left.isConstantNull() || right.isConstantNull() || 3014 if (left.isConstantNull() || right.isConstantNull() ||
3030 (leftType.isPrimitive() && leftType == rightType)) { 3015 (leftType.isPrimitive() && leftType == rightType)) {
3031 return '=='; 3016 return '==';
3032 } 3017 }
3033 return null; 3018 return null;
3034 } else { 3019 } else {
3035 return '==='; 3020 return '===';
3036 } 3021 }
3037 } 3022 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/builder.dart ('k') | tests/language/bailout5_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698