Chromium Code Reviews| 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 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 4652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4663 JumpHandler jumpHandler, | 4663 JumpHandler jumpHandler, |
| 4664 HInstruction buildExpression(), | 4664 HInstruction buildExpression(), |
| 4665 var switchCases, | 4665 var switchCases, |
| 4666 Iterable<Constant> getConstants(SwitchCase switchCase), | 4666 Iterable<Constant> getConstants(SwitchCase switchCase), |
| 4667 bool isDefaultCase(SwitchCase switchCase), | 4667 bool isDefaultCase(SwitchCase switchCase), |
| 4668 void buildSwitchCase(SwitchCase switchCase)) { | 4668 void buildSwitchCase(SwitchCase switchCase)) { |
| 4669 Map<CaseMatch, Constant> constants = new Map<CaseMatch, Constant>(); | 4669 Map<CaseMatch, Constant> constants = new Map<CaseMatch, Constant>(); |
| 4670 | 4670 |
| 4671 // TODO(ngeoffray): Handle switch-instruction in bailout code. | 4671 // TODO(ngeoffray): Handle switch-instruction in bailout code. |
| 4672 work.allowSpeculativeOptimization = false; | 4672 work.allowSpeculativeOptimization = false; |
| 4673 // Then build a switch structure. | |
| 4674 HBasicBlock expressionStart = openNewBlock(); | 4673 HBasicBlock expressionStart = openNewBlock(); |
| 4675 HInstruction expression = buildExpression(); | 4674 HInstruction expression = buildExpression(); |
| 4676 if (switchCases.isEmpty) { | 4675 if (switchCases.isEmpty) { |
| 4677 return; | 4676 return; |
| 4678 } | 4677 } |
| 4679 HBasicBlock expressionEnd = current; | |
| 4680 | 4678 |
| 4681 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); | 4679 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); |
| 4682 HBasicBlock expressionBlock = close(switchInstruction); | 4680 HBasicBlock expressionEnd = close(switchInstruction); |
| 4683 LocalsHandler savedLocals = localsHandler; | 4681 LocalsHandler savedLocals = localsHandler; |
| 4684 | 4682 |
| 4685 List<List<Constant>> matchExpressions = <List<Constant>>[]; | 4683 List<List<Constant>> matchExpressions = <List<Constant>>[]; |
| 4686 List<HStatementInformation> statements = <HStatementInformation>[]; | 4684 List<HStatementInformation> statements = <HStatementInformation>[]; |
| 4687 bool hasDefault = false; | 4685 bool hasDefault = false; |
| 4688 Element getFallThroughErrorElement = backend.getFallThroughError(); | 4686 Element getFallThroughErrorElement = backend.getFallThroughError(); |
| 4689 HasNextIterator<Node> caseIterator = | 4687 HasNextIterator<Node> caseIterator = |
| 4690 new HasNextIterator<Node>(switchCases.iterator); | 4688 new HasNextIterator<Node>(switchCases.iterator); |
| 4691 while (caseIterator.hasNext) { | 4689 while (caseIterator.hasNext) { |
| 4692 SwitchCase switchCase = caseIterator.next(); | 4690 SwitchCase switchCase = caseIterator.next(); |
| 4693 List<Constant> caseConstants = <Constant>[]; | 4691 List<Constant> caseConstants = <Constant>[]; |
| 4694 HBasicBlock block = graph.addNewBlock(); | 4692 HBasicBlock block = graph.addNewBlock(); |
| 4695 for (Constant constant in getConstants(switchCase)) { | 4693 for (Constant constant in getConstants(switchCase)) { |
| 4696 caseConstants.add(constant); | 4694 caseConstants.add(constant); |
| 4697 HConstant hConstant = graph.addConstant(constant, compiler); | 4695 HConstant hConstant = graph.addConstant(constant, compiler); |
| 4698 switchInstruction.inputs.add(hConstant); | 4696 switchInstruction.inputs.add(hConstant); |
| 4699 hConstant.usedBy.add(switchInstruction); | 4697 hConstant.usedBy.add(switchInstruction); |
| 4700 expressionBlock.addSuccessor(block); | 4698 expressionEnd.addSuccessor(block); |
| 4701 } | 4699 } |
| 4702 matchExpressions.add(caseConstants); | 4700 matchExpressions.add(caseConstants); |
| 4703 | 4701 |
| 4704 if (isDefaultCase(switchCase)) { | 4702 if (isDefaultCase(switchCase)) { |
| 4705 // An HSwitch has n inputs and n+1 successors, the last being the | 4703 // An HSwitch has n inputs and n+1 successors, the last being the |
| 4706 // default case. | 4704 // default case. |
| 4707 expressionBlock.addSuccessor(block); | 4705 expressionEnd.addSuccessor(block); |
| 4708 hasDefault = true; | 4706 hasDefault = true; |
| 4709 } | 4707 } |
| 4710 open(block); | 4708 open(block); |
| 4711 localsHandler = new LocalsHandler.from(savedLocals); | 4709 localsHandler = new LocalsHandler.from(savedLocals); |
| 4712 buildSwitchCase(switchCase); | 4710 buildSwitchCase(switchCase); |
| 4713 if (!isAborted() && caseIterator.hasNext) { | 4711 if (!isAborted() && caseIterator.hasNext) { |
| 4714 pushInvokeStatic(switchCase, getFallThroughErrorElement, []); | 4712 pushInvokeStatic(switchCase, getFallThroughErrorElement, []); |
| 4715 HInstruction error = pop(); | 4713 HInstruction error = pop(); |
| 4716 closeAndGotoExit(new HThrow(error)); | 4714 closeAndGotoExit(new HThrow(error)); |
| 4717 } | 4715 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 4735 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { | 4733 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| 4736 assert(invariant(errorNode, false, | 4734 assert(invariant(errorNode, false, |
| 4737 message: 'Continue cannot target a switch.')); | 4735 message: 'Continue cannot target a switch.')); |
| 4738 }); | 4736 }); |
| 4739 if (!isAborted()) { | 4737 if (!isAborted()) { |
| 4740 current.close(new HGoto()); | 4738 current.close(new HGoto()); |
| 4741 lastOpenedBlock.addSuccessor(joinBlock); | 4739 lastOpenedBlock.addSuccessor(joinBlock); |
| 4742 caseHandlers.add(localsHandler); | 4740 caseHandlers.add(localsHandler); |
| 4743 } | 4741 } |
| 4744 if (!hasDefault) { | 4742 if (!hasDefault) { |
| 4745 // The current flow is only aborted if the switch has a default that | 4743 // Always create a default case, to avoid a critical edge in the |
| 4746 // aborts (all previous cases must abort, and if there is no default, | 4744 // graph. |
| 4747 // it's possible to miss all the cases). | 4745 HBasicBlock avoidCriticalEdge = addNewBlock(); |
|
karlklose
2013/08/14 14:36:43
Rename variable to 'defaultCase'?
ngeoffray
2013/08/14 14:57:57
Done.
| |
| 4748 expressionEnd.addSuccessor(joinBlock); | 4746 expressionEnd.addSuccessor(avoidCriticalEdge); |
| 4747 open(avoidCriticalEdge); | |
| 4748 close(new HGoto()); | |
| 4749 avoidCriticalEdge.addSuccessor(joinBlock); | |
| 4749 caseHandlers.add(savedLocals); | 4750 caseHandlers.add(savedLocals); |
| 4751 matchExpressions.add(<Constant>[]); | |
| 4752 statements.add(new HSubGraphBlockInformation(new SubGraph( | |
| 4753 avoidCriticalEdge, avoidCriticalEdge))); | |
| 4750 } | 4754 } |
| 4751 assert(caseHandlers.length == joinBlock.predecessors.length); | 4755 assert(caseHandlers.length == joinBlock.predecessors.length); |
| 4752 if (caseHandlers.length != 0) { | 4756 if (caseHandlers.length != 0) { |
| 4753 graph.addBlock(joinBlock); | 4757 graph.addBlock(joinBlock); |
| 4754 open(joinBlock); | 4758 open(joinBlock); |
| 4755 if (caseHandlers.length == 1) { | 4759 if (caseHandlers.length == 1) { |
| 4756 localsHandler = caseHandlers[0]; | 4760 localsHandler = caseHandlers[0]; |
| 4757 } else { | 4761 } else { |
| 4758 localsHandler = savedLocals.mergeMultiple(caseHandlers, joinBlock); | 4762 localsHandler = savedLocals.mergeMultiple(caseHandlers, joinBlock); |
| 4759 } | 4763 } |
| 4760 } else { | 4764 } else { |
| 4761 // The joinblock is not used. | 4765 // The joinblock is not used. |
| 4762 joinBlock = null; | 4766 joinBlock = null; |
| 4763 } | 4767 } |
| 4764 | 4768 |
| 4765 HSubExpressionBlockInformation expressionInfo = | 4769 HSubExpressionBlockInformation expressionInfo = |
| 4766 new HSubExpressionBlockInformation(new SubExpression(expressionStart, | 4770 new HSubExpressionBlockInformation(new SubExpression(expressionStart, |
| 4767 expressionEnd)); | 4771 expressionEnd)); |
| 4768 expressionStart.setBlockFlow( | 4772 expressionStart.setBlockFlow( |
| 4769 new HSwitchBlockInformation(expressionInfo, | 4773 new HSwitchBlockInformation(expressionInfo, |
| 4770 matchExpressions, | 4774 matchExpressions, |
| 4771 statements, | 4775 statements, |
| 4772 hasDefault, | |
| 4773 jumpHandler.target, | 4776 jumpHandler.target, |
| 4774 jumpHandler.labels()), | 4777 jumpHandler.labels()), |
| 4775 joinBlock); | 4778 joinBlock); |
| 4776 | 4779 |
| 4777 jumpHandler.close(); | 4780 jumpHandler.close(); |
| 4778 } | 4781 } |
| 4779 | 4782 |
| 4780 bool nonPrimitiveTypeOverridesEquals(Constant constant) { | 4783 bool nonPrimitiveTypeOverridesEquals(Constant constant) { |
| 4781 // Function values override equals. Even static ones, since | 4784 // Function values override equals. Even static ones, since |
| 4782 // they inherit from [Function]. | 4785 // they inherit from [Function]. |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5443 new HSubGraphBlockInformation(elseBranch.graph)); | 5446 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5444 | 5447 |
| 5445 HBasicBlock conditionStartBlock = conditionBranch.block; | 5448 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5446 conditionStartBlock.setBlockFlow(info, joinBlock); | 5449 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5447 SubGraph conditionGraph = conditionBranch.graph; | 5450 SubGraph conditionGraph = conditionBranch.graph; |
| 5448 HIf branch = conditionGraph.end.last; | 5451 HIf branch = conditionGraph.end.last; |
| 5449 assert(branch is HIf); | 5452 assert(branch is HIf); |
| 5450 branch.blockInformation = conditionStartBlock.blockFlow; | 5453 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5451 } | 5454 } |
| 5452 } | 5455 } |
| OLD | NEW |