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