| 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 library dart2js.enqueue; | 5 library dart2js.enqueue; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'common/codegen.dart' show CodegenWorkItem; | 9 import 'common/codegen.dart' show CodegenWorkItem; |
| 10 import 'common/names.dart' show Identifiers; | 10 import 'common/names.dart' show Identifiers; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 String get name => 'Enqueue'; | 51 String get name => 'Enqueue'; |
| 52 | 52 |
| 53 EnqueueTask(Compiler compiler) | 53 EnqueueTask(Compiler compiler) |
| 54 : compiler = compiler, | 54 : compiler = compiler, |
| 55 resolution = new ResolutionEnqueuer( | 55 resolution = new ResolutionEnqueuer( |
| 56 compiler, | 56 compiler, |
| 57 compiler.backend.createItemCompilationContext, | 57 compiler.backend.createItemCompilationContext, |
| 58 compiler.options.analyzeOnly && compiler.options.analyzeMain | 58 compiler.options.analyzeOnly && compiler.options.analyzeMain |
| 59 ? const EnqueuerStrategy() | 59 ? const EnqueuerStrategy() |
| 60 : const TreeShakingEnqueuerStrategy()), | 60 : const TreeShakingEnqueuerStrategy()), |
| 61 codegen = new CodegenEnqueuer( | 61 codegen = compiler.backend.createCodegenEnqueuer(compiler), |
| 62 compiler, | |
| 63 compiler.backend.createItemCompilationContext, | |
| 64 const TreeShakingEnqueuerStrategy()), | |
| 65 super(compiler.measurer) { | 62 super(compiler.measurer) { |
| 66 codegen.task = this; | 63 codegen.task = this; |
| 67 resolution.task = this; | 64 resolution.task = this; |
| 68 | 65 |
| 69 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); | 66 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); |
| 70 resolution.nativeEnqueuer = | 67 resolution.nativeEnqueuer = |
| 71 compiler.backend.nativeResolutionEnqueuer(resolution); | 68 compiler.backend.nativeResolutionEnqueuer(resolution); |
| 72 } | 69 } |
| 73 | 70 |
| 74 void forgetElement(Element element) { | 71 void forgetElement(Element element) { |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 log('Resolved ${processedElements.length} elements.'); | 825 log('Resolved ${processedElements.length} elements.'); |
| 829 } | 826 } |
| 830 | 827 |
| 831 void forgetElement(Element element) { | 828 void forgetElement(Element element) { |
| 832 super.forgetElement(element); | 829 super.forgetElement(element); |
| 833 processedElements.remove(element); | 830 processedElements.remove(element); |
| 834 } | 831 } |
| 835 } | 832 } |
| 836 | 833 |
| 837 /// [Enqueuer] which is specific to code generation. | 834 /// [Enqueuer] which is specific to code generation. |
| 838 class CodegenEnqueuer extends Enqueuer { | 835 abstract class CodegenEnqueuer implements Enqueuer { |
| 839 final Queue<CodegenWorkItem> queue; | 836 Map<Element, js.Expression> get generatedCode; |
| 840 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; | |
| 841 | 837 |
| 842 final Set<Element> newlyEnqueuedElements; | 838 Set<Element> get newlyEnqueuedElements; |
| 843 | |
| 844 final Set<DynamicUse> newlySeenSelectors; | |
| 845 | |
| 846 bool enabledNoSuchMethod = false; | |
| 847 | |
| 848 static const ImpactUseCase IMPACT_USE = | |
| 849 const ImpactUseCase('CodegenEnqueuer'); | |
| 850 | |
| 851 ImpactUseCase get impactUse => IMPACT_USE; | |
| 852 | |
| 853 CodegenEnqueuer( | |
| 854 Compiler compiler, | |
| 855 ItemCompilationContext itemCompilationContextCreator(), | |
| 856 EnqueuerStrategy strategy) | |
| 857 : queue = new Queue<CodegenWorkItem>(), | |
| 858 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | |
| 859 newlySeenSelectors = compiler.cacheStrategy.newSet(), | |
| 860 super('codegen enqueuer', compiler, itemCompilationContextCreator, | |
| 861 strategy); | |
| 862 | |
| 863 bool isProcessed(Element member) => | |
| 864 member.isAbstract || generatedCode.containsKey(member); | |
| 865 | |
| 866 /** | |
| 867 * Decides whether an element should be included to satisfy requirements | |
| 868 * of the mirror system. | |
| 869 * | |
| 870 * For code generation, we rely on the precomputed set of elements that takes | |
| 871 * subtyping constraints into account. | |
| 872 */ | |
| 873 bool shouldIncludeElementDueToMirrors(Element element, | |
| 874 {bool includedEnclosing}) { | |
| 875 return compiler.backend.isAccessibleByReflection(element); | |
| 876 } | |
| 877 | |
| 878 bool internalAddToWorkList(Element element) { | |
| 879 // Don't generate code for foreign elements. | |
| 880 if (compiler.backend.isForeign(element)) return false; | |
| 881 | |
| 882 // Codegen inlines field initializers. It only needs to generate | |
| 883 // code for checked setters. | |
| 884 if (element.isField && element.isInstanceMember) { | |
| 885 if (!compiler.options.enableTypeAssertions || | |
| 886 element.enclosingElement.isClosure) { | |
| 887 return false; | |
| 888 } | |
| 889 } | |
| 890 | |
| 891 if (compiler.options.hasIncrementalSupport && !isProcessed(element)) { | |
| 892 newlyEnqueuedElements.add(element); | |
| 893 } | |
| 894 | |
| 895 if (queueIsClosed) { | |
| 896 throw new SpannableAssertionFailure( | |
| 897 element, "Codegen work list is closed. Trying to add $element"); | |
| 898 } | |
| 899 CodegenWorkItem workItem = | |
| 900 new CodegenWorkItem(compiler, element, itemCompilationContextCreator()); | |
| 901 queue.add(workItem); | |
| 902 return true; | |
| 903 } | |
| 904 | |
| 905 void registerNoSuchMethod(Element element) { | |
| 906 if (!enabledNoSuchMethod && compiler.backend.enabledNoSuchMethod) { | |
| 907 compiler.backend.enableNoSuchMethod(this); | |
| 908 enabledNoSuchMethod = true; | |
| 909 } | |
| 910 } | |
| 911 | |
| 912 void _logSpecificSummary(log(message)) { | |
| 913 log('Compiled ${generatedCode.length} methods.'); | |
| 914 } | |
| 915 | |
| 916 void forgetElement(Element element) { | |
| 917 super.forgetElement(element); | |
| 918 generatedCode.remove(element); | |
| 919 if (element is MemberElement) { | |
| 920 for (Element closure in element.nestedClosures) { | |
| 921 generatedCode.remove(closure); | |
| 922 removeFromSet(instanceMembersByName, closure); | |
| 923 removeFromSet(instanceFunctionsByName, closure); | |
| 924 } | |
| 925 } | |
| 926 } | |
| 927 | |
| 928 void handleUnseenSelector(DynamicUse dynamicUse) { | |
| 929 if (compiler.options.hasIncrementalSupport) { | |
| 930 newlySeenSelectors.add(dynamicUse); | |
| 931 } | |
| 932 super.handleUnseenSelector(dynamicUse); | |
| 933 } | |
| 934 } | 839 } |
| 935 | 840 |
| 936 /// Parameterizes filtering of which work items are enqueued. | 841 /// Parameterizes filtering of which work items are enqueued. |
| 937 class QueueFilter { | 842 class QueueFilter { |
| 938 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 843 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
| 939 enqueuer.task.measure(() { | 844 enqueuer.task.measure(() { |
| 940 // Run through the classes and see if we need to compile methods. | 845 // Run through the classes and see if we need to compile methods. |
| 941 for (ClassElement classElement | 846 for (ClassElement classElement |
| 942 in enqueuer.universe.directlyInstantiatedClasses) { | 847 in enqueuer.universe.directlyInstantiatedClasses) { |
| 943 for (ClassElement currentClass = classElement; | 848 for (ClassElement currentClass = classElement; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 } | 922 } |
| 1018 | 923 |
| 1019 typedef void _DeferredActionFunction(); | 924 typedef void _DeferredActionFunction(); |
| 1020 | 925 |
| 1021 class _DeferredAction { | 926 class _DeferredAction { |
| 1022 final Element element; | 927 final Element element; |
| 1023 final _DeferredActionFunction action; | 928 final _DeferredActionFunction action; |
| 1024 | 929 |
| 1025 _DeferredAction(this.element, this.action); | 930 _DeferredAction(this.element, this.action); |
| 1026 } | 931 } |
| OLD | NEW |