| 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 |