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