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 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 | 1002 |
1003 // Once we start to compile the arguments we must be sure that we don't | 1003 // Once we start to compile the arguments we must be sure that we don't |
1004 // abort. | 1004 // abort. |
1005 List<HInstruction> compiledArguments = new List<HInstruction>(); | 1005 List<HInstruction> compiledArguments = new List<HInstruction>(); |
1006 bool succeeded = addStaticSendArgumentsToList(selector, | 1006 bool succeeded = addStaticSendArgumentsToList(selector, |
1007 arguments, | 1007 arguments, |
1008 function, | 1008 function, |
1009 compiledArguments); | 1009 compiledArguments); |
1010 assert(succeeded); | 1010 assert(succeeded); |
1011 | 1011 |
| 1012 // Create the inlining state after evaluating the arguments, that |
| 1013 // may have an impact on the state of the current method. |
| 1014 InliningState state = new InliningState( |
| 1015 function, returnElement, returnType, elements, stack, localsHandler); |
| 1016 localsHandler = new LocalsHandler.from(localsHandler); |
| 1017 |
1012 FunctionSignature signature = function.computeSignature(compiler); | 1018 FunctionSignature signature = function.computeSignature(compiler); |
1013 int index = 0; | 1019 int index = 0; |
1014 signature.orderedForEachParameter((Element parameter) { | 1020 signature.orderedForEachParameter((Element parameter) { |
1015 HInstruction argument = compiledArguments[index++]; | 1021 HInstruction argument = compiledArguments[index++]; |
1016 localsHandler.updateLocal(parameter, argument); | 1022 localsHandler.updateLocal(parameter, argument); |
1017 potentiallyCheckType(argument, parameter.computeType(compiler)); | 1023 potentiallyCheckType(argument, parameter.computeType(compiler)); |
1018 }); | 1024 }); |
1019 | 1025 |
1020 if (function.isConstructor()) { | 1026 if (function.isConstructor()) { |
1021 ClassElement enclosing = function.getEnclosingClass(); | 1027 ClassElement enclosing = function.getEnclosingClass(); |
1022 if (compiler.world.needsRti(enclosing)) { | 1028 if (compiler.world.needsRti(enclosing)) { |
1023 assert(currentNode is NewExpression); | 1029 assert(currentNode is NewExpression); |
1024 InterfaceType type = elements.getType(currentNode); | 1030 InterfaceType type = elements.getType(currentNode); |
1025 Link<DartType> typeVariable = enclosing.typeVariables; | 1031 Link<DartType> typeVariable = enclosing.typeVariables; |
1026 type.typeArguments.forEach((DartType argument) { | 1032 type.typeArguments.forEach((DartType argument) { |
1027 HInstruction instruction = | 1033 HInstruction instruction = |
1028 analyzeTypeArgument(argument, currentNode); | 1034 analyzeTypeArgument(argument, currentNode); |
1029 localsHandler.updateLocal(typeVariable.head.element, instruction); | 1035 localsHandler.updateLocal(typeVariable.head.element, instruction); |
1030 typeVariable = typeVariable.tail; | 1036 typeVariable = typeVariable.tail; |
1031 }); | 1037 }); |
1032 while (!typeVariable.isEmpty) { | 1038 while (!typeVariable.isEmpty) { |
1033 localsHandler.updateLocal(typeVariable.head.element, | 1039 localsHandler.updateLocal(typeVariable.head.element, |
1034 graph.addConstantNull(constantSystem)); | 1040 graph.addConstantNull(constantSystem)); |
1035 typeVariable = typeVariable.tail; | 1041 typeVariable = typeVariable.tail; |
1036 } | 1042 } |
1037 } | 1043 } |
1038 } | 1044 } |
1039 InliningState state = | |
1040 new InliningState(function, returnElement, returnType, elements, stack); | |
1041 | 1045 |
1042 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1046 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
1043 returnElement = new ElementX(const SourceString("result"), | 1047 returnElement = new ElementX(const SourceString("result"), |
1044 ElementKind.VARIABLE, | 1048 ElementKind.VARIABLE, |
1045 function); | 1049 function); |
1046 localsHandler.updateLocal(returnElement, | 1050 localsHandler.updateLocal(returnElement, |
1047 graph.addConstantNull(constantSystem)); | 1051 graph.addConstantNull(constantSystem)); |
1048 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1052 elements = compiler.enqueuer.resolution.getCachedElements(function); |
1049 assert(elements != null); | 1053 assert(elements != null); |
1050 returnType = signature.returnType; | 1054 returnType = signature.returnType; |
1051 stack = <HInstruction>[]; | 1055 stack = <HInstruction>[]; |
1052 inliningStack.add(state); | 1056 inliningStack.add(state); |
1053 return state; | 1057 return state; |
1054 } | 1058 } |
1055 | 1059 |
1056 void leaveInlinedMethod(InliningState state) { | 1060 void leaveInlinedMethod(InliningState state) { |
1057 InliningState poppedState = inliningStack.removeLast(); | 1061 InliningState poppedState = inliningStack.removeLast(); |
1058 assert(state == poppedState); | 1062 assert(state == poppedState); |
1059 elements = state.oldElements; | 1063 elements = state.oldElements; |
1060 stack.add(localsHandler.readLocal(returnElement)); | 1064 stack.add(localsHandler.readLocal(returnElement)); |
1061 returnElement = state.oldReturnElement; | 1065 returnElement = state.oldReturnElement; |
1062 returnType = state.oldReturnType; | 1066 returnType = state.oldReturnType; |
1063 assert(stack.length == 1); | 1067 assert(stack.length == 1); |
1064 state.oldStack.add(stack[0]); | 1068 state.oldStack.add(stack[0]); |
1065 stack = state.oldStack; | 1069 stack = state.oldStack; |
| 1070 localsHandler = state.oldLocalsHandler; |
1066 } | 1071 } |
1067 | 1072 |
1068 /** | 1073 /** |
1069 * Try to inline [element] within the currect context of the | 1074 * Try to inline [element] within the currect context of the |
1070 * builder. The insertion point is the state of the builder. | 1075 * builder. The insertion point is the state of the builder. |
1071 */ | 1076 */ |
1072 bool tryInlineMethod(Element element, | 1077 bool tryInlineMethod(Element element, |
1073 Selector selector, | 1078 Selector selector, |
1074 Link<Node> arguments, | 1079 Link<Node> arguments, |
1075 Node currentNode) { | 1080 Node currentNode) { |
(...skipping 3751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4827 /** | 4832 /** |
4828 * Documentation wanted -- johnniwinther | 4833 * Documentation wanted -- johnniwinther |
4829 * | 4834 * |
4830 * Invariant: [function] must be an implementation element. | 4835 * Invariant: [function] must be an implementation element. |
4831 */ | 4836 */ |
4832 final PartialFunctionElement function; | 4837 final PartialFunctionElement function; |
4833 final Element oldReturnElement; | 4838 final Element oldReturnElement; |
4834 final DartType oldReturnType; | 4839 final DartType oldReturnType; |
4835 final TreeElements oldElements; | 4840 final TreeElements oldElements; |
4836 final List<HInstruction> oldStack; | 4841 final List<HInstruction> oldStack; |
| 4842 final LocalsHandler oldLocalsHandler; |
4837 | 4843 |
4838 InliningState(this.function, | 4844 InliningState(this.function, |
4839 this.oldReturnElement, | 4845 this.oldReturnElement, |
4840 this.oldReturnType, | 4846 this.oldReturnType, |
4841 this.oldElements, | 4847 this.oldElements, |
4842 this.oldStack) { | 4848 this.oldStack, |
| 4849 this.oldLocalsHandler) { |
4843 assert(function.isImplementation); | 4850 assert(function.isImplementation); |
4844 } | 4851 } |
4845 } | 4852 } |
4846 | 4853 |
4847 class SsaBranch { | 4854 class SsaBranch { |
4848 final SsaBranchBuilder branchBuilder; | 4855 final SsaBranchBuilder branchBuilder; |
4849 final HBasicBlock block; | 4856 final HBasicBlock block; |
4850 LocalsHandler startLocals; | 4857 LocalsHandler startLocals; |
4851 LocalsHandler exitLocals; | 4858 LocalsHandler exitLocals; |
4852 SubGraph graph; | 4859 SubGraph graph; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5072 new HSubGraphBlockInformation(elseBranch.graph)); | 5079 new HSubGraphBlockInformation(elseBranch.graph)); |
5073 | 5080 |
5074 HBasicBlock conditionStartBlock = conditionBranch.block; | 5081 HBasicBlock conditionStartBlock = conditionBranch.block; |
5075 conditionStartBlock.setBlockFlow(info, joinBlock); | 5082 conditionStartBlock.setBlockFlow(info, joinBlock); |
5076 SubGraph conditionGraph = conditionBranch.graph; | 5083 SubGraph conditionGraph = conditionBranch.graph; |
5077 HIf branch = conditionGraph.end.last; | 5084 HIf branch = conditionGraph.end.last; |
5078 assert(branch is HIf); | 5085 assert(branch is HIf); |
5079 branch.blockInformation = conditionStartBlock.blockFlow; | 5086 branch.blockInformation = conditionStartBlock.blockFlow; |
5080 } | 5087 } |
5081 } | 5088 } |
OLD | NEW |