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