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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder/collector.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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.js_emitter.program_builder; 5 part of dart2js.js_emitter.program_builder;
6 6
7 /** 7 /**
8 * Generates the code for all used classes in the program. Static fields (even 8 * Generates the code for all used classes in the program. Static fields (even
9 * in classes) are ignored, since they can be treated as non-class elements. 9 * in classes) are ignored, since they can be treated as non-class elements.
10 * 10 *
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true; 69 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true;
70 70
71 Set<ClassElement> unneededClasses = new Set<ClassElement>(); 71 Set<ClassElement> unneededClasses = new Set<ClassElement>();
72 // The [Bool] class is not marked as abstract, but has a factory 72 // The [Bool] class is not marked as abstract, but has a factory
73 // constructor that always throws. We never need to emit it. 73 // constructor that always throws. We never need to emit it.
74 unneededClasses.add(coreClasses.boolClass); 74 unneededClasses.add(coreClasses.boolClass);
75 75
76 // Go over specialized interceptors and then constants to know which 76 // Go over specialized interceptors and then constants to know which
77 // interceptors are needed. 77 // interceptors are needed.
78 Set<ClassElement> needed = new Set<ClassElement>(); 78 Set<ClassElement> needed = new Set<ClassElement>();
79 backend.specializedGetInterceptors.forEach( 79 backend.specializedGetInterceptors
80 (_, Iterable<ClassElement> elements) { 80 .forEach((_, Iterable<ClassElement> elements) {
81 needed.addAll(elements); 81 needed.addAll(elements);
82 } 82 });
83 );
84 83
85 // Add interceptors referenced by constants. 84 // Add interceptors referenced by constants.
86 needed.addAll(computeInterceptorsReferencedFromConstants()); 85 needed.addAll(computeInterceptorsReferencedFromConstants());
87 86
88 // Add unneeded interceptors to the [unneededClasses] set. 87 // Add unneeded interceptors to the [unneededClasses] set.
89 for (ClassElement interceptor in backend.interceptedClasses) { 88 for (ClassElement interceptor in backend.interceptedClasses) {
90 if (!needed.contains(interceptor) 89 if (!needed.contains(interceptor) &&
91 && interceptor != coreClasses.objectClass) { 90 interceptor != coreClasses.objectClass) {
92 unneededClasses.add(interceptor); 91 unneededClasses.add(interceptor);
93 } 92 }
94 } 93 }
95 94
96 // These classes are just helpers for the backend's type system. 95 // These classes are just helpers for the backend's type system.
97 unneededClasses.add(helpers.jsMutableArrayClass); 96 unneededClasses.add(helpers.jsMutableArrayClass);
98 unneededClasses.add(helpers.jsFixedArrayClass); 97 unneededClasses.add(helpers.jsFixedArrayClass);
99 unneededClasses.add(helpers.jsExtendableArrayClass); 98 unneededClasses.add(helpers.jsExtendableArrayClass);
100 unneededClasses.add(helpers.jsUInt32Class); 99 unneededClasses.add(helpers.jsUInt32Class);
101 unneededClasses.add(helpers.jsUInt31Class); 100 unneededClasses.add(helpers.jsUInt31Class);
102 unneededClasses.add(helpers.jsPositiveIntClass); 101 unneededClasses.add(helpers.jsPositiveIntClass);
103 102
104 return (ClassElement cls) => !unneededClasses.contains(cls); 103 return (ClassElement cls) => !unneededClasses.contains(cls);
105 } 104 }
106 105
107 /** 106 /**
108 * Compute all the constants that must be emitted. 107 * Compute all the constants that must be emitted.
109 */ 108 */
110 void computeNeededConstants() { 109 void computeNeededConstants() {
111 // Make sure we retain all metadata of all elements. This could add new 110 // Make sure we retain all metadata of all elements. This could add new
112 // constants to the handler. 111 // constants to the handler.
113 if (backend.mustRetainMetadata) { 112 if (backend.mustRetainMetadata) {
114 // TODO(floitsch): verify that we don't run through the same elements 113 // TODO(floitsch): verify that we don't run through the same elements
115 // multiple times. 114 // multiple times.
116 for (Element element in backend.generatedCode.keys) { 115 for (Element element in backend.generatedCode.keys) {
117 if (backend.isAccessibleByReflection(element)) { 116 if (backend.isAccessibleByReflection(element)) {
118 bool shouldRetainMetadata = backend.retainMetadataOf(element); 117 bool shouldRetainMetadata = backend.retainMetadataOf(element);
119 if (shouldRetainMetadata && 118 if (shouldRetainMetadata &&
120 (element.isFunction || element.isConstructor || 119 (element.isFunction ||
121 element.isSetter)) { 120 element.isConstructor ||
121 element.isSetter)) {
122 FunctionElement function = element; 122 FunctionElement function = element;
123 function.functionSignature.forEachParameter( 123 function.functionSignature
124 backend.retainMetadataOf); 124 .forEachParameter(backend.retainMetadataOf);
125 } 125 }
126 } 126 }
127 } 127 }
128 for (ClassElement cls in neededClasses) { 128 for (ClassElement cls in neededClasses) {
129 final onlyForRti = classesOnlyNeededForRti.contains(cls); 129 final onlyForRti = classesOnlyNeededForRti.contains(cls);
130 if (!onlyForRti) { 130 if (!onlyForRti) {
131 backend.retainMetadataOf(cls); 131 backend.retainMetadataOf(cls);
132 new FieldVisitor(compiler, namer).visitFields(cls, false, 132 new FieldVisitor(compiler, namer).visitFields(cls, false,
133 (Element member, 133 (Element member, js.Name name, js.Name accessorName,
134 js.Name name, 134 bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
135 js.Name accessorName,
136 bool needsGetter,
137 bool needsSetter,
138 bool needsCheckedSetter) {
139 bool needsAccessor = needsGetter || needsSetter; 135 bool needsAccessor = needsGetter || needsSetter;
140 if (needsAccessor && backend.isAccessibleByReflection(member)) { 136 if (needsAccessor && backend.isAccessibleByReflection(member)) {
141 backend.retainMetadataOf(member); 137 backend.retainMetadataOf(member);
142 } 138 }
143 }); 139 });
144 } 140 }
145 } 141 }
146 typedefsNeededForReflection.forEach(backend.retainMetadataOf); 142 typedefsNeededForReflection.forEach(backend.retainMetadataOf);
147 } 143 }
148 144
149 JavaScriptConstantCompiler handler = backend.constants; 145 JavaScriptConstantCompiler handler = backend.constants;
150 List<ConstantValue> constants = handler.getConstantsForEmission( 146 List<ConstantValue> constants = handler.getConstantsForEmission(compiler
151 compiler.options.hasIncrementalSupport ? null 147 .options.hasIncrementalSupport ? null : emitter.compareConstants);
152 : emitter.compareConstants);
153 for (ConstantValue constant in constants) { 148 for (ConstantValue constant in constants) {
154 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; 149 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue;
155 150
156 if (constant.isList) outputContainsConstantList = true; 151 if (constant.isList) outputContainsConstantList = true;
157 152
158 OutputUnit constantUnit = 153 OutputUnit constantUnit =
159 compiler.deferredLoadTask.outputUnitForConstant(constant); 154 compiler.deferredLoadTask.outputUnitForConstant(constant);
160 if (constantUnit == null) { 155 if (constantUnit == null) {
161 // The back-end introduces some constants, like "InterceptorConstant" or 156 // The back-end introduces some constants, like "InterceptorConstant" or
162 // some list constants. They are emitted in the main output-unit. 157 // some list constants. They are emitted in the main output-unit.
163 // TODO(sigurdm): We should track those constants. 158 // TODO(sigurdm): We should track those constants.
164 constantUnit = compiler.deferredLoadTask.mainOutputUnit; 159 constantUnit = compiler.deferredLoadTask.mainOutputUnit;
165 } 160 }
166 outputConstantLists.putIfAbsent( 161 outputConstantLists
167 constantUnit, () => new List<ConstantValue>()).add(constant); 162 .putIfAbsent(constantUnit, () => new List<ConstantValue>())
163 .add(constant);
168 } 164 }
169 } 165 }
170 166
171 /// Compute all the classes and typedefs that must be emitted. 167 /// Compute all the classes and typedefs that must be emitted.
172 void computeNeededDeclarations() { 168 void computeNeededDeclarations() {
173 // Compute needed typedefs. 169 // Compute needed typedefs.
174 typedefsNeededForReflection = Elements.sortedByPosition( 170 typedefsNeededForReflection = Elements.sortedByPosition(compiler
175 compiler.world.allTypedefs 171 .world.allTypedefs
176 .where(backend.isAccessibleByReflection) 172 .where(backend.isAccessibleByReflection)
177 .toList()); 173 .toList());
178 174
179 // Compute needed classes. 175 // Compute needed classes.
180 Set<ClassElement> instantiatedClasses = 176 Set<ClassElement> instantiatedClasses = compiler
181 compiler.codegenWorld.directlyInstantiatedClasses 177 .codegenWorld.directlyInstantiatedClasses
182 .where(computeClassFilter()).toSet(); 178 .where(computeClassFilter())
179 .toSet();
183 180
184 void addClassWithSuperclasses(ClassElement cls) { 181 void addClassWithSuperclasses(ClassElement cls) {
185 neededClasses.add(cls); 182 neededClasses.add(cls);
186 for (ClassElement superclass = cls.superclass; 183 for (ClassElement superclass = cls.superclass;
187 superclass != null; 184 superclass != null;
188 superclass = superclass.superclass) { 185 superclass = superclass.superclass) {
189 neededClasses.add(superclass); 186 neededClasses.add(superclass);
190 } 187 }
191 } 188 }
192 189
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 } 235 }
239 236
240 // 4. Finally, sort the classes. 237 // 4. Finally, sort the classes.
241 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); 238 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
242 239
243 for (ClassElement element in sortedClasses) { 240 for (ClassElement element in sortedClasses) {
244 if (backend.isNativeOrExtendsNative(element) && 241 if (backend.isNativeOrExtendsNative(element) &&
245 !classesOnlyNeededForRti.contains(element)) { 242 !classesOnlyNeededForRti.contains(element)) {
246 // For now, native classes and related classes cannot be deferred. 243 // For now, native classes and related classes cannot be deferred.
247 nativeClassesAndSubclasses.add(element); 244 nativeClassesAndSubclasses.add(element);
248 assert(invariant(element, 245 assert(
249 !compiler.deferredLoadTask.isDeferred(element))); 246 invariant(element, !compiler.deferredLoadTask.isDeferred(element)));
250 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, 247 outputClassLists
251 () => new List<ClassElement>()).add(element); 248 .putIfAbsent(compiler.deferredLoadTask.mainOutputUnit,
249 () => new List<ClassElement>())
250 .add(element);
252 } else { 251 } else {
253 outputClassLists.putIfAbsent( 252 outputClassLists
254 compiler.deferredLoadTask.outputUnitForElement(element), 253 .putIfAbsent(
255 () => new List<ClassElement>()) 254 compiler.deferredLoadTask.outputUnitForElement(element),
255 () => new List<ClassElement>())
256 .add(element); 256 .add(element);
257 } 257 }
258 } 258 }
259 } 259 }
260 260
261 void computeNeededStatics() { 261 void computeNeededStatics() {
262 bool isStaticFunction(Element element) => 262 bool isStaticFunction(Element element) =>
263 !element.isInstanceMember && !element.isField; 263 !element.isInstanceMember && !element.isField;
264 264
265 Iterable<Element> elements = 265 Iterable<Element> elements =
266 backend.generatedCode.keys.where(isStaticFunction); 266 backend.generatedCode.keys.where(isStaticFunction);
267 267
268 for (Element element in Elements.sortedByPosition(elements)) { 268 for (Element element in Elements.sortedByPosition(elements)) {
269 List<Element> list = outputStaticLists.putIfAbsent( 269 List<Element> list = outputStaticLists.putIfAbsent(
270 compiler.deferredLoadTask.outputUnitForElement(element), 270 compiler.deferredLoadTask.outputUnitForElement(element),
271 () => new List<Element>()); 271 () => new List<Element>());
272 list.add(element); 272 list.add(element);
273 } 273 }
274 } 274 }
275 275
276 void computeNeededStaticNonFinalFields() { 276 void computeNeededStaticNonFinalFields() {
277 JavaScriptConstantCompiler handler = backend.constants; 277 JavaScriptConstantCompiler handler = backend.constants;
278 addToOutputUnit(Element element) { 278 addToOutputUnit(Element element) {
279 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( 279 List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent(
280 compiler.deferredLoadTask.outputUnitForElement(element), 280 compiler.deferredLoadTask.outputUnitForElement(element),
281 () => new List<VariableElement>()); 281 () => new List<VariableElement>());
282 list.add(element); 282 list.add(element);
283 } 283 }
284 284
285 Iterable<VariableElement> staticNonFinalFields = handler 285 Iterable<VariableElement> staticNonFinalFields = handler
286 .getStaticNonFinalFieldsForEmission() 286 .getStaticNonFinalFieldsForEmission()
287 .where(compiler.codegenWorld.allReferencedStaticFields.contains); 287 .where(compiler.codegenWorld.allReferencedStaticFields.contains);
288 288
289 Elements.sortedByPosition(staticNonFinalFields).forEach(addToOutputUnit); 289 Elements.sortedByPosition(staticNonFinalFields).forEach(addToOutputUnit);
290 290
291 // We also need to emit static const fields if they are available for 291 // We also need to emit static const fields if they are available for
292 // reflection. 292 // reflection.
293 compiler.codegenWorld.allReferencedStaticFields 293 compiler.codegenWorld.allReferencedStaticFields
294 .where((FieldElement field) => field.isConst) 294 .where((FieldElement field) => field.isConst)
295 .where(backend.isAccessibleByReflection) 295 .where(backend.isAccessibleByReflection)
296 .forEach(addToOutputUnit); 296 .forEach(addToOutputUnit);
297 } 297 }
298 298
299 void computeNeededLibraries() { 299 void computeNeededLibraries() {
300 void addSurroundingLibraryToSet(Element element) { 300 void addSurroundingLibraryToSet(Element element) {
301 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element); 301 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element);
302 LibraryElement library = element.library; 302 LibraryElement library = element.library;
303 outputLibraryLists.putIfAbsent(unit, () => new Set<LibraryElement>()) 303 outputLibraryLists
304 .putIfAbsent(unit, () => new Set<LibraryElement>())
304 .add(library); 305 .add(library);
305 } 306 }
306 307
307 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); 308 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet);
308 neededClasses.forEach(addSurroundingLibraryToSet); 309 neededClasses.forEach(addSurroundingLibraryToSet);
309 } 310 }
310 311
311 void collect() { 312 void collect() {
312 computeNeededDeclarations(); 313 computeNeededDeclarations();
313 computeNeededConstants(); 314 computeNeededConstants();
314 computeNeededStatics(); 315 computeNeededStatics();
315 computeNeededStaticNonFinalFields(); 316 computeNeededStaticNonFinalFields();
316 computeNeededLibraries(); 317 computeNeededLibraries();
317 } 318 }
318 } 319 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698