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 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 | 1315 |
1316 // Bail out early if the inlining decision is in the cache and we can't | 1316 // Bail out early if the inlining decision is in the cache and we can't |
1317 // inline (no need to check the hard constraints). | 1317 // inline (no need to check the hard constraints). |
1318 bool cachedCanBeInlined = | 1318 bool cachedCanBeInlined = |
1319 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 1319 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
1320 if (cachedCanBeInlined == false) return false; | 1320 if (cachedCanBeInlined == false) return false; |
1321 | 1321 |
1322 bool meetsHardConstraints() { | 1322 bool meetsHardConstraints() { |
1323 if (compiler.disableInlining) return false; | 1323 if (compiler.disableInlining) return false; |
1324 | 1324 |
1325 assert(selector != null | 1325 assert(invariant( |
1326 || Elements.isStaticOrTopLevel(element) | 1326 currentNode != null ? currentNode : element, |
1327 || element.isGenerativeConstructorBody); | 1327 selector != null || |
| 1328 Elements.isStaticOrTopLevel(element) || |
| 1329 element.isGenerativeConstructorBody, |
| 1330 message: "Missing selector for inlining of $element.")); |
1328 if (selector != null && !selector.applies(function, compiler.world)) { | 1331 if (selector != null && !selector.applies(function, compiler.world)) { |
1329 return false; | 1332 return false; |
1330 } | 1333 } |
1331 | 1334 |
1332 // Don't inline operator== methods if the parameter can be null. | 1335 // Don't inline operator== methods if the parameter can be null. |
1333 if (element.name == '==') { | 1336 if (element.name == '==') { |
1334 if (element.enclosingClass != compiler.objectClass | 1337 if (element.enclosingClass != compiler.objectClass |
1335 && providedArguments[1].canBeNull()) { | 1338 && providedArguments[1].canBeNull()) { |
1336 return false; | 1339 return false; |
1337 } | 1340 } |
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3239 | 3242 |
3240 HInstruction generateInstanceSendReceiver(ast.Send send) { | 3243 HInstruction generateInstanceSendReceiver(ast.Send send) { |
3241 assert(Elements.isInstanceSend(send, elements)); | 3244 assert(Elements.isInstanceSend(send, elements)); |
3242 if (send.receiver == null) { | 3245 if (send.receiver == null) { |
3243 return localsHandler.readThis(); | 3246 return localsHandler.readThis(); |
3244 } | 3247 } |
3245 visit(send.receiver); | 3248 visit(send.receiver); |
3246 return pop(); | 3249 return pop(); |
3247 } | 3250 } |
3248 | 3251 |
3249 String noSuchMethodTargetSymbolString(ErroneousElement error, | 3252 String noSuchMethodTargetSymbolString(Element error, [String prefix]) { |
3250 [String prefix]) { | |
3251 String result = error.name; | 3253 String result = error.name; |
3252 if (prefix == "set") return "$result="; | 3254 if (prefix == "set") return "$result="; |
3253 return result; | 3255 return result; |
3254 } | 3256 } |
3255 | 3257 |
3256 /** | 3258 /** |
3257 * Returns a set of interceptor classes that contain the given | 3259 * Returns a set of interceptor classes that contain the given |
3258 * [selector]. | 3260 * [selector]. |
3259 */ | 3261 */ |
3260 void generateInstanceGetterWithCompiledReceiver(ast.Send send, | 3262 void generateInstanceGetterWithCompiledReceiver(ast.Send send, |
(...skipping 20 matching lines...) Expand all Loading... |
3281 } | 3283 } |
3282 | 3284 |
3283 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 3285 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
3284 /// resolves to a deferred library. | 3286 /// resolves to a deferred library. |
3285 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 3287 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
3286 generateIsDeferredLoadedCheckIfNeeded( | 3288 generateIsDeferredLoadedCheckIfNeeded( |
3287 compiler.deferredLoadTask.deferredPrefixElement(node, elements), | 3289 compiler.deferredLoadTask.deferredPrefixElement(node, elements), |
3288 node); | 3290 node); |
3289 } | 3291 } |
3290 | 3292 |
| 3293 void handleInvalidStaticGet(ast.Send node, Element element) { |
| 3294 generateThrowNoSuchMethod( |
| 3295 node, |
| 3296 noSuchMethodTargetSymbolString(element, 'get'), |
| 3297 argumentNodes: const Link<ast.Node>()); |
| 3298 } |
| 3299 |
3291 /// Generate read access of an unresolved static or top level entity. | 3300 /// Generate read access of an unresolved static or top level entity. |
3292 void generateStaticUnresolvedGet(ast.Send node, Element element) { | 3301 void generateStaticUnresolvedGet(ast.Send node, Element element) { |
3293 if (element is ErroneousElement) { | 3302 if (element is ErroneousElement) { |
3294 // An erroneous element indicates an unresolved static getter. | 3303 // An erroneous element indicates an unresolved static getter. |
3295 generateThrowNoSuchMethod( | 3304 handleInvalidStaticGet(node, element); |
3296 node, | |
3297 noSuchMethodTargetSymbolString(element, 'get'), | |
3298 argumentNodes: const Link<ast.Node>()); | |
3299 } else { | 3305 } else { |
3300 // This happens when [element] has parse errors. | 3306 // This happens when [element] has parse errors. |
3301 assert(invariant(node, element == null || element.isErroneous)); | 3307 assert(invariant(node, element == null || element.isErroneous)); |
3302 // TODO(ahe): Do something like the above, that is, emit a runtime | 3308 // TODO(ahe): Do something like the above, that is, emit a runtime |
3303 // error. | 3309 // error. |
3304 stack.add(graph.addConstantNull(compiler)); | 3310 stack.add(graph.addConstantNull(compiler)); |
3305 } | 3311 } |
3306 } | 3312 } |
3307 | 3313 |
3308 /// Read a static or top level [field] of constant value. | 3314 /// Read a static or top level [field] of constant value. |
(...skipping 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5135 ast.Send node, | 5141 ast.Send node, |
5136 FunctionElement getter, | 5142 FunctionElement getter, |
5137 ast.NodeList arguments, | 5143 ast.NodeList arguments, |
5138 CallStructure callStructure, | 5144 CallStructure callStructure, |
5139 _) { | 5145 _) { |
5140 generateStaticGetterGet(node, getter); | 5146 generateStaticGetterGet(node, getter); |
5141 generateCallInvoke(node, pop()); | 5147 generateCallInvoke(node, pop()); |
5142 } | 5148 } |
5143 | 5149 |
5144 @override | 5150 @override |
| 5151 void visitTopLevelSetterGet( |
| 5152 ast.Send node, |
| 5153 MethodElement setter, |
| 5154 _) { |
| 5155 handleInvalidStaticGet(node, setter); |
| 5156 } |
| 5157 |
| 5158 @override |
| 5159 void visitStaticSetterGet( |
| 5160 ast.Send node, |
| 5161 MethodElement setter, |
| 5162 _) { |
| 5163 handleInvalidStaticGet(node, setter); |
| 5164 } |
| 5165 |
| 5166 @override |
5145 void visitUnresolvedGet( | 5167 void visitUnresolvedGet( |
5146 ast.Send node, | 5168 ast.Send node, |
5147 Element element, | 5169 Element element, |
5148 _) { | 5170 _) { |
5149 generateStaticUnresolvedGet(node, element); | 5171 generateStaticUnresolvedGet(node, element); |
5150 } | 5172 } |
5151 | 5173 |
| 5174 void handleInvalidStaticInvoke(ast.Send node, Element element) { |
| 5175 generateThrowNoSuchMethod(node, |
| 5176 noSuchMethodTargetSymbolString(element), |
| 5177 argumentNodes: node.arguments); |
| 5178 } |
| 5179 |
| 5180 @override |
| 5181 void visitStaticSetterInvoke( |
| 5182 ast.Send node, |
| 5183 MethodElement setter, |
| 5184 ast.NodeList arguments, |
| 5185 CallStructure callStructure, |
| 5186 _) { |
| 5187 handleInvalidStaticInvoke(node, setter); |
| 5188 } |
| 5189 |
| 5190 @override |
| 5191 void visitTopLevelSetterInvoke( |
| 5192 ast.Send node, |
| 5193 MethodElement setter, |
| 5194 ast.NodeList arguments, |
| 5195 CallStructure callStructure, |
| 5196 _) { |
| 5197 handleInvalidStaticInvoke(node, setter); |
| 5198 } |
| 5199 |
5152 @override | 5200 @override |
5153 void visitUnresolvedInvoke( | 5201 void visitUnresolvedInvoke( |
5154 ast.Send node, | 5202 ast.Send node, |
5155 Element element, | 5203 Element element, |
5156 ast.NodeList arguments, | 5204 ast.NodeList arguments, |
5157 Selector selector, | 5205 Selector selector, |
5158 _) { | 5206 _) { |
5159 if (element is ErroneousElement) { | 5207 if (element is ErroneousElement) { |
5160 // An erroneous element indicates that the funciton could not be | 5208 // An erroneous element indicates that the funciton could not be |
5161 // resolved (a warning has been issued). | 5209 // resolved (a warning has been issued). |
5162 generateThrowNoSuchMethod(node, | 5210 handleInvalidStaticInvoke(node, element); |
5163 noSuchMethodTargetSymbolString(element), | |
5164 argumentNodes: node.arguments); | |
5165 } else { | 5211 } else { |
5166 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 5212 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
5167 stack.add(graph.addConstantNull(compiler)); | 5213 stack.add(graph.addConstantNull(compiler)); |
5168 } | 5214 } |
5169 return; | 5215 return; |
5170 } | 5216 } |
5171 | 5217 |
5172 HConstant addConstantString(String string) { | 5218 HConstant addConstantString(String string) { |
5173 ast.DartString dartString = new ast.DartString.literal(string); | 5219 ast.DartString dartString = new ast.DartString.literal(string); |
5174 ConstantValue constant = constantSystem.createString(dartString); | 5220 ConstantValue constant = constantSystem.createString(dartString); |
(...skipping 2647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7822 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7868 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
7823 unaliased.accept(this, builder); | 7869 unaliased.accept(this, builder); |
7824 } | 7870 } |
7825 | 7871 |
7826 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7872 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
7827 JavaScriptBackend backend = builder.compiler.backend; | 7873 JavaScriptBackend backend = builder.compiler.backend; |
7828 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7874 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
7829 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7875 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
7830 } | 7876 } |
7831 } | 7877 } |
OLD | NEW |