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

Unified 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, 11 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 17824)
+++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy)
@@ -337,10 +337,6 @@
beginGraph(HGraph graph);
endGraph(HGraph graph);
- beginLoop(HBasicBlock block);
- endLoop(HBasicBlock block);
- handleLoopCondition(HLoopBranch node);
-
preLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
startLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
endLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
@@ -959,11 +955,7 @@
assignPhisOfSuccessors(avoidEdge);
bool hasPhiUpdates = !updateBody.statements.isEmpty;
currentContainer = body;
- if (hasPhiUpdates || !isConditionExpression || info.updates != null) {
- wrapLoopBodyForContinue(info);
- } else {
- visitBodyIgnoreLabels(info);
- }
+ visitBodyIgnoreLabels(info);
if (info.updates != null) {
generateStatements(info.updates);
}
@@ -1125,15 +1117,9 @@
currentBlock = node;
// If this node has block-structure based information attached,
// try using that to traverse from here.
- if (node.blockFlow != null &&
- handleBlockFlow(node.blockFlow)) {
+ if (node.blockFlow != null && handleBlockFlow(node.blockFlow)) {
return;
}
- // Flow based traversal.
- if (node.isLoopHeader() &&
- !identical(node.loopInformation.loopBlockInformation, currentBlockInformation)) {
- beginLoop(node);
- }
iterateBasicBlock(node);
}
@@ -1363,6 +1349,18 @@
visitBasicBlock(dominated[0]);
}
+ visitLoopBranch(HLoopBranch node) {
+ assert(node.block == subGraph.end);
+ // We are generating code for a loop condition.
+ // If we are generating the subgraph as an expression, the
+ // condition will be generated as the expression.
+ // Otherwise, we don't generate the expression, and leave that
+ // to the code that called [visitSubGraph].
+ if (isGeneratingExpression) {
+ use(node.inputs[0]);
+ }
+ }
+
/**
* Checks if [map] contains an [ElementAction] for [element], and
* if so calls that action and returns true.
@@ -1833,43 +1831,6 @@
world.registerInstantiatedClass(type.element);
}
- visitLoopBranch(HLoopBranch node) {
- if (subGraph != null && identical(node.block, subGraph.end)) {
- // We are generating code for a loop condition.
- // If doing this as part of a SubGraph traversal, the
- // calling code will handle the control flow logic.
-
- // If we are generating the subgraph as an expression, the
- // condition will be generated as the expression.
- // Otherwise, we don't generate the expression, and leave that
- // to the code that called [visitSubGraph].
- if (isGeneratingExpression) {
- use(node.inputs[0]);
- }
- return;
- }
- HBasicBlock branchBlock = currentBlock;
- handleLoopCondition(node);
- List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
- if (!node.isDoWhile()) {
- // For a do while loop, the body has already been visited.
- visitBasicBlock(dominated[0]);
- }
- endLoop(node.block);
-
- // If the branch does not dominate the code after the loop, the
- // dominator will visit it.
- if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
-
- visitBasicBlock(branchBlock.successors[1]);
- // With labeled breaks we can have more dominated blocks.
- if (dominated.length >= 3) {
- for (int i = 2; i < dominated.length; i++) {
- visitBasicBlock(dominated[i]);
- }
- }
- }
-
visitNot(HNot node) {
assert(node.inputs.length == 1);
generateNot(node.inputs[0]);
@@ -2655,33 +2616,6 @@
// Do nothing. Bailout targets are only used in the non-optimized version.
}
- void beginLoop(HBasicBlock block) {
- oldContainerStack.add(currentContainer);
- currentContainer = new js.Block.empty();
- }
-
- void endLoop(HBasicBlock block) {
- js.Statement body = currentContainer;
- currentContainer = oldContainerStack.removeLast();
- body = unwrapStatement(body);
- js.While loop = new js.While(newLiteralBool(true), body);
-
- HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader;
- HLoopInformation info = header.loopInformation;
- attachLocationRange(loop,
- info.loopBlockInformation.sourcePosition,
- info.loopBlockInformation.endSourcePosition);
- pushStatement(wrapIntoLabels(loop, info.labels));
- }
-
- void handleLoopCondition(HLoopBranch node) {
- use(node.inputs[0]);
- js.Expression test = new js.Prefix('!', pop());
- js.Statement then = new js.Break(null);
- pushStatement(new js.If.noElse(test, then), node);
- }
-
-
void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
}
@@ -2795,6 +2729,25 @@
bool visitAndOrInfo(HAndOrBlockInformation info) => false;
+ visitLoopBranch(HLoopBranch node) {
+ HBasicBlock header = node.isDoWhile()
+ ? node.block.successors[0]
+ : node.block;
+ if (header.hasBailoutTargets()) {
+ // The graph visitor in [visitLoopInfo] does not handle the
+ // condition. We must instead manually emit it here.
+ handleLoopCondition(node);
+ // We must also visit the body from here.
+ // For a do while loop, the body has already been visited.
+ if (!node.isDoWhile()) {
+ visitBasicBlock(node.block.dominatedBlocks[0]);
+ }
+ } else {
+ super.visitLoopBranch(node);
+ }
+ }
+
+
bool visitIfInfo(HIfBlockInformation info) {
if (info.thenGraph.start.hasBailoutTargets()) return false;
if (info.elseGraph.start.hasBailoutTargets()) return false;
@@ -2802,8 +2755,22 @@
}
bool visitLoopInfo(HLoopBlockInformation info) {
- if (info.start.hasBailoutTargets()) return false;
- if (info.loopHeader.hasBailoutTargets()) return false;
+ // Always emit with block flow traversal.
+ if (info.loopHeader.hasBailoutTargets()) {
+ // If there are any bailout targets in the loop, we cannot use
+ // the pretty [SsaCodeGenerator.visitLoopInfo] printer.
+ if (info.initializer != null) {
+ generateStatements(info.initializer);
+ }
+ beginLoop(info.loopHeader);
+ generateStatements(info.condition);
+ generateStatements(info.body);
+ if (info.updates != null) {
+ generateStatements(info.updates);
+ }
+ endLoop(info.end);
+ return true;
+ }
return super.visitLoopInfo(info);
}
« 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