| 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 // Generative constructors of native classes should not be called directly | 676 // Generative constructors of native classes should not be called directly |
| 677 // and have an extra argument that causes problems with inlining. | 677 // and have an extra argument that causes problems with inlining. |
| 678 if (element.isGenerativeConstructor && | 678 if (element.isGenerativeConstructor && |
| 679 backend.isNativeOrExtendsNative(element.enclosingClass)) { | 679 backend.isNativeOrExtendsNative(element.enclosingClass)) { |
| 680 return false; | 680 return false; |
| 681 } | 681 } |
| 682 | 682 |
| 683 // A generative constructor body is not seen by global analysis, | 683 // A generative constructor body is not seen by global analysis, |
| 684 // so we should not query for its type. | 684 // so we should not query for its type. |
| 685 if (!element.isGenerativeConstructorBody) { | 685 if (!element.isGenerativeConstructorBody) { |
| 686 // Don't inline if the return type was inferred to be non-null empty. | 686 if (compiler.globalInference.throwsAlways(element)) { |
| 687 // This means that the function always throws an exception. | |
| 688 TypeMask returnType = | |
| 689 compiler.typesTask.getGuaranteedReturnTypeOfElement(element); | |
| 690 if (returnType != null && returnType.isEmpty) { | |
| 691 isReachable = false; | 687 isReachable = false; |
| 692 return false; | 688 return false; |
| 693 } | 689 } |
| 694 } | 690 } |
| 695 | 691 |
| 696 return true; | 692 return true; |
| 697 } | 693 } |
| 698 | 694 |
| 699 bool doesNotContainCode() { | 695 bool doesNotContainCode() { |
| 700 // A function with size 1 does not contain any code. | 696 // A function with size 1 does not contain any code. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 | 813 |
| 818 bool get allInlinedFunctionsCalledOnce { | 814 bool get allInlinedFunctionsCalledOnce { |
| 819 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; | 815 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; |
| 820 } | 816 } |
| 821 | 817 |
| 822 bool isFunctionCalledOnce(Element element) { | 818 bool isFunctionCalledOnce(Element element) { |
| 823 if (element is ConstructorBodyElement) { | 819 if (element is ConstructorBodyElement) { |
| 824 // ConstructorBodyElements are not in the type inference graph. | 820 // ConstructorBodyElements are not in the type inference graph. |
| 825 return false; | 821 return false; |
| 826 } | 822 } |
| 827 TypesInferrer inferrer = compiler.typesTask.typesInferrer; | 823 return compiler.globalInference.isCalledOnce(element); |
| 828 return inferrer.isCalledOnce(element); | |
| 829 } | 824 } |
| 830 | 825 |
| 831 bool isCalledOnce(Element element) { | 826 bool isCalledOnce(Element element) { |
| 832 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); | 827 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); |
| 833 } | 828 } |
| 834 | 829 |
| 835 inlinedFrom(ResolvedAst resolvedAst, f()) { | 830 inlinedFrom(ResolvedAst resolvedAst, f()) { |
| 836 Element element = resolvedAst.element; | 831 Element element = resolvedAst.element; |
| 837 assert(element is FunctionElement || element is VariableElement); | 832 assert(element is FunctionElement || element is VariableElement); |
| 838 return reporter.withCurrentElement(element.implementation, () { | 833 return reporter.withCurrentElement(element.implementation, () { |
| (...skipping 3383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4222 var constant = inputs[0]; | 4217 var constant = inputs[0]; |
| 4223 int value = constant.constant.primitiveValue; | 4218 int value = constant.constant.primitiveValue; |
| 4224 if (0 <= value && value < 0x100000000) canThrow = false; | 4219 if (0 <= value && value < 0x100000000) canThrow = false; |
| 4225 } | 4220 } |
| 4226 HForeignCode foreign = new HForeignCode(code, elementType, inputs, | 4221 HForeignCode foreign = new HForeignCode(code, elementType, inputs, |
| 4227 nativeBehavior: behavior, | 4222 nativeBehavior: behavior, |
| 4228 throwBehavior: canThrow | 4223 throwBehavior: canThrow |
| 4229 ? native.NativeThrowBehavior.MAY | 4224 ? native.NativeThrowBehavior.MAY |
| 4230 : native.NativeThrowBehavior.NEVER); | 4225 : native.NativeThrowBehavior.NEVER); |
| 4231 push(foreign); | 4226 push(foreign); |
| 4232 TypesInferrer inferrer = compiler.typesTask.typesInferrer; | 4227 if (compiler.globalInference.isFixedArrayCheckedForGrowable(send)) { |
| 4233 if (inferrer.isFixedArrayCheckedForGrowable(send)) { | |
| 4234 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); | 4228 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); |
| 4235 // We set the instruction as [canThrow] to avoid it being dead code. | 4229 // We set the instruction as [canThrow] to avoid it being dead code. |
| 4236 // We need a finer grained side effect. | 4230 // We need a finer grained side effect. |
| 4237 add(new HForeignCode(code, backend.nullType, [stack.last], | 4231 add(new HForeignCode(code, backend.nullType, [stack.last], |
| 4238 throwBehavior: native.NativeThrowBehavior.MAY)); | 4232 throwBehavior: native.NativeThrowBehavior.MAY)); |
| 4239 } | 4233 } |
| 4240 } else if (isGrowableListConstructorCall) { | 4234 } else if (isGrowableListConstructorCall) { |
| 4241 push(buildLiteralList(<HInstruction>[])); | 4235 push(buildLiteralList(<HInstruction>[])); |
| 4242 stack.last.instructionType = elementType; | 4236 stack.last.instructionType = elementType; |
| 4243 } else { | 4237 } else { |
| (...skipping 3600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7844 const _LoopTypeVisitor(); | 7838 const _LoopTypeVisitor(); |
| 7845 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 7839 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 7846 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 7840 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
| 7847 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 7841 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 7848 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 7842 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 7849 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7843 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 7850 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7844 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 7851 int visitSwitchStatement(ast.SwitchStatement node) => | 7845 int visitSwitchStatement(ast.SwitchStatement node) => |
| 7852 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 7846 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 7853 } | 7847 } |
| OLD | NEW |