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

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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 instruction: node); 1342 instruction: node);
1357 } 1343 }
1358 if (dominated.length == 2 && !identical(currentBlock, currentGraph.entry)) { 1344 if (dominated.length == 2 && !identical(currentBlock, currentGraph.entry)) {
1359 compiler.internalError('currentBlock !== currentGraph.entry', 1345 compiler.internalError('currentBlock !== currentGraph.entry',
1360 instruction: node); 1346 instruction: node);
1361 } 1347 }
1362 assert(dominated[0] == currentBlock.successors[0]); 1348 assert(dominated[0] == currentBlock.successors[0]);
1363 visitBasicBlock(dominated[0]); 1349 visitBasicBlock(dominated[0]);
1364 } 1350 }
1365 1351
1352 visitLoopBranch(HLoopBranch node) {
1353 assert(node.block == subGraph.end);
1354 // We are generating code for a loop condition.
1355 // If we are generating the subgraph as an expression, the
1356 // condition will be generated as the expression.
1357 // Otherwise, we don't generate the expression, and leave that
1358 // to the code that called [visitSubGraph].
1359 if (isGeneratingExpression) {
1360 use(node.inputs[0]);
1361 }
1362 }
1363
1366 /** 1364 /**
1367 * Checks if [map] contains an [ElementAction] for [element], and 1365 * Checks if [map] contains an [ElementAction] for [element], and
1368 * if so calls that action and returns true. 1366 * if so calls that action and returns true.
1369 * Otherwise returns false. 1367 * Otherwise returns false.
1370 */ 1368 */
1371 bool tryCallAction(Map<Element, ElementAction> map, Element element) { 1369 bool tryCallAction(Map<Element, ElementAction> map, Element element) {
1372 ElementAction action = map[element]; 1370 ElementAction action = map[element];
1373 if (action == null) return false; 1371 if (action == null) return false;
1374 action(element); 1372 action(element);
1375 return true; 1373 return true;
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 assert(isGenerateAtUseSite(node)); 1824 assert(isGenerateAtUseSite(node));
1827 generateConstant(node.constant); 1825 generateConstant(node.constant);
1828 DartType type = node.constant.computeType(compiler); 1826 DartType type = node.constant.computeType(compiler);
1829 if (node.constant is ConstructedConstant) { 1827 if (node.constant is ConstructedConstant) {
1830 ConstantHandler handler = compiler.constantHandler; 1828 ConstantHandler handler = compiler.constantHandler;
1831 handler.registerCompileTimeConstant(node.constant); 1829 handler.registerCompileTimeConstant(node.constant);
1832 } 1830 }
1833 world.registerInstantiatedClass(type.element); 1831 world.registerInstantiatedClass(type.element);
1834 } 1832 }
1835 1833
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) { 1834 visitNot(HNot node) {
1874 assert(node.inputs.length == 1); 1835 assert(node.inputs.length == 1);
1875 generateNot(node.inputs[0]); 1836 generateNot(node.inputs[0]);
1876 attachLocationToLast(node); 1837 attachLocationToLast(node);
1877 } 1838 }
1878 1839
1879 void generateNot(HInstruction input) { 1840 void generateNot(HInstruction input) {
1880 bool canGenerateOptimizedComparison(HInstruction instruction) { 1841 bool canGenerateOptimizedComparison(HInstruction instruction) {
1881 if (instruction is !HRelational) return false; 1842 if (instruction is !HRelational) return false;
1882 HRelational relational = instruction; 1843 HRelational relational = instruction;
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 pushStatement(new js.If.noElse(test, then), node); 2609 pushStatement(new js.If.noElse(test, then), node);
2649 } else { 2610 } else {
2650 compiler.internalError('Unexpected type guard', instruction: input); 2611 compiler.internalError('Unexpected type guard', instruction: input);
2651 } 2612 }
2652 } 2613 }
2653 2614
2654 void visitBailoutTarget(HBailoutTarget target) { 2615 void visitBailoutTarget(HBailoutTarget target) {
2655 // Do nothing. Bailout targets are only used in the non-optimized version. 2616 // Do nothing. Bailout targets are only used in the non-optimized version.
2656 } 2617 }
2657 2618
2658 void beginLoop(HBasicBlock block) {
2659 oldContainerStack.add(currentContainer);
2660 currentContainer = new js.Block.empty();
2661 }
2662
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) { 2619 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2686 } 2620 }
2687 2621
2688 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2622 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2689 } 2623 }
2690 2624
2691 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2625 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2692 } 2626 }
2693 } 2627 }
2694 2628
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 } 2722 }
2789 } 2723 }
2790 2724
2791 visitParameterValue(HParameterValue node) { 2725 visitParameterValue(HParameterValue node) {
2792 // Nothing to do, parameters are dealt with specially in a bailout 2726 // Nothing to do, parameters are dealt with specially in a bailout
2793 // method. 2727 // method.
2794 } 2728 }
2795 2729
2796 bool visitAndOrInfo(HAndOrBlockInformation info) => false; 2730 bool visitAndOrInfo(HAndOrBlockInformation info) => false;
2797 2731
2732 visitLoopBranch(HLoopBranch node) {
2733 HBasicBlock header = node.isDoWhile()
2734 ? node.block.successors[0]
2735 : node.block;
2736 if (header.hasBailoutTargets()) {
2737 // The graph visitor in [visitLoopInfo] does not handle the
2738 // condition. We must instead manually emit it here.
2739 handleLoopCondition(node);
2740 // We must also visit the body from here.
2741 // For a do while loop, the body has already been visited.
2742 if (!node.isDoWhile()) {
2743 visitBasicBlock(node.block.dominatedBlocks[0]);
2744 }
2745 } else {
2746 super.visitLoopBranch(node);
2747 }
2748 }
2749
2750
2798 bool visitIfInfo(HIfBlockInformation info) { 2751 bool visitIfInfo(HIfBlockInformation info) {
2799 if (info.thenGraph.start.hasBailoutTargets()) return false; 2752 if (info.thenGraph.start.hasBailoutTargets()) return false;
2800 if (info.elseGraph.start.hasBailoutTargets()) return false; 2753 if (info.elseGraph.start.hasBailoutTargets()) return false;
2801 return super.visitIfInfo(info); 2754 return super.visitIfInfo(info);
2802 } 2755 }
2803 2756
2804 bool visitLoopInfo(HLoopBlockInformation info) { 2757 bool visitLoopInfo(HLoopBlockInformation info) {
2805 if (info.start.hasBailoutTargets()) return false; 2758 // Always emit with block flow traversal.
2806 if (info.loopHeader.hasBailoutTargets()) return false; 2759 if (info.loopHeader.hasBailoutTargets()) {
2760 // If there are any bailout targets in the loop, we cannot use
2761 // the pretty [SsaCodeGenerator.visitLoopInfo] printer.
2762 if (info.initializer != null) {
2763 generateStatements(info.initializer);
2764 }
2765 beginLoop(info.loopHeader);
2766 generateStatements(info.condition);
2767 generateStatements(info.body);
2768 if (info.updates != null) {
2769 generateStatements(info.updates);
2770 }
2771 endLoop(info.end);
2772 return true;
2773 }
2807 return super.visitLoopInfo(info); 2774 return super.visitLoopInfo(info);
2808 } 2775 }
2809 2776
2810 bool visitTryInfo(HTryBlockInformation info) => false; 2777 bool visitTryInfo(HTryBlockInformation info) => false;
2811 bool visitSequenceInfo(HStatementSequenceInformation info) => false; 2778 bool visitSequenceInfo(HStatementSequenceInformation info) => false;
2812 2779
2813 void visitTypeGuard(HTypeGuard node) { 2780 void visitTypeGuard(HTypeGuard node) {
2814 // Do nothing. Type guards are only used in the optimized version. 2781 // Do nothing. Type guards are only used in the optimized version.
2815 } 2782 }
2816 2783
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 if (leftType.canBeNull() && rightType.canBeNull()) { 2995 if (leftType.canBeNull() && rightType.canBeNull()) {
3029 if (left.isConstantNull() || right.isConstantNull() || 2996 if (left.isConstantNull() || right.isConstantNull() ||
3030 (leftType.isPrimitive() && leftType == rightType)) { 2997 (leftType.isPrimitive() && leftType == rightType)) {
3031 return '=='; 2998 return '==';
3032 } 2999 }
3033 return null; 3000 return null;
3034 } else { 3001 } else {
3035 return '==='; 3002 return '===';
3036 } 3003 }
3037 } 3004 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/builder.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698