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 dart2js; | 5 part of dart2js; |
6 | 6 |
7 typedef ItemCompilationContext ItemCompilationContextCreator(); | 7 typedef ItemCompilationContext ItemCompilationContextCreator(); |
8 | 8 |
9 class EnqueueTask extends CompilerTask { | 9 class EnqueueTask extends CompilerTask { |
10 final ResolutionEnqueuer resolution; | 10 final ResolutionEnqueuer resolution; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 static final TRACE_MIRROR_ENQUEUING = | 42 static final TRACE_MIRROR_ENQUEUING = |
43 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | 43 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); |
44 | 44 |
45 bool queueIsClosed = false; | 45 bool queueIsClosed = false; |
46 EnqueueTask task; | 46 EnqueueTask task; |
47 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 47 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
48 | 48 |
49 bool hasEnqueuedReflectiveElements = false; | 49 bool hasEnqueuedReflectiveElements = false; |
50 bool hasEnqueuedReflectiveStaticFields = false; | 50 bool hasEnqueuedReflectiveStaticFields = false; |
51 | 51 |
52 CompilationInformation get compilationInfo; | 52 DependencyInformation get dependencyInfo; |
sra1
2014/07/30 21:43:48
I would remove this from the enqueuers and do it a
Ty Overby (Google)
2014/08/01 16:39:38
Done.
| |
53 | 53 |
54 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); | 54 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); |
55 | 55 |
56 Queue<WorkItem> get queue; | 56 Queue<WorkItem> get queue; |
57 bool get queueIsEmpty => queue.isEmpty; | 57 bool get queueIsEmpty => queue.isEmpty; |
58 | 58 |
59 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 59 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
60 bool get isResolutionQueue => false; | 60 bool get isResolutionQueue => false; |
61 | 61 |
62 QueueFilter get filter => compiler.enqueuerFilter; | 62 QueueFilter get filter => compiler.enqueuerFilter; |
63 | 63 |
64 /// Returns [:true:] if [member] has been processed by this enqueuer. | 64 /// Returns [:true:] if [member] has been processed by this enqueuer. |
65 bool isProcessed(Element member); | 65 bool isProcessed(Element member); |
66 | 66 |
67 /** | 67 /** |
68 * Documentation wanted -- johnniwinther | 68 * Documentation wanted -- johnniwinther |
69 * | 69 * |
70 * Invariant: [element] must be a declaration element. | 70 * Invariant: [element] must be a declaration element. |
71 */ | 71 */ |
72 void addToWorkList(Element element) { | 72 void addToWorkList(Element element) { |
73 assert(invariant(element, element.isDeclaration)); | 73 assert(invariant(element, element.isDeclaration)); |
74 if (internalAddToWorkList(element)) { | 74 internalAddToWorkList(element); |
75 compilationInfo.addsToWorkList(compiler.currentElement, element); | |
76 } | |
77 } | 75 } |
78 | 76 |
79 /** | 77 /** |
80 * Adds [element] to the work list if it has not already been processed. | 78 * Adds [element] to the work list if it has not already been processed. |
81 * | 79 * |
82 * Returns [true] if the element was actually added to the queue. | 80 * Returns [true] if the element was actually added to the queue. |
83 */ | 81 */ |
84 bool internalAddToWorkList(Element element); | 82 bool internalAddToWorkList(Element element); |
85 | 83 |
86 void registerInstantiatedType(InterfaceType type, Registry registry, | 84 void registerInstantiatedType(InterfaceType type, Registry registry, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 registerClosurizedMember(member, compiler.globalDependencies); | 180 registerClosurizedMember(member, compiler.globalDependencies); |
183 addToWorkList(member); | 181 addToWorkList(member); |
184 return; | 182 return; |
185 } | 183 } |
186 // Store the member in [instanceFunctionsByName] to catch | 184 // Store the member in [instanceFunctionsByName] to catch |
187 // getters on the function. | 185 // getters on the function. |
188 Link<Element> members = instanceFunctionsByName.putIfAbsent( | 186 Link<Element> members = instanceFunctionsByName.putIfAbsent( |
189 memberName, () => const Link<Element>()); | 187 memberName, () => const Link<Element>()); |
190 instanceFunctionsByName[memberName] = members.prepend(member); | 188 instanceFunctionsByName[memberName] = members.prepend(member); |
191 if (universe.hasInvocation(member, compiler)) { | 189 if (universe.hasInvocation(member, compiler)) { |
192 compilationInfo.enqueues(getContext(), member); | |
193 addToWorkList(member); | 190 addToWorkList(member); |
194 return; | 191 return; |
195 } | 192 } |
196 } else if (member.kind == ElementKind.GETTER) { | 193 } else if (member.kind == ElementKind.GETTER) { |
197 if (universe.hasInvokedGetter(member, compiler)) { | 194 if (universe.hasInvokedGetter(member, compiler)) { |
198 addToWorkList(member); | 195 addToWorkList(member); |
199 return; | 196 return; |
200 } | 197 } |
201 // We don't know what selectors the returned closure accepts. If | 198 // We don't know what selectors the returned closure accepts. If |
202 // the set contains any selector we have to assume that it matches. | 199 // the set contains any selector we have to assume that it matches. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 } | 250 } |
254 }); | 251 }); |
255 } | 252 } |
256 | 253 |
257 void registerNewSelector(Element context, | 254 void registerNewSelector(Element context, |
258 Selector selector, | 255 Selector selector, |
259 Map<String, Set<Selector>> selectorsMap) { | 256 Map<String, Set<Selector>> selectorsMap) { |
260 String name = selector.name; | 257 String name = selector.name; |
261 Set<Selector> selectors = | 258 Set<Selector> selectors = |
262 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); | 259 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); |
260 dependencyInfo.elementUsesSelector(context, selector); | |
sra1
2014/07/30 21:43:48
If we move this to CodegenRegistry, we can get rid
Ty Overby (Google)
2014/08/01 16:39:37
Done.
| |
263 if (!selectors.contains(selector)) { | 261 if (!selectors.contains(selector)) { |
264 selectors.add(selector); | 262 selectors.add(selector); |
265 handleUnseenSelector(context, name, selector); | 263 handleUnseenSelector(context, name, selector); |
266 } | 264 } |
267 } | 265 } |
268 | 266 |
269 void registerInvocation(Element context, Selector selector) { | 267 void registerInvocation(Element context, Selector selector) { |
270 task.measure(() { | 268 task.measure(() { |
271 registerNewSelector(context, selector, universe.invokedNames); | 269 registerNewSelector(context, selector, universe.invokedNames); |
272 }); | 270 }); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 } | 469 } |
472 | 470 |
473 processInstanceFunctions(String n, bool f(Element e)) { | 471 processInstanceFunctions(String n, bool f(Element e)) { |
474 processLink(instanceFunctionsByName, n, f); | 472 processLink(instanceFunctionsByName, n, f); |
475 } | 473 } |
476 | 474 |
477 void handleUnseenSelector(Element context, | 475 void handleUnseenSelector(Element context, |
478 String methodName, | 476 String methodName, |
479 Selector selector) { | 477 Selector selector) { |
480 processInstanceMembers(methodName, (Element member) { | 478 processInstanceMembers(methodName, (Element member) { |
481 compilationInfo.enqueues(context, member); | |
482 if (selector.appliesUnnamed(member, compiler)) { | 479 if (selector.appliesUnnamed(member, compiler)) { |
483 if (member.isFunction && selector.isGetter) { | 480 if (member.isFunction && selector.isGetter) { |
484 registerClosurizedMember(member, compiler.globalDependencies); | 481 registerClosurizedMember(member, compiler.globalDependencies); |
485 } | 482 } |
486 if (member.isField && member.enclosingClass.isNative) { | 483 if (member.isField && member.enclosingClass.isNative) { |
487 if (selector.isGetter || selector.isCall) { | 484 if (selector.isGetter || selector.isCall) { |
488 nativeEnqueuer.registerFieldLoad(member); | 485 nativeEnqueuer.registerFieldLoad(member); |
489 // We have to also handle storing to the field because we only get | 486 // We have to also handle storing to the field because we only get |
490 // one look at each member and there might be a store we have not | 487 // one look at each member and there might be a store we have not |
491 // seen yet. | 488 // seen yet. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 final Set<AstElement> resolvedElements; | 653 final Set<AstElement> resolvedElements; |
657 | 654 |
658 final Queue<ResolutionWorkItem> queue; | 655 final Queue<ResolutionWorkItem> queue; |
659 | 656 |
660 /** | 657 /** |
661 * A deferred task queue for the resolution phase which is processed | 658 * A deferred task queue for the resolution phase which is processed |
662 * when the resolution queue has been emptied. | 659 * when the resolution queue has been emptied. |
663 */ | 660 */ |
664 final Queue<DeferredTask> deferredTaskQueue; | 661 final Queue<DeferredTask> deferredTaskQueue; |
665 | 662 |
666 CompilationInformation compilationInfo; | 663 DependencyInformation dependencyInfo; |
667 | 664 |
668 ResolutionEnqueuer(Compiler compiler, | 665 ResolutionEnqueuer(Compiler compiler, |
669 ItemCompilationContext itemCompilationContextCreator()) | 666 ItemCompilationContext itemCompilationContextCreator()) |
670 : super('resolution enqueuer', compiler, itemCompilationContextCreator), | 667 : super('resolution enqueuer', compiler, itemCompilationContextCreator), |
671 resolvedElements = new Set<AstElement>(), | 668 resolvedElements = new Set<AstElement>(), |
672 queue = new Queue<ResolutionWorkItem>(), | 669 queue = new Queue<ResolutionWorkItem>(), |
673 deferredTaskQueue = new Queue<DeferredTask>() { | 670 deferredTaskQueue = new Queue<DeferredTask>() { |
674 compilationInfo = new CompilationInformation(this, compiler.dumpInfo); | 671 dependencyInfo = new DependencyInformation(this, compiler.dumpInfo); |
675 } | 672 } |
676 | 673 |
677 bool get isResolutionQueue => true; | 674 bool get isResolutionQueue => true; |
678 | 675 |
679 bool isProcessed(Element member) => resolvedElements.contains(member); | 676 bool isProcessed(Element member) => resolvedElements.contains(member); |
680 | 677 |
681 /// Returns `true` if [element] has been processed by the resolution enqueuer. | 678 /// Returns `true` if [element] has been processed by the resolution enqueuer. |
682 bool hasBeenResolved(Element element) { | 679 bool hasBeenResolved(Element element) { |
683 return resolvedElements.contains(element.analyzableElement.declaration); | 680 return resolvedElements.contains(element.analyzableElement.declaration); |
684 } | 681 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
808 } | 805 } |
809 | 806 |
810 /// [Enqueuer] which is specific to code generation. | 807 /// [Enqueuer] which is specific to code generation. |
811 class CodegenEnqueuer extends Enqueuer { | 808 class CodegenEnqueuer extends Enqueuer { |
812 final Queue<CodegenWorkItem> queue; | 809 final Queue<CodegenWorkItem> queue; |
813 final Map<Element, js.Expression> generatedCode = | 810 final Map<Element, js.Expression> generatedCode = |
814 new Map<Element, js.Expression>(); | 811 new Map<Element, js.Expression>(); |
815 | 812 |
816 final Set<Element> newlyEnqueuedElements; | 813 final Set<Element> newlyEnqueuedElements; |
817 | 814 |
818 CompilationInformation compilationInfo; | 815 DependencyInformation dependencyInfo; |
819 | 816 |
820 CodegenEnqueuer(Compiler compiler, | 817 CodegenEnqueuer(Compiler compiler, |
821 ItemCompilationContext itemCompilationContextCreator()) | 818 ItemCompilationContext itemCompilationContextCreator()) |
822 : queue = new Queue<CodegenWorkItem>(), | 819 : queue = new Queue<CodegenWorkItem>(), |
823 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 820 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
824 super('codegen enqueuer', compiler, itemCompilationContextCreator) { | 821 super('codegen enqueuer', compiler, itemCompilationContextCreator) { |
825 compilationInfo = new CompilationInformation(this, compiler.dumpInfo); | 822 dependencyInfo = new DependencyInformation(this, compiler.dumpInfo); |
826 } | 823 } |
827 | 824 |
828 bool isProcessed(Element member) => | 825 bool isProcessed(Element member) => |
829 member.isAbstract || generatedCode.containsKey(member); | 826 member.isAbstract || generatedCode.containsKey(member); |
830 | 827 |
831 /** | 828 /** |
832 * Decides whether an element should be included to satisfy requirements | 829 * Decides whether an element should be included to satisfy requirements |
833 * of the mirror system. | 830 * of the mirror system. |
834 * | 831 * |
835 * For code generation, we rely on the precomputed set of elements that takes | 832 * For code generation, we rely on the precomputed set of elements that takes |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
884 } | 881 } |
885 } | 882 } |
886 }); | 883 }); |
887 return true; | 884 return true; |
888 } | 885 } |
889 | 886 |
890 void processWorkItem(void f(WorkItem work), WorkItem work) { | 887 void processWorkItem(void f(WorkItem work), WorkItem work) { |
891 f(work); | 888 f(work); |
892 } | 889 } |
893 } | 890 } |
OLD | NEW |