| 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 implement [TypedElement.type] because our | 9 * methods. We need to implement [TypedElement.type] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 | 1165 |
| 1166 // Bail out early if the inlining decision is in the cache and we can't | 1166 // Bail out early if the inlining decision is in the cache and we can't |
| 1167 // inline (no need to check the hard constraints). | 1167 // inline (no need to check the hard constraints). |
| 1168 bool cachedCanBeInlined = | 1168 bool cachedCanBeInlined = |
| 1169 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 1169 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
| 1170 if (cachedCanBeInlined == false) return false; | 1170 if (cachedCanBeInlined == false) return false; |
| 1171 | 1171 |
| 1172 bool meetsHardConstraints() { | 1172 bool meetsHardConstraints() { |
| 1173 // Don't inline from one output unit to another. If something is deferred | 1173 // Don't inline from one output unit to another. If something is deferred |
| 1174 // it is to save space in the loading code. | 1174 // it is to save space in the loading code. |
| 1175 var getOutputUnit = compiler.deferredLoadTask.outputUnitForElement; | 1175 if (!compiler.deferredLoadTask |
| 1176 if (getOutputUnit(element) != | 1176 .inSameOutputUnit(element,compiler.currentElement)) { |
| 1177 getOutputUnit(compiler.currentElement)) { | |
| 1178 return false; | 1177 return false; |
| 1179 } | 1178 } |
| 1180 if (compiler.disableInlining) return false; | 1179 if (compiler.disableInlining) return false; |
| 1181 | 1180 |
| 1182 assert(selector != null | 1181 assert(selector != null |
| 1183 || Elements.isStaticOrTopLevel(element) | 1182 || Elements.isStaticOrTopLevel(element) |
| 1184 || element.isGenerativeConstructorBody()); | 1183 || element.isGenerativeConstructorBody()); |
| 1185 if (selector != null && !selector.applies(function, compiler)) { | 1184 if (selector != null && !selector.applies(function, compiler)) { |
| 1186 return false; | 1185 return false; |
| 1187 } | 1186 } |
| (...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2922 * [selector]. | 2921 * [selector]. |
| 2923 */ | 2922 */ |
| 2924 void generateInstanceGetterWithCompiledReceiver(ast.Send send, | 2923 void generateInstanceGetterWithCompiledReceiver(ast.Send send, |
| 2925 Selector selector, | 2924 Selector selector, |
| 2926 HInstruction receiver) { | 2925 HInstruction receiver) { |
| 2927 assert(Elements.isInstanceSend(send, elements)); | 2926 assert(Elements.isInstanceSend(send, elements)); |
| 2928 assert(selector.isGetter()); | 2927 assert(selector.isGetter()); |
| 2929 pushInvokeDynamic(send, selector, [receiver]); | 2928 pushInvokeDynamic(send, selector, [receiver]); |
| 2930 } | 2929 } |
| 2931 | 2930 |
| 2931 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
| 2932 /// resolves to a deferred library. |
| 2933 void generateIsDeferredLoadedCheckIfNeeded(ast.Send node) { |
| 2934 DeferredLoadTask deferredTask = compiler.deferredLoadTask; |
| 2935 PrefixElement prefixElement = |
| 2936 deferredTask.deferredPrefixElement(node, elements); |
| 2937 if (prefixElement != null) { |
| 2938 String loadId = |
| 2939 deferredTask.importDeferName[prefixElement.deferredImport]; |
| 2940 HInstruction loadIdConstant = addConstantString(loadId); |
| 2941 String uri = prefixElement.deferredImport.uri.dartString.slowToString(); |
| 2942 HInstruction uriConstant = addConstantString(uri); |
| 2943 Element helper = backend.getCheckDeferredIsLoaded(); |
| 2944 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]); |
| 2945 pop(); |
| 2946 } |
| 2947 } |
| 2948 |
| 2932 void generateGetter(ast.Send send, Element element) { | 2949 void generateGetter(ast.Send send, Element element) { |
| 2933 if (element != null && element.isForeign(compiler)) { | 2950 if (element != null && element.isForeign(compiler)) { |
| 2934 visitForeignGetter(send); | 2951 visitForeignGetter(send); |
| 2935 } else if (Elements.isStaticOrTopLevelField(element)) { | 2952 } else if (Elements.isStaticOrTopLevelField(element)) { |
| 2936 Constant value; | 2953 Constant value; |
| 2937 if (element.isField() && !element.isAssignable()) { | 2954 if (element.isField() && !element.isAssignable()) { |
| 2938 // A static final or const. Get its constant value and inline it if | 2955 // A static final or const. Get its constant value and inline it if |
| 2939 // the value can be compiled eagerly. | 2956 // the value can be compiled eagerly. |
| 2940 value = backend.constants.getConstantForVariable(element); | 2957 value = backend.constants.getConstantForVariable(element); |
| 2941 } | 2958 } |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3914 // The new object will now be referenced through the | 3931 // The new object will now be referenced through the |
| 3915 // `setRuntimeTypeInfo` call. We therefore set the type of that | 3932 // `setRuntimeTypeInfo` call. We therefore set the type of that |
| 3916 // instruction to be of the object's type. | 3933 // instruction to be of the object's type. |
| 3917 assert(stack.last is HInvokeStatic || stack.last == newObject); | 3934 assert(stack.last is HInvokeStatic || stack.last == newObject); |
| 3918 stack.last.instructionType = newObject.instructionType; | 3935 stack.last.instructionType = newObject.instructionType; |
| 3919 return pop(); | 3936 return pop(); |
| 3920 } | 3937 } |
| 3921 | 3938 |
| 3922 handleNewSend(ast.NewExpression node) { | 3939 handleNewSend(ast.NewExpression node) { |
| 3923 ast.Send send = node.send; | 3940 ast.Send send = node.send; |
| 3941 generateIsDeferredLoadedCheckIfNeeded(send); |
| 3942 |
| 3924 bool isFixedList = false; | 3943 bool isFixedList = false; |
| 3925 bool isFixedListConstructorCall = | 3944 bool isFixedListConstructorCall = |
| 3926 Elements.isFixedListConstructorCall(elements[send], send, compiler); | 3945 Elements.isFixedListConstructorCall(elements[send], send, compiler); |
| 3927 bool isGrowableListConstructorCall = | 3946 bool isGrowableListConstructorCall = |
| 3928 Elements.isGrowableListConstructorCall(elements[send], send, compiler); | 3947 Elements.isGrowableListConstructorCall(elements[send], send, compiler); |
| 3929 | 3948 |
| 3930 TypeMask computeType(element) { | 3949 TypeMask computeType(element) { |
| 3931 Element originalElement = elements[send]; | 3950 Element originalElement = elements[send]; |
| 3932 if (isFixedListConstructorCall | 3951 if (isFixedListConstructorCall |
| 3933 || Elements.isFilledListConstructorCall( | 3952 || Elements.isFilledListConstructorCall( |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4165 } | 4184 } |
| 4166 if (element.isErroneous()) { | 4185 if (element.isErroneous()) { |
| 4167 // An erroneous element indicates that the funciton could not be resolved | 4186 // An erroneous element indicates that the funciton could not be resolved |
| 4168 // (a warning has been issued). | 4187 // (a warning has been issued). |
| 4169 generateThrowNoSuchMethod(node, | 4188 generateThrowNoSuchMethod(node, |
| 4170 getTargetName(element), | 4189 getTargetName(element), |
| 4171 argumentNodes: node.arguments); | 4190 argumentNodes: node.arguments); |
| 4172 return; | 4191 return; |
| 4173 } | 4192 } |
| 4174 invariant(element, !element.isGenerativeConstructor()); | 4193 invariant(element, !element.isGenerativeConstructor()); |
| 4194 generateIsDeferredLoadedCheckIfNeeded(node); |
| 4175 if (element.isFunction()) { | 4195 if (element.isFunction()) { |
| 4176 var inputs = <HInstruction>[]; | 4196 var inputs = <HInstruction>[]; |
| 4177 // TODO(5347): Try to avoid the need for calling [implementation] before | 4197 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 4178 // calling [addStaticSendArgumentsToList]. | 4198 // calling [addStaticSendArgumentsToList]. |
| 4179 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 4199 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 4180 element.implementation, | 4200 element.implementation, |
| 4181 inputs); | 4201 inputs); |
| 4182 if (!succeeded) { | 4202 if (!succeeded) { |
| 4183 generateWrongArgumentCountError(node, element, node.arguments); | 4203 generateWrongArgumentCountError(node, element, node.arguments); |
| 4184 return; | 4204 return; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4240 HInstruction target = pop(); | 4260 HInstruction target = pop(); |
| 4241 Selector selector = elements.getSelector(node); | 4261 Selector selector = elements.getSelector(node); |
| 4242 List<HInstruction> inputs = <HInstruction>[target]; | 4262 List<HInstruction> inputs = <HInstruction>[target]; |
| 4243 addDynamicSendArgumentsToList(node, inputs); | 4263 addDynamicSendArgumentsToList(node, inputs); |
| 4244 Selector closureSelector = new Selector.callClosureFrom(selector); | 4264 Selector closureSelector = new Selector.callClosureFrom(selector); |
| 4245 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); | 4265 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); |
| 4246 } | 4266 } |
| 4247 } | 4267 } |
| 4248 | 4268 |
| 4249 visitGetterSend(ast.Send node) { | 4269 visitGetterSend(ast.Send node) { |
| 4270 generateIsDeferredLoadedCheckIfNeeded(node); |
| 4250 generateGetter(node, elements[node]); | 4271 generateGetter(node, elements[node]); |
| 4251 } | 4272 } |
| 4252 | 4273 |
| 4253 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. | 4274 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. |
| 4254 internalError(String reason, {ast.Node node}) { | 4275 internalError(String reason, {ast.Node node}) { |
| 4255 compiler.internalError(node, reason); | 4276 compiler.internalError(node, reason); |
| 4256 } | 4277 } |
| 4257 | 4278 |
| 4258 void generateError(ast.Node node, String message, Element helper) { | 4279 void generateError(ast.Node node, String message, Element helper) { |
| 4259 HInstruction errorMessage = addConstantString(message); | 4280 HInstruction errorMessage = addConstantString(message); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4508 } else { | 4529 } else { |
| 4509 visit(arguments.head); | 4530 visit(arguments.head); |
| 4510 assert(arguments.tail.isEmpty); | 4531 assert(arguments.tail.isEmpty); |
| 4511 rhs = pop(); | 4532 rhs = pop(); |
| 4512 } | 4533 } |
| 4513 visitBinary(receiver, node.assignmentOperator, rhs, | 4534 visitBinary(receiver, node.assignmentOperator, rhs, |
| 4514 elements.getOperatorSelectorInComplexSendSet(node), node); | 4535 elements.getOperatorSelectorInComplexSendSet(node), node); |
| 4515 } | 4536 } |
| 4516 | 4537 |
| 4517 visitSendSet(ast.SendSet node) { | 4538 visitSendSet(ast.SendSet node) { |
| 4539 generateIsDeferredLoadedCheckIfNeeded(node); |
| 4518 Element element = elements[node]; | 4540 Element element = elements[node]; |
| 4519 if (!Elements.isUnresolved(element) && element.impliesType()) { | 4541 if (!Elements.isUnresolved(element) && element.impliesType()) { |
| 4520 ast.Identifier selector = node.selector; | 4542 ast.Identifier selector = node.selector; |
| 4521 generateThrowNoSuchMethod(node, selector.source, | 4543 generateThrowNoSuchMethod(node, selector.source, |
| 4522 argumentNodes: node.arguments); | 4544 argumentNodes: node.arguments); |
| 4523 return; | 4545 return; |
| 4524 } | 4546 } |
| 4525 ast.Operator op = node.assignmentOperator; | 4547 ast.Operator op = node.assignmentOperator; |
| 4526 if (node.isSuperCall) { | 4548 if (node.isSuperCall) { |
| 4527 HInstruction result; | 4549 HInstruction result; |
| (...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6270 DartType unaliased = type.unalias(builder.compiler); | 6292 DartType unaliased = type.unalias(builder.compiler); |
| 6271 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6293 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6272 unaliased.accept(this, builder); | 6294 unaliased.accept(this, builder); |
| 6273 } | 6295 } |
| 6274 | 6296 |
| 6275 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6297 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6276 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); | 6298 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); |
| 6277 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); | 6299 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); |
| 6278 } | 6300 } |
| 6279 } | 6301 } |
| OLD | NEW |