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

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

Issue 656043003: dart2js: restructure emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 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) 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.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter"); 7 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter");
8 8
9 /** 9 /**
10 * Generates the code for all used classes in the program. Static fields (even 10 * Generates the code for all used classes in the program. Static fields (even
11 * in classes) are ignored, since they can be treated as non-class elements. 11 * in classes) are ignored, since they can be treated as non-class elements.
12 * 12 *
13 * The code for the containing (used) methods must exist in the [:universe:]. 13 * The code for the containing (used) methods must exist in the [:universe:].
14 */ 14 */
15 class CodeEmitterTask extends CompilerTask { 15 class CodeEmitterTask extends CompilerTask {
16 // TODO(floitsch): the code-emitter task should not need a namer. 16 // TODO(floitsch): the code-emitter task should not need a namer.
17 final Namer namer; 17 final Namer namer;
18 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter(); 18 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter();
19 NativeEmitter nativeEmitter; 19 NativeEmitter nativeEmitter;
20 OldEmitter oldEmitter; 20 OldEmitter oldEmitter;
21 Emitter emitter; 21 Emitter emitter;
22 22
23 final Set<ClassElement> neededClasses = new Set<ClassElement>(); 23 final Set<ClassElement> neededClasses = new Set<ClassElement>();
24 final Map<OutputUnit, List<ClassElement>> outputClassLists = 24 final Map<OutputUnit, List<ClassElement>> outputClassLists =
25 new Map<OutputUnit, List<ClassElement>>(); 25 new Map<OutputUnit, List<ClassElement>>();
26 final Map<OutputUnit, List<ConstantValue>> outputConstantLists = 26 final Map<OutputUnit, List<ConstantValue>> outputConstantLists =
27 new Map<OutputUnit, List<ConstantValue>>(); 27 new Map<OutputUnit, List<ConstantValue>>();
28 final Map<OutputUnit, List<Element>> outputStaticLists =
29 new Map<OutputUnit, List<Element>>();
30 final Map<OutputUnit, Set<LibraryElement>> outputLibraryLists =
31 new Map<OutputUnit, Set<LibraryElement>>();
32
33 /// True, if the output contains a constant list.
34 ///
35 /// This flag is updated in [computeNeededConstants].
36 bool outputContainsConstantList = false;
37
28 final List<ClassElement> nativeClasses = <ClassElement>[]; 38 final List<ClassElement> nativeClasses = <ClassElement>[];
29 39
30 /// Records if a type variable is read dynamically for type tests. 40 /// Records if a type variable is read dynamically for type tests.
31 final Set<TypeVariableElement> readTypeVariables = 41 final Set<TypeVariableElement> readTypeVariables =
32 new Set<TypeVariableElement>(); 42 new Set<TypeVariableElement>();
33 43
34 List<TypedefElement> typedefsNeededForReflection; 44 List<TypedefElement> typedefsNeededForReflection;
35 45
36 JavaScriptBackend get backend => compiler.backend; 46 JavaScriptBackend get backend => compiler.backend;
37 47
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 166 }
157 } 167 }
158 typedefsNeededForReflection.forEach(backend.retainMetadataOf); 168 typedefsNeededForReflection.forEach(backend.retainMetadataOf);
159 } 169 }
160 170
161 JavaScriptConstantCompiler handler = backend.constants; 171 JavaScriptConstantCompiler handler = backend.constants;
162 List<ConstantValue> constants = handler.getConstantsForEmission( 172 List<ConstantValue> constants = handler.getConstantsForEmission(
163 compiler.hasIncrementalSupport ? null : emitter.compareConstants); 173 compiler.hasIncrementalSupport ? null : emitter.compareConstants);
164 for (ConstantValue constant in constants) { 174 for (ConstantValue constant in constants) {
165 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; 175 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue;
176
177 if (constant.isList) outputContainsConstantList = true;
178
166 OutputUnit constantUnit = 179 OutputUnit constantUnit =
167 compiler.deferredLoadTask.outputUnitForConstant(constant); 180 compiler.deferredLoadTask.outputUnitForConstant(constant);
168 if (constantUnit == null) { 181 if (constantUnit == null) {
169 // The back-end introduces some constants, like "InterceptorConstant" or 182 // The back-end introduces some constants, like "InterceptorConstant" or
170 // some list constants. They are emitted in the main output-unit. 183 // some list constants. They are emitted in the main output-unit.
171 // TODO(sigurdm): We should track those constants. 184 // TODO(sigurdm): We should track those constants.
172 constantUnit = compiler.deferredLoadTask.mainOutputUnit; 185 constantUnit = compiler.deferredLoadTask.mainOutputUnit;
173 } 186 }
174 outputConstantLists.putIfAbsent( 187 outputConstantLists.putIfAbsent(
175 constantUnit, () => new List<ConstantValue>()).add(constant); 188 constantUnit, () => new List<ConstantValue>()).add(constant);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 292 }
280 } else { 293 } else {
281 outputClassLists.putIfAbsent( 294 outputClassLists.putIfAbsent(
282 compiler.deferredLoadTask.outputUnitForElement(element), 295 compiler.deferredLoadTask.outputUnitForElement(element),
283 () => new List<ClassElement>()) 296 () => new List<ClassElement>())
284 .add(element); 297 .add(element);
285 } 298 }
286 } 299 }
287 } 300 }
288 301
302 void computeNeededStatics() {
303 bool isStaticFunction(Element element) =>
304 !element.isInstanceMember && !element.isField;
305
306 Iterable<Element> elements =
307 backend.generatedCode.keys.where(isStaticFunction);
308
309 for (Element element in Elements.sortedByPosition(elements)) {
310 outputStaticLists.putIfAbsent(
311 compiler.deferredLoadTask.outputUnitForElement(element),
312 () => new List<Element>())
313 .add(element);
314 }
315 }
316
317 void computeNeededLibraries() {
318 void addSurroundingLibraryToSet(Element element) {
319 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element);
320 LibraryElement library = element.library;
321 outputLibraryLists.putIfAbsent(unit, () => new Set<LibraryElement>())
322 .add(library);
323 }
324
325 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet);
326 neededClasses.forEach(addSurroundingLibraryToSet);
327 }
328
289 void assembleProgram() { 329 void assembleProgram() {
290 measure(() { 330 measure(() {
291 emitter.invalidateCaches(); 331 emitter.invalidateCaches();
292 332
293 // Compute the required type checks to know which classes need a 333 // Compute the required type checks to know which classes need a
294 // 'is$' method. 334 // 'is$' method.
295 typeTestEmitter.computeRequiredTypeChecks(); 335 typeTestEmitter.computeRequiredTypeChecks();
296 336
297 computeNeededDeclarations(); 337 computeNeededDeclarations();
298 computeNeededConstants(); 338 computeNeededConstants();
339 computeNeededStatics();
340 computeNeededLibraries();
341
299 342
300 Program program; 343 Program program;
301 if (USE_NEW_EMITTER) { 344 if (USE_NEW_EMITTER) {
302 program = new ProgramBuilder(compiler, namer, this).buildProgram(); 345 program = new ProgramBuilder(compiler, namer, this).buildProgram();
303 } 346 }
304 emitter.emitProgram(program); 347 emitter.emitProgram(program);
305 }); 348 });
306 } 349 }
307 } 350 }
308 351
309 abstract class Emitter { 352 abstract class Emitter {
310 void emitProgram(Program program); 353 void emitProgram(Program program);
311 354
312 jsAst.Expression generateEmbeddedGlobalAccess(String global); 355 jsAst.Expression generateEmbeddedGlobalAccess(String global);
313 jsAst.Expression constantReference(ConstantValue value); 356 jsAst.Expression constantReference(ConstantValue value);
314 357
315 int compareConstants(ConstantValue a, ConstantValue b); 358 int compareConstants(ConstantValue a, ConstantValue b);
316 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant); 359 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant);
317 360
318 void invalidateCaches(); 361 void invalidateCaches();
319 } 362 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698