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

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: Full diff 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.
Johnni Winther 2014/10/16 08:04:50 Add that this is updated in [computeNeededConstant
floitsch 2014/10/16 11:53:36 Done.
34 bool outputContainsConstantList = false;
35
28 final List<ClassElement> nativeClasses = <ClassElement>[]; 36 final List<ClassElement> nativeClasses = <ClassElement>[];
29 37
30 /// Records if a type variable is read dynamically for type tests. 38 /// Records if a type variable is read dynamically for type tests.
31 final Set<TypeVariableElement> readTypeVariables = 39 final Set<TypeVariableElement> readTypeVariables =
32 new Set<TypeVariableElement>(); 40 new Set<TypeVariableElement>();
33 41
34 List<TypedefElement> typedefsNeededForReflection; 42 List<TypedefElement> typedefsNeededForReflection;
35 43
36 JavaScriptBackend get backend => compiler.backend; 44 JavaScriptBackend get backend => compiler.backend;
37 45
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 164 }
157 } 165 }
158 typedefsNeededForReflection.forEach(backend.retainMetadataOf); 166 typedefsNeededForReflection.forEach(backend.retainMetadataOf);
159 } 167 }
160 168
161 JavaScriptConstantCompiler handler = backend.constants; 169 JavaScriptConstantCompiler handler = backend.constants;
162 List<ConstantValue> constants = handler.getConstantsForEmission( 170 List<ConstantValue> constants = handler.getConstantsForEmission(
163 compiler.hasIncrementalSupport ? null : emitter.compareConstants); 171 compiler.hasIncrementalSupport ? null : emitter.compareConstants);
164 for (ConstantValue constant in constants) { 172 for (ConstantValue constant in constants) {
165 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; 173 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue;
174
175 if (constant.isList) outputContainsConstantList = true;
176
166 OutputUnit constantUnit = 177 OutputUnit constantUnit =
167 compiler.deferredLoadTask.outputUnitForConstant(constant); 178 compiler.deferredLoadTask.outputUnitForConstant(constant);
168 if (constantUnit == null) { 179 if (constantUnit == null) {
169 // The back-end introduces some constants, like "InterceptorConstant" or 180 // The back-end introduces some constants, like "InterceptorConstant" or
170 // some list constants. They are emitted in the main output-unit. 181 // some list constants. They are emitted in the main output-unit.
171 // TODO(sigurdm): We should track those constants. 182 // TODO(sigurdm): We should track those constants.
172 constantUnit = compiler.deferredLoadTask.mainOutputUnit; 183 constantUnit = compiler.deferredLoadTask.mainOutputUnit;
173 } 184 }
174 outputConstantLists.putIfAbsent(constantUnit, () => new List<ConstantValue >()) 185 outputConstantLists.putIfAbsent(constantUnit, () => new List<ConstantValue >())
175 .add(constant); 186 .add(constant);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 290 }
280 } else { 291 } else {
281 outputClassLists.putIfAbsent( 292 outputClassLists.putIfAbsent(
282 compiler.deferredLoadTask.outputUnitForElement(element), 293 compiler.deferredLoadTask.outputUnitForElement(element),
283 () => new List<ClassElement>()) 294 () => new List<ClassElement>())
284 .add(element); 295 .add(element);
285 } 296 }
286 } 297 }
287 } 298 }
288 299
300 void computeNeededStatics() {
301 bool isStaticFunction(Element element) =>
302 !element.isInstanceMember && !element.isField;
303
304 Iterable<Element> elements =
305 backend.generatedCode.keys.where(isStaticFunction);
306
307 for (Element element in Elements.sortedByPosition(elements)) {
308 outputStaticLists.putIfAbsent(
309 compiler.deferredLoadTask.outputUnitForElement(element),
310 () => new List<Element>())
311 .add(element);
312 }
313 }
314
315 void computeNeededLibraries() {
316 void addSurroundingLibraryToSet(Element element) {
317 OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element);
318 LibraryElement library = element.library;
319 outputLibraryLists.putIfAbsent(unit, () => new Set<LibraryElement>())
320 .add(library);
321 }
322
323 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet);
324 neededClasses.forEach(addSurroundingLibraryToSet);
325 }
326
289 void assembleProgram() { 327 void assembleProgram() {
290 measure(() { 328 measure(() {
291 emitter.invalidateCaches(); 329 emitter.invalidateCaches();
292 330
293 // Compute the required type checks to know which classes need a 331 // Compute the required type checks to know which classes need a
294 // 'is$' method. 332 // 'is$' method.
295 typeTestEmitter.computeRequiredTypeChecks(); 333 typeTestEmitter.computeRequiredTypeChecks();
296 334
297 computeNeededDeclarations(); 335 computeNeededDeclarations();
298 computeNeededConstants(); 336 computeNeededConstants();
337 computeNeededStatics();
338 computeNeededLibraries();
339
299 340
300 Program program; 341 Program program;
301 if (USE_NEW_EMITTER) { 342 if (USE_NEW_EMITTER) {
302 program = new ProgramBuilder(compiler, namer, this).buildProgram(); 343 program = new ProgramBuilder(compiler, namer, this).buildProgram();
303 } 344 }
304 emitter.emitProgram(program); 345 emitter.emitProgram(program);
305 }); 346 });
306 } 347 }
307 } 348 }
308 349
309 abstract class Emitter { 350 abstract class Emitter {
310 void emitProgram(Program program); 351 void emitProgram(Program program);
311 352
312 jsAst.Expression generateEmbeddedGlobalAccess(String global); 353 jsAst.Expression generateEmbeddedGlobalAccess(String global);
313 jsAst.Expression constantReference(ConstantValue value); 354 jsAst.Expression constantReference(ConstantValue value);
314 355
315 int compareConstants(ConstantValue a, ConstantValue b); 356 int compareConstants(ConstantValue a, ConstantValue b);
316 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant); 357 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant);
317 358
318 void invalidateCaches(); 359 void invalidateCaches();
319 } 360 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698