| 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 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 | 906 |
| 907 /** | 907 /** |
| 908 * Indicates whether the current block is dead (because it has a throw or a | 908 * Indicates whether the current block is dead (because it has a throw or a |
| 909 * return further up). If this is false, then [_current] may be null. If the | 909 * return further up). If this is false, then [_current] may be null. If the |
| 910 * block is dead then it may also be aborted, but for simplicity we only | 910 * block is dead then it may also be aborted, but for simplicity we only |
| 911 * abort on statement boundaries, not in the middle of expressions. See | 911 * abort on statement boundaries, not in the middle of expressions. See |
| 912 * isAborted. | 912 * isAborted. |
| 913 */ | 913 */ |
| 914 bool isReachable = true; | 914 bool isReachable = true; |
| 915 | 915 |
| 916 /** |
| 917 * True if we are visiting the expression of a throw expression. |
| 918 */ |
| 919 bool inThrowExpression = false; |
| 920 |
| 916 final List<Element> sourceElementStack; | 921 final List<Element> sourceElementStack; |
| 917 | 922 |
| 918 Element get currentElement => sourceElementStack.last.declaration; | 923 Element get currentElement => sourceElementStack.last.declaration; |
| 919 Element get currentNonClosureClass { | 924 Element get currentNonClosureClass { |
| 920 ClassElement cls = currentElement.getEnclosingClass(); | 925 ClassElement cls = currentElement.getEnclosingClass(); |
| 921 if (cls != null && cls.isClosure()) { | 926 if (cls != null && cls.isClosure()) { |
| 922 var closureClass = cls; | 927 var closureClass = cls; |
| 923 return closureClass.methodElement.getEnclosingClass(); | 928 return closureClass.methodElement.getEnclosingClass(); |
| 924 } else { | 929 } else { |
| 925 return cls; | 930 return cls; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { | 1311 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { |
| 1307 // Don't inline recursivly | 1312 // Don't inline recursivly |
| 1308 if (inliningStack.any((entry) => entry.function == function)) { | 1313 if (inliningStack.any((entry) => entry.function == function)) { |
| 1309 return false; | 1314 return false; |
| 1310 } | 1315 } |
| 1311 | 1316 |
| 1312 if (element.isSynthesized) return true; | 1317 if (element.isSynthesized) return true; |
| 1313 | 1318 |
| 1314 if (cachedCanBeInlined == true) return cachedCanBeInlined; | 1319 if (cachedCanBeInlined == true) return cachedCanBeInlined; |
| 1315 | 1320 |
| 1321 if (inThrowExpression) return false; |
| 1322 |
| 1316 int numParameters = function.functionSignature.parameterCount; | 1323 int numParameters = function.functionSignature.parameterCount; |
| 1317 int maxInliningNodes; | 1324 int maxInliningNodes; |
| 1318 if (insideLoop) { | 1325 if (insideLoop) { |
| 1319 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + | 1326 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + |
| 1320 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; | 1327 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; |
| 1321 } else { | 1328 } else { |
| 1322 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + | 1329 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + |
| 1323 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; | 1330 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; |
| 1324 } | 1331 } |
| 1325 bool canBeInlined = InlineWeeder.canBeInlined( | 1332 bool canBeInlined = InlineWeeder.canBeInlined( |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2053 } | 2060 } |
| 2054 } | 2061 } |
| 2055 assert(!current.isClosed()); | 2062 assert(!current.isClosed()); |
| 2056 if (!stack.isEmpty) compiler.cancel('non-empty instruction stack'); | 2063 if (!stack.isEmpty) compiler.cancel('non-empty instruction stack'); |
| 2057 } | 2064 } |
| 2058 | 2065 |
| 2059 visitClassNode(ClassNode node) { | 2066 visitClassNode(ClassNode node) { |
| 2060 compiler.internalError('visitClassNode should not be called', node: node); | 2067 compiler.internalError('visitClassNode should not be called', node: node); |
| 2061 } | 2068 } |
| 2062 | 2069 |
| 2070 visitThrowExpression(Expression expression) { |
| 2071 bool old = inThrowExpression; |
| 2072 try { |
| 2073 inThrowExpression = true; |
| 2074 visit(expression); |
| 2075 } finally { |
| 2076 inThrowExpression = old; |
| 2077 } |
| 2078 } |
| 2079 |
| 2063 visitExpressionStatement(ExpressionStatement node) { | 2080 visitExpressionStatement(ExpressionStatement node) { |
| 2064 if (!isReachable) return; | 2081 if (!isReachable) return; |
| 2065 Throw throwExpression = node.expression.asThrow(); | 2082 Throw throwExpression = node.expression.asThrow(); |
| 2066 if (throwExpression != null && inliningStack.isEmpty) { | 2083 if (throwExpression != null && inliningStack.isEmpty) { |
| 2067 visit(throwExpression.expression); | 2084 visitThrowExpression(throwExpression.expression); |
| 2068 handleInTryStatement(); | 2085 handleInTryStatement(); |
| 2069 closeAndGotoExit(new HThrow(pop())); | 2086 closeAndGotoExit(new HThrow(pop())); |
| 2070 } else { | 2087 } else { |
| 2071 visit(node.expression); | 2088 visit(node.expression); |
| 2072 pop(); | 2089 pop(); |
| 2073 } | 2090 } |
| 2074 } | 2091 } |
| 2075 | 2092 |
| 2076 /** | 2093 /** |
| 2077 * Creates a new loop-header block. The previous [current] block | 2094 * Creates a new loop-header block. The previous [current] block |
| (...skipping 2234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4312 handleInTryStatement(); | 4329 handleInTryStatement(); |
| 4313 | 4330 |
| 4314 if (!inliningStack.isEmpty) { | 4331 if (!inliningStack.isEmpty) { |
| 4315 localsHandler.updateLocal(returnElement, value); | 4332 localsHandler.updateLocal(returnElement, value); |
| 4316 } else { | 4333 } else { |
| 4317 closeAndGotoExit(attachPosition(new HReturn(value), node)); | 4334 closeAndGotoExit(attachPosition(new HReturn(value), node)); |
| 4318 } | 4335 } |
| 4319 } | 4336 } |
| 4320 | 4337 |
| 4321 visitThrow(Throw node) { | 4338 visitThrow(Throw node) { |
| 4322 visit(node.expression); | 4339 visitThrowExpression(node.expression); |
| 4323 if (isReachable) { | 4340 if (isReachable) { |
| 4324 handleInTryStatement(); | 4341 handleInTryStatement(); |
| 4325 push(new HThrowExpression(pop())); | 4342 push(new HThrowExpression(pop())); |
| 4326 isReachable = false; | 4343 isReachable = false; |
| 4327 } | 4344 } |
| 4328 } | 4345 } |
| 4329 | 4346 |
| 4330 visitTypeAnnotation(TypeAnnotation node) { | 4347 visitTypeAnnotation(TypeAnnotation node) { |
| 4331 compiler.internalError('visiting type annotation in SSA builder', | 4348 compiler.internalError('visiting type annotation in SSA builder', |
| 4332 node: node); | 4349 node: node); |
| (...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5574 new HSubGraphBlockInformation(elseBranch.graph)); | 5591 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5575 | 5592 |
| 5576 HBasicBlock conditionStartBlock = conditionBranch.block; | 5593 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5577 conditionStartBlock.setBlockFlow(info, joinBlock); | 5594 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5578 SubGraph conditionGraph = conditionBranch.graph; | 5595 SubGraph conditionGraph = conditionBranch.graph; |
| 5579 HIf branch = conditionGraph.end.last; | 5596 HIf branch = conditionGraph.end.last; |
| 5580 assert(branch is HIf); | 5597 assert(branch is HIf); |
| 5581 branch.blockInformation = conditionStartBlock.blockFlow; | 5598 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5582 } | 5599 } |
| 5583 } | 5600 } |
| OLD | NEW |