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

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

Issue 26662006: Changed LinkedHashSet to Set and LinkedHashMap to Map. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: HashMap -> Map. Created 7 years, 2 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 deferred_load; 5 library deferred_load;
6 6
7 import 'dart:collection'
8 show LinkedHashMap,
9 LinkedHashSet;
10
11 import 'dart2jslib.dart' 7 import 'dart2jslib.dart'
12 show Compiler, 8 show Compiler,
13 CompilerTask, 9 CompilerTask,
14 ConstructedConstant, 10 ConstructedConstant,
15 MessageKind, 11 MessageKind,
16 SourceString, 12 SourceString,
17 StringConstant; 13 StringConstant;
18 14
19 import 'elements/elements.dart' 15 import 'elements/elements.dart'
20 show ClassElement, 16 show ClassElement,
21 Element, 17 Element,
22 Elements, 18 Elements,
23 FunctionElement, 19 FunctionElement,
24 LibraryElement, 20 LibraryElement,
25 MetadataAnnotation, 21 MetadataAnnotation,
26 ScopeContainerElement; 22 ScopeContainerElement;
27 23
28 import 'util/util.dart' 24 import 'util/util.dart'
29 show Link; 25 show Link;
30 26
31 import 'tree/tree.dart' 27 import 'tree/tree.dart'
32 show LibraryTag, 28 show LibraryTag,
33 Node, 29 Node,
34 Visitor; 30 Visitor;
35 31
36 import 'resolution/resolution.dart' 32 import 'resolution/resolution.dart'
37 show TreeElements; 33 show TreeElements;
38 34
39 class DeferredLoadTask extends CompilerTask { 35 class DeferredLoadTask extends CompilerTask {
40 final Set<LibraryElement> deferredLibraries = 36 final Set<LibraryElement> deferredLibraries = new Set<LibraryElement>();
41 new LinkedHashSet<LibraryElement>();
42 37
43 /// Records all elements that are deferred. 38 /// Records all elements that are deferred.
44 /// 39 ///
45 /// Long term, we want to split deferred element into more than one 40 /// Long term, we want to split deferred element into more than one
46 /// file (one for each library that is deferred), and this field 41 /// file (one for each library that is deferred), and this field
47 /// should become obsolete. 42 /// should become obsolete.
48 final Set<Element> allDeferredElements = new LinkedHashSet<Element>(); 43 final Set<Element> allDeferredElements = new Set<Element>();
49 44
50 DeferredLoadTask(Compiler compiler) : super(compiler); 45 DeferredLoadTask(Compiler compiler) : super(compiler);
51 46
52 String get name => 'Deferred Loading'; 47 String get name => 'Deferred Loading';
53 48
54 /// DeferredLibrary from dart:async 49 /// DeferredLibrary from dart:async
55 ClassElement get deferredLibraryClass => compiler.deferredLibraryClass; 50 ClassElement get deferredLibraryClass => compiler.deferredLibraryClass;
56 51
57 bool get areAnyElementsDeferred => !allDeferredElements.isEmpty; 52 bool get areAnyElementsDeferred => !allDeferredElements.isEmpty;
58 53
(...skipping 12 matching lines...) Expand all
71 LibraryElement mainApp = main.getLibrary(); 66 LibraryElement mainApp = main.getLibrary();
72 measureElement(mainApp, () { 67 measureElement(mainApp, () {
73 deferredLibraries.addAll(findDeferredLibraries(mainApp).toList()); 68 deferredLibraries.addAll(findDeferredLibraries(mainApp).toList());
74 if (deferredLibraries.isEmpty) return; 69 if (deferredLibraries.isEmpty) return;
75 70
76 // TODO(ahe): Enforce the following invariants on 71 // TODO(ahe): Enforce the following invariants on
77 // [deferredElements] and [eagerElements]: 72 // [deferredElements] and [eagerElements]:
78 // 1. Only static or top-level elements are recorded. 73 // 1. Only static or top-level elements are recorded.
79 // 2. Only implementation is stored. 74 // 2. Only implementation is stored.
80 Map<LibraryElement, Set<Element>> deferredElements = 75 Map<LibraryElement, Set<Element>> deferredElements =
81 new LinkedHashMap<LibraryElement, Set<Element>>(); 76 new Map<LibraryElement, Set<Element>>();
82 Set<Element> eagerElements = new LinkedHashSet<Element>(); 77 Set<Element> eagerElements = new Set<Element>();
83 78
84 // Iterate through live local members of the main script. Create 79 // Iterate through live local members of the main script. Create
85 // a root-set of elements that must be loaded eagerly 80 // a root-set of elements that must be loaded eagerly
86 // (everything that is directly referred to from the main 81 // (everything that is directly referred to from the main
87 // script, but not imported from a deferred library), as well as 82 // script, but not imported from a deferred library), as well as
88 // root-sets for deferred libraries. 83 // root-sets for deferred libraries.
89 mainApp.forEachLocalMember((Element e) { 84 mainApp.forEachLocalMember((Element e) {
90 if (compiler.enqueuer.resolution.isLive(e)) { 85 if (compiler.enqueuer.resolution.isLive(e)) {
91 for (Element dependency in allElementsResolvedFrom(e)) { 86 for (Element dependency in allElementsResolvedFrom(e)) {
92 if (isExplicitlyDeferred(dependency)) { 87 if (isExplicitlyDeferred(dependency)) {
93 Set<Element> deferredElementsFromLibrary = 88 Set<Element> deferredElementsFromLibrary =
94 deferredElements.putIfAbsent( 89 deferredElements.putIfAbsent(
95 dependency.getLibrary(), 90 dependency.getLibrary(),
96 () => new LinkedHashSet<Element>()); 91 () => new Set<Element>());
97 deferredElementsFromLibrary.add(dependency); 92 deferredElementsFromLibrary.add(dependency);
98 } else if (dependency.getLibrary() != mainApp) { 93 } else if (dependency.getLibrary() != mainApp) {
99 eagerElements.add(dependency.implementation); 94 eagerElements.add(dependency.implementation);
100 } 95 }
101 } 96 }
102 } 97 }
103 }); 98 });
104 99
105 // Also add "global" dependencies to the eager root-set. These 100 // Also add "global" dependencies to the eager root-set. These
106 // are things that the backend need but cannot associate with a 101 // are things that the backend need but cannot associate with a
107 // particular element, for example, startRootIsolate. This set 102 // particular element, for example, startRootIsolate. This set
108 // also contains elements for which we lack precise information. 103 // also contains elements for which we lack precise information.
109 eagerElements.addAll(compiler.globalDependencies.otherDependencies); 104 eagerElements.addAll(compiler.globalDependencies.otherDependencies);
110 105
111 addTransitiveClosureTo(eagerElements); 106 addTransitiveClosureTo(eagerElements);
112 107
113 for (Set<Element> e in deferredElements.values) { 108 for (Set<Element> e in deferredElements.values) {
114 addTransitiveClosureTo(e); 109 addTransitiveClosureTo(e);
115 e.removeAll(eagerElements); 110 e.removeAll(eagerElements);
116 for (Element element in e) { 111 for (Element element in e) {
117 allDeferredElements.add(element); 112 allDeferredElements.add(element);
118 } 113 }
119 } 114 }
120 115
121 // TODO(ahe): The following code has no effect yet. I'm 116 // TODO(ahe): The following code has no effect yet. I'm
122 // including it as a comment for how to extend this to support 117 // including it as a comment for how to extend this to support
123 // multiple deferred files. 118 // multiple deferred files.
124 Map<Element, List<LibraryElement>> reverseMap = 119 Map<Element, List<LibraryElement>> reverseMap =
125 new LinkedHashMap<Element, List<LibraryElement>>(); 120 new Map<Element, List<LibraryElement>>();
126 121
127 deferredElements.forEach((LibraryElement library, Set<Element> map) { 122 deferredElements.forEach((LibraryElement library, Set<Element> map) {
128 for (Element element in map) { 123 for (Element element in map) {
129 List<LibraryElement> libraries = 124 List<LibraryElement> libraries =
130 reverseMap.putIfAbsent(element, () => <LibraryElement>[]); 125 reverseMap.putIfAbsent(element, () => <LibraryElement>[]);
131 libraries.add(library); 126 libraries.add(library);
132 } 127 }
133 }); 128 });
134 129
135 // Now compute the output files based on the lists in reverseMap. 130 // Now compute the output files based on the lists in reverseMap.
136 // TODO(ahe): Do that. 131 // TODO(ahe): Do that.
137 }); 132 });
138 } 133 }
139 134
140 /// Returns all elements in the tree map of [element], but not the 135 /// Returns all elements in the tree map of [element], but not the
141 /// transitive closure. 136 /// transitive closure.
142 Set<Element> allElementsResolvedFrom(Element element) { 137 Set<Element> allElementsResolvedFrom(Element element) {
143 element = element.implementation; 138 element = element.implementation;
144 Set<Element> result = new LinkedHashSet<Element>(); 139 Set<Element> result = new Set<Element>();
145 if (element.isGenerativeConstructor()) { 140 if (element.isGenerativeConstructor()) {
146 // When instantiating a class, we record a reference to the 141 // When instantiating a class, we record a reference to the
147 // constructor, not the class itself. We must add all the 142 // constructor, not the class itself. We must add all the
148 // instance members of the constructor's class (see below). 143 // instance members of the constructor's class (see below).
149 result.addAll( 144 result.addAll(
150 allElementsResolvedFrom(element.getEnclosingClass().implementation)); 145 allElementsResolvedFrom(element.getEnclosingClass().implementation));
151 } 146 }
152 if (element.isClass()) { 147 if (element.isClass()) {
153 // If we see a class, add everything its instance members refer 148 // If we see a class, add everything its instance members refer
154 // to. Static members are not relevant. 149 // to. Static members are not relevant.
(...skipping 17 matching lines...) Expand all
172 } else if (Elements.isStaticOrTopLevel(element) 167 } else if (Elements.isStaticOrTopLevel(element)
173 || element.isConstructor()) { 168 || element.isConstructor()) {
174 result.addAll(DependencyCollector.collect(element, compiler)); 169 result.addAll(DependencyCollector.collect(element, compiler));
175 } 170 }
176 // Other elements, in particular instance members, are ignored as 171 // Other elements, in particular instance members, are ignored as
177 // they are processed as part of the class. 172 // they are processed as part of the class.
178 return result; 173 return result;
179 } 174 }
180 175
181 void addTransitiveClosureTo(Set<Element> elements) { 176 void addTransitiveClosureTo(Set<Element> elements) {
182 Set<Element> workSet = new LinkedHashSet.from(elements); 177 Set<Element> workSet = new Set.from(elements);
183 Set<Element> closure = new LinkedHashSet<Element>(); 178 Set<Element> closure = new Set<Element>();
184 while (!workSet.isEmpty) { 179 while (!workSet.isEmpty) {
185 Element current = workSet.first; 180 Element current = workSet.first;
186 workSet.remove(current); 181 workSet.remove(current);
187 if (closure.contains(current)) continue; 182 if (closure.contains(current)) continue;
188 workSet.addAll(allElementsResolvedFrom(current)); 183 workSet.addAll(allElementsResolvedFrom(current));
189 closure.add(current); 184 closure.add(current);
190 } 185 }
191 elements.addAll(closure); 186 elements.addAll(closure);
192 } 187 }
193 188
(...skipping 23 matching lines...) Expand all
217 'actualName': actualName.slowToString()}); 212 'actualName': actualName.slowToString()});
218 } 213 }
219 } 214 }
220 } 215 }
221 } 216 }
222 return link; 217 return link;
223 } 218 }
224 } 219 }
225 220
226 class DependencyCollector extends Visitor { 221 class DependencyCollector extends Visitor {
227 final Set<Element> dependencies = new LinkedHashSet<Element>(); 222 final Set<Element> dependencies = new Set<Element>();
228 final TreeElements elements; 223 final TreeElements elements;
229 final Compiler compiler; 224 final Compiler compiler;
230 225
231 DependencyCollector(this.elements, this.compiler); 226 DependencyCollector(this.elements, this.compiler);
232 227
233 visitNode(Node node) { 228 visitNode(Node node) {
234 node.visitChildren(this); 229 node.visitChildren(this);
235 Element dependency = elements[node]; 230 Element dependency = elements[node];
236 if (Elements.isUnresolved(dependency)) return; 231 if (Elements.isUnresolved(dependency)) return;
237 dependencies.add(dependency.implementation); 232 dependencies.add(dependency.implementation);
238 } 233 }
239 234
240 static Set<Element> collect(Element element, Compiler compiler) { 235 static Set<Element> collect(Element element, Compiler compiler) {
241 TreeElements elements = 236 TreeElements elements =
242 compiler.enqueuer.resolution.getCachedElements(element); 237 compiler.enqueuer.resolution.getCachedElements(element);
243 if (elements == null) return new LinkedHashSet<Element>(); 238 if (elements == null) return new Set<Element>();
244 Node node = element.parseNode(compiler); 239 Node node = element.parseNode(compiler);
245 if (node == null) return new LinkedHashSet<Element>(); 240 if (node == null) return new Set<Element>();
246 var collector = new DependencyCollector(elements, compiler); 241 var collector = new DependencyCollector(elements, compiler);
247 node.accept(collector); 242 node.accept(collector);
248 collector.dependencies.addAll(elements.otherDependencies); 243 collector.dependencies.addAll(elements.otherDependencies);
249 return collector.dependencies; 244 return collector.dependencies;
250 } 245 }
251 } 246 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698