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 3933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3944 } | 3944 } |
3945 | 3945 |
3946 void handleInTryStatement() { | 3946 void handleInTryStatement() { |
3947 if (!inTryStatement) return; | 3947 if (!inTryStatement) return; |
3948 HBasicBlock block = close(new HExitTry()); | 3948 HBasicBlock block = close(new HExitTry()); |
3949 HBasicBlock newBlock = graph.addNewBlock(); | 3949 HBasicBlock newBlock = graph.addNewBlock(); |
3950 block.addSuccessor(newBlock); | 3950 block.addSuccessor(newBlock); |
3951 open(newBlock); | 3951 open(newBlock); |
3952 } | 3952 } |
3953 | 3953 |
| 3954 visitRethrow(Rethrow node) { |
| 3955 HInstruction exception = rethrowableException; |
| 3956 if (exception == null) { |
| 3957 exception = graph.addConstantNull(constantSystem); |
| 3958 compiler.internalError( |
| 3959 'rethrowableException should not be null', node: node); |
| 3960 } |
| 3961 handleInTryStatement(); |
| 3962 closeAndGotoExit(new HThrow(exception, isRethrow: true)); |
| 3963 } |
| 3964 |
3954 visitReturn(Return node) { | 3965 visitReturn(Return node) { |
3955 if (identical(node.getBeginToken().stringValue, 'native')) { | 3966 if (identical(node.getBeginToken().stringValue, 'native')) { |
3956 native.handleSsaNative(this, node.expression); | 3967 native.handleSsaNative(this, node.expression); |
3957 return; | 3968 return; |
3958 } | 3969 } |
3959 assert(invariant(node, !node.isRedirectingFactoryBody)); | 3970 assert(invariant(node, !node.isRedirectingFactoryBody)); |
3960 HInstruction value; | 3971 HInstruction value; |
3961 if (node.expression == null) { | 3972 if (node.expression == null) { |
3962 value = graph.addConstantNull(constantSystem); | 3973 value = graph.addConstantNull(constantSystem); |
3963 } else { | 3974 } else { |
3964 visit(node.expression); | 3975 visit(node.expression); |
3965 value = pop(); | 3976 value = pop(); |
3966 value = potentiallyCheckType(value, returnType); | 3977 value = potentiallyCheckType(value, returnType); |
3967 } | 3978 } |
3968 | 3979 |
3969 handleInTryStatement(); | 3980 handleInTryStatement(); |
3970 | 3981 |
3971 if (!inliningStack.isEmpty) { | 3982 if (!inliningStack.isEmpty) { |
3972 localsHandler.updateLocal(returnElement, value); | 3983 localsHandler.updateLocal(returnElement, value); |
3973 } else { | 3984 } else { |
3974 closeAndGotoExit(attachPosition(new HReturn(value), node)); | 3985 closeAndGotoExit(attachPosition(new HReturn(value), node)); |
3975 } | 3986 } |
3976 } | 3987 } |
3977 | 3988 |
3978 visitThrow(Throw node) { | 3989 visitThrow(Throw node) { |
3979 if (node.expression == null) { | 3990 visit(node.expression); |
3980 HInstruction exception = rethrowableException; | 3991 if (isReachable) { |
3981 if (exception == null) { | |
3982 exception = graph.addConstantNull(constantSystem); | |
3983 compiler.internalError( | |
3984 'rethrowableException should not be null', node: node); | |
3985 } | |
3986 handleInTryStatement(); | 3992 handleInTryStatement(); |
3987 closeAndGotoExit(new HThrow(exception, isRethrow: true)); | 3993 push(new HThrowExpression(pop())); |
3988 } else { | 3994 isReachable = false; |
3989 visit(node.expression); | |
3990 handleInTryStatement(); | |
3991 if (inliningStack.isEmpty) { | |
3992 closeAndGotoExit(new HThrow(pop())); | |
3993 } else if (isReachable) { | |
3994 // We don't close the block when we are inlining, because we could be | |
3995 // inside an expression, and it is rather complicated to close the | |
3996 // block at an arbitrary place in an expression. | |
3997 add(new HThrowExpression(pop())); | |
3998 isReachable = false; | |
3999 } | |
4000 } | 3995 } |
4001 } | 3996 } |
4002 | 3997 |
4003 visitTypeAnnotation(TypeAnnotation node) { | 3998 visitTypeAnnotation(TypeAnnotation node) { |
4004 compiler.internalError('visiting type annotation in SSA builder', | 3999 compiler.internalError('visiting type annotation in SSA builder', |
4005 node: node); | 4000 node: node); |
4006 } | 4001 } |
4007 | 4002 |
4008 visitVariableDefinitions(VariableDefinitions node) { | 4003 visitVariableDefinitions(VariableDefinitions node) { |
4009 assert(isReachable); | 4004 assert(isReachable); |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4965 node.visitChildren(this); | 4960 node.visitChildren(this); |
4966 } | 4961 } |
4967 | 4962 |
4968 visitLoop(Node node) { | 4963 visitLoop(Node node) { |
4969 // It's actually not difficult to inline a method with a loop, but | 4964 // It's actually not difficult to inline a method with a loop, but |
4970 // our measurements show that it's currently better to not inline a | 4965 // our measurements show that it's currently better to not inline a |
4971 // method that contains a loop. | 4966 // method that contains a loop. |
4972 tooDifficult = true; | 4967 tooDifficult = true; |
4973 } | 4968 } |
4974 | 4969 |
| 4970 void visitRethrow(Rethrow node) { |
| 4971 if (!registerNode()) return; |
| 4972 tooDifficult = true; |
| 4973 } |
| 4974 |
4975 void visitReturn(Return node) { | 4975 void visitReturn(Return node) { |
4976 if (!registerNode()) return; | 4976 if (!registerNode()) return; |
4977 if (seenReturn | 4977 if (seenReturn |
4978 || identical(node.getBeginToken().stringValue, 'native') | 4978 || identical(node.getBeginToken().stringValue, 'native') |
4979 || node.isRedirectingFactoryBody) { | 4979 || node.isRedirectingFactoryBody) { |
4980 tooDifficult = true; | 4980 tooDifficult = true; |
4981 return; | 4981 return; |
4982 } | 4982 } |
4983 node.visitChildren(this); | 4983 node.visitChildren(this); |
4984 seenReturn = true; | 4984 seenReturn = true; |
4985 } | 4985 } |
4986 | 4986 |
4987 void visitTryStatement(Node node) { | 4987 void visitTryStatement(Node node) { |
4988 if (!registerNode()) return; | 4988 if (!registerNode()) return; |
4989 tooDifficult = true; | 4989 tooDifficult = true; |
4990 } | 4990 } |
4991 | 4991 |
4992 void visitThrow(Throw node) { | 4992 void visitThrow(Throw node) { |
4993 if (!registerNode()) return; | 4993 if (!registerNode()) return; |
4994 // We can't inline rethrows and we don't want to handle throw after a return | 4994 // For now, we don't want to handle throw after a return even if |
4995 // even if it is in an "if". | 4995 // it is in an "if". |
4996 if (seenReturn || node.expression == null) tooDifficult = true; | 4996 if (seenReturn) tooDifficult = true; |
4997 } | 4997 } |
4998 } | 4998 } |
4999 | 4999 |
5000 class InliningState { | 5000 class InliningState { |
5001 /** | 5001 /** |
5002 * Documentation wanted -- johnniwinther | 5002 * Documentation wanted -- johnniwinther |
5003 * | 5003 * |
5004 * Invariant: [function] must be an implementation element. | 5004 * Invariant: [function] must be an implementation element. |
5005 */ | 5005 */ |
5006 final PartialFunctionElement function; | 5006 final PartialFunctionElement function; |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5248 new HSubGraphBlockInformation(elseBranch.graph)); | 5248 new HSubGraphBlockInformation(elseBranch.graph)); |
5249 | 5249 |
5250 HBasicBlock conditionStartBlock = conditionBranch.block; | 5250 HBasicBlock conditionStartBlock = conditionBranch.block; |
5251 conditionStartBlock.setBlockFlow(info, joinBlock); | 5251 conditionStartBlock.setBlockFlow(info, joinBlock); |
5252 SubGraph conditionGraph = conditionBranch.graph; | 5252 SubGraph conditionGraph = conditionBranch.graph; |
5253 HIf branch = conditionGraph.end.last; | 5253 HIf branch = conditionGraph.end.last; |
5254 assert(branch is HIf); | 5254 assert(branch is HIf); |
5255 branch.blockInformation = conditionStartBlock.blockFlow; | 5255 branch.blockInformation = conditionStartBlock.blockFlow; |
5256 } | 5256 } |
5257 } | 5257 } |
OLD | NEW |