| 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 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 LocalsHandler newLocalsHandler = new LocalsHandler(this); | 1179 LocalsHandler newLocalsHandler = new LocalsHandler(this); |
| 1180 newLocalsHandler.closureData = | 1180 newLocalsHandler.closureData = |
| 1181 compiler.closureToClassMapper.computeClosureToClassMapping( | 1181 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1182 function, function.parseNode(compiler), elements); | 1182 function, function.parseNode(compiler), elements); |
| 1183 int argumentIndex = 0; | 1183 int argumentIndex = 0; |
| 1184 if (isInstanceMember) { | 1184 if (isInstanceMember) { |
| 1185 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, | 1185 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, |
| 1186 compiledArguments[argumentIndex++]); | 1186 compiledArguments[argumentIndex++]); |
| 1187 } | 1187 } |
| 1188 | 1188 |
| 1189 FunctionSignature signature = function.computeSignature(compiler); |
| 1190 signature.orderedForEachParameter((Element parameter) { |
| 1191 HInstruction argument = compiledArguments[argumentIndex++]; |
| 1192 newLocalsHandler.updateLocal(parameter, argument); |
| 1193 }); |
| 1194 |
| 1189 ClassElement enclosing = function.getEnclosingClass(); | 1195 ClassElement enclosing = function.getEnclosingClass(); |
| 1190 FunctionSignature signature = function.computeSignature(compiler); | |
| 1191 int parameterCount = signature.parameterCount; | |
| 1192 // If [function] is a generative constructor body, we need to add | |
| 1193 // 1 for the new instance. | |
| 1194 int typeArgumentIndex = parameterCount + (isInstanceMember ? 1 : 0); | |
| 1195 if ((function.isConstructor() || function.isGenerativeConstructorBody()) | 1196 if ((function.isConstructor() || function.isGenerativeConstructorBody()) |
| 1196 && backend.needsRti(enclosing)) { | 1197 && backend.needsRti(enclosing)) { |
| 1197 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | 1198 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1198 HInstruction argument = compiledArguments[typeArgumentIndex++]; | 1199 HInstruction argument = compiledArguments[argumentIndex++]; |
| 1199 newLocalsHandler.updateLocal(typeVariable.element, argument); | 1200 newLocalsHandler.updateLocal(typeVariable.element, argument); |
| 1200 }); | 1201 }); |
| 1201 } | 1202 } |
| 1202 assert(typeArgumentIndex == compiledArguments.length); | 1203 assert(argumentIndex == compiledArguments.length); |
| 1203 | |
| 1204 // Check the type of the arguments. This must be done after setting up the | |
| 1205 // type variables in the [localsHandler] because the checked types may | |
| 1206 // contain type variables. | |
| 1207 signature.orderedForEachParameter((Element parameter) { | |
| 1208 HInstruction argument = compiledArguments[argumentIndex++]; | |
| 1209 newLocalsHandler.updateLocal(parameter, argument); | |
| 1210 potentiallyCheckType(argument, parameter.computeType(compiler)); | |
| 1211 }); | |
| 1212 assert(argumentIndex == parameterCount + (isInstanceMember ? 1 : 0)); | |
| 1213 | 1204 |
| 1214 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 1205 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 1215 returnElement = new ElementX(const SourceString("result"), | 1206 returnElement = new ElementX(const SourceString("result"), |
| 1216 ElementKind.VARIABLE, | 1207 ElementKind.VARIABLE, |
| 1217 function); | 1208 function); |
| 1218 newLocalsHandler.updateLocal(returnElement, | 1209 newLocalsHandler.updateLocal(returnElement, |
| 1219 graph.addConstantNull(constantSystem)); | 1210 graph.addConstantNull(constantSystem)); |
| 1220 elements = compiler.enqueuer.resolution.getCachedElements(function); | 1211 elements = compiler.enqueuer.resolution.getCachedElements(function); |
| 1221 assert(elements != null); | 1212 assert(elements != null); |
| 1222 returnType = signature.returnType; | 1213 returnType = signature.returnType; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1250 Node currentNode) { | 1241 Node currentNode) { |
| 1251 // We cannot inline a method from a deferred library into a method | 1242 // We cannot inline a method from a deferred library into a method |
| 1252 // which isn't deferred. | 1243 // which isn't deferred. |
| 1253 // TODO(ahe): But we should still inline into the same | 1244 // TODO(ahe): But we should still inline into the same |
| 1254 // connected-component of the deferred library. | 1245 // connected-component of the deferred library. |
| 1255 if (compiler.deferredLoadTask.isDeferred(element)) return false; | 1246 if (compiler.deferredLoadTask.isDeferred(element)) return false; |
| 1256 | 1247 |
| 1257 if (compiler.disableInlining) return false; | 1248 if (compiler.disableInlining) return false; |
| 1258 // Ensure that [element] is an implementation element. | 1249 // Ensure that [element] is an implementation element. |
| 1259 element = element.implementation; | 1250 element = element.implementation; |
| 1260 // TODO(floitsch): we should be able to inline inside lazy initializers. | |
| 1261 if (currentElement.isField()) return false; | |
| 1262 // TODO(floitsch): find a cleaner way to know if the element is a function | 1251 // TODO(floitsch): find a cleaner way to know if the element is a function |
| 1263 // containing nodes. | 1252 // containing nodes. |
| 1264 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. | 1253 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. |
| 1265 if (element is !PartialFunctionElement | 1254 if (element is !PartialFunctionElement |
| 1266 && !element.isGenerativeConstructorBody()) { | 1255 && !element.isGenerativeConstructorBody()) { |
| 1267 return false; | 1256 return false; |
| 1268 } | 1257 } |
| 1269 if (inliningStack.length > MAX_INLINING_DEPTH) return false; | 1258 if (inliningStack.length > MAX_INLINING_DEPTH) return false; |
| 1270 // Don't inline recursive calls. We use the same elements for the inlined | 1259 // Don't inline recursive calls. We use the same elements for the inlined |
| 1271 // functions and would thus clobber our local variables. | 1260 // functions and would thus clobber our local variables. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1297 if (newElements == null) { | 1286 if (newElements == null) { |
| 1298 compiler.internalError("Element not resolved: $function"); | 1287 compiler.internalError("Element not resolved: $function"); |
| 1299 } | 1288 } |
| 1300 | 1289 |
| 1301 if (canBeInlined == null) { | 1290 if (canBeInlined == null) { |
| 1302 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); | 1291 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); |
| 1303 backend.canBeInlined[function] = canBeInlined; | 1292 backend.canBeInlined[function] = canBeInlined; |
| 1304 if (!canBeInlined) return false; | 1293 if (!canBeInlined) return false; |
| 1305 } | 1294 } |
| 1306 | 1295 |
| 1307 // We cannot inline methods with type variables in the signature in checked | |
| 1308 // mode, because we currently do not have access to the type variables | |
| 1309 // through the locals. | |
| 1310 // TODO(karlklose): remove this and enable inlining of these methods. | |
| 1311 if (compiler.enableTypeAssertions | |
| 1312 && !element.isGenerativeConstructorBody() | |
| 1313 && element.computeType(compiler).containsTypeVariables) { | |
| 1314 return false; | |
| 1315 } | |
| 1316 | |
| 1317 assert(canBeInlined); | 1296 assert(canBeInlined); |
| 1318 // Add an explicit null check on the receiver before doing the | 1297 // Add an explicit null check on the receiver before doing the |
| 1319 // inlining. We use [element] to get the same name in the NoSuchMethodError | 1298 // inlining. We use [element] to get the same name in the NoSuchMethodError |
| 1320 // message as if we had called it. | 1299 // message as if we had called it. |
| 1321 if (element.isInstanceMember() | 1300 if (element.isInstanceMember() |
| 1322 && !element.isGenerativeConstructorBody() | 1301 && !element.isGenerativeConstructorBody() |
| 1323 && (selector.mask == null || selector.mask.isNullable)) { | 1302 && (selector.mask == null || selector.mask.isNullable)) { |
| 1324 addWithPosition( | 1303 addWithPosition( |
| 1325 new HFieldGet(element, providedArguments[0]), currentNode); | 1304 new HFieldGet(element, providedArguments[0]), currentNode); |
| 1326 } | 1305 } |
| 1327 InliningState state = enterInlinedMethod( | 1306 InliningState state = enterInlinedMethod( |
| 1328 function, selector, argumentsNodes, providedArguments, currentNode); | 1307 function, selector, argumentsNodes, providedArguments, currentNode); |
| 1308 |
| 1329 inlinedFrom(element, () { | 1309 inlinedFrom(element, () { |
| 1310 FunctionSignature signature = element.computeSignature(compiler); |
| 1311 signature.orderedForEachParameter((Element parameter) { |
| 1312 HInstruction argument = localsHandler.readLocal(parameter); |
| 1313 potentiallyCheckType(argument, parameter.computeType(compiler)); |
| 1314 }); |
| 1330 element.isGenerativeConstructor() | 1315 element.isGenerativeConstructor() |
| 1331 ? buildFactory(element) | 1316 ? buildFactory(element) |
| 1332 : functionExpression.body.accept(this); | 1317 : functionExpression.body.accept(this); |
| 1333 }); | 1318 }); |
| 1319 |
| 1334 leaveInlinedMethod(state); | 1320 leaveInlinedMethod(state); |
| 1335 return true; | 1321 return true; |
| 1336 } | 1322 } |
| 1337 | 1323 |
| 1338 inlinedFrom(Element element, f()) { | 1324 inlinedFrom(Element element, f()) { |
| 1339 assert(element is FunctionElement || element is VariableElement); | 1325 assert(element is FunctionElement || element is VariableElement); |
| 1340 return compiler.withCurrentElement(element, () { | 1326 return compiler.withCurrentElement(element, () { |
| 1341 sourceElementStack.add(element); | 1327 sourceElementStack.add(element); |
| 1342 var result = f(); | 1328 var result = f(); |
| 1343 sourceElementStack.removeLast(); | 1329 sourceElementStack.removeLast(); |
| (...skipping 4051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5395 new HSubGraphBlockInformation(elseBranch.graph)); | 5381 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5396 | 5382 |
| 5397 HBasicBlock conditionStartBlock = conditionBranch.block; | 5383 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5398 conditionStartBlock.setBlockFlow(info, joinBlock); | 5384 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5399 SubGraph conditionGraph = conditionBranch.graph; | 5385 SubGraph conditionGraph = conditionBranch.graph; |
| 5400 HIf branch = conditionGraph.end.last; | 5386 HIf branch = conditionGraph.end.last; |
| 5401 assert(branch is HIf); | 5387 assert(branch is HIf); |
| 5402 branch.blockInformation = conditionStartBlock.blockFlow; | 5388 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5403 } | 5389 } |
| 5404 } | 5390 } |
| OLD | NEW |