Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 430913002: Better dependency tracking (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix self critiques Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698