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

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

Issue 763123002: dart2js: Split TypeTestEmitter into a registry and an emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: full diff Created 6 years 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 TypeTestRegistry typeTestRegistry;
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 = 28 final Map<OutputUnit, List<Element>> outputStaticLists =
(...skipping 11 matching lines...) Expand all
40 /// Records if a type variable is read dynamically for type tests. 40 /// Records if a type variable is read dynamically for type tests.
41 final Set<TypeVariableElement> readTypeVariables = 41 final Set<TypeVariableElement> readTypeVariables =
42 new Set<TypeVariableElement>(); 42 new Set<TypeVariableElement>();
43 43
44 List<TypedefElement> typedefsNeededForReflection; 44 List<TypedefElement> typedefsNeededForReflection;
45 45
46 JavaScriptBackend get backend => compiler.backend; 46 JavaScriptBackend get backend => compiler.backend;
47 47
48 CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap) 48 CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap)
49 : super(compiler), 49 : super(compiler),
50 this.namer = namer { 50 this.namer = namer,
51 this.typeTestRegistry = new TypeTestRegistry(compiler) {
51 oldEmitter = new OldEmitter(compiler, namer, generateSourceMap, this); 52 oldEmitter = new OldEmitter(compiler, namer, generateSourceMap, this);
52 emitter = USE_NEW_EMITTER 53 emitter = USE_NEW_EMITTER
53 ? new new_js_emitter.Emitter(compiler, namer) 54 ? new new_js_emitter.Emitter(compiler, namer)
54 : oldEmitter; 55 : oldEmitter;
55 nativeEmitter = new NativeEmitter(this); 56 nativeEmitter = new NativeEmitter(this);
56 typeTestEmitter.emitter = this.oldEmitter;
57 } 57 }
58 58
59 59
60 jsAst.Expression generateEmbeddedGlobalAccess(String global) { 60 jsAst.Expression generateEmbeddedGlobalAccess(String global) {
61 return emitter.generateEmbeddedGlobalAccess(global); 61 return emitter.generateEmbeddedGlobalAccess(global);
62 } 62 }
63 63
64 jsAst.Expression constantReference(ConstantValue value) { 64 jsAst.Expression constantReference(ConstantValue value) {
65 return emitter.constantReference(value); 65 return emitter.constantReference(value);
66 } 66 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (backend.isAccessibleByReflection(element)) { 138 if (backend.isAccessibleByReflection(element)) {
139 bool shouldRetainMetadata = backend.retainMetadataOf(element); 139 bool shouldRetainMetadata = backend.retainMetadataOf(element);
140 if (shouldRetainMetadata && element.isFunction) { 140 if (shouldRetainMetadata && element.isFunction) {
141 FunctionElement function = element; 141 FunctionElement function = element;
142 function.functionSignature.forEachParameter( 142 function.functionSignature.forEachParameter(
143 backend.retainMetadataOf); 143 backend.retainMetadataOf);
144 } 144 }
145 } 145 }
146 } 146 }
147 for (ClassElement cls in neededClasses) { 147 for (ClassElement cls in neededClasses) {
148 final onlyForRti = typeTestEmitter.rtiNeededClasses.contains(cls); 148 final onlyForRti = typeTestRegistry.rtiNeededClasses.contains(cls);
149 if (!onlyForRti) { 149 if (!onlyForRti) {
150 backend.retainMetadataOf(cls); 150 backend.retainMetadataOf(cls);
151 oldEmitter.classEmitter.visitFields(cls, false, 151 oldEmitter.classEmitter.visitFields(cls, false,
152 (Element member, 152 (Element member,
153 String name, 153 String name,
154 String accessorName, 154 String accessorName,
155 bool needsGetter, 155 bool needsGetter,
156 bool needsSetter, 156 bool needsSetter,
157 bool needsCheckedSetter) { 157 bool needsCheckedSetter) {
158 bool needsAccessor = needsGetter || needsSetter; 158 bool needsAccessor = needsGetter || needsSetter;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } 241 }
242 } 242 }
243 243
244 // 4. Find all classes needed for rti. 244 // 4. Find all classes needed for rti.
245 // It is important that this is the penultimate step, at this point, 245 // It is important that this is the penultimate step, at this point,
246 // neededClasses must only contain classes that have been resolved and 246 // neededClasses must only contain classes that have been resolved and
247 // codegen'd. The rtiNeededClasses may contain additional classes, but 247 // codegen'd. The rtiNeededClasses may contain additional classes, but
248 // these are thought to not have been instantiated, so we neeed to be able 248 // these are thought to not have been instantiated, so we neeed to be able
249 // to identify them later and make sure we only emit "empty shells" without 249 // to identify them later and make sure we only emit "empty shells" without
250 // fields, etc. 250 // fields, etc.
251 typeTestEmitter.computeRtiNeededClasses(); 251 typeTestRegistry.computeRtiNeededClasses();
252 252
253 // TODO(floitsch): either change the name, or get the rti-classes 253 // TODO(floitsch): either change the name, or get the rti-classes
254 // differently. 254 // differently.
255 typeTestEmitter.rtiNeededClasses.removeAll(neededClasses); 255 typeTestRegistry.rtiNeededClasses.removeAll(neededClasses);
256 // rtiNeededClasses now contains only the "empty shells". 256 // rtiNeededClasses now contains only the "empty shells".
257 neededClasses.addAll(typeTestEmitter.rtiNeededClasses); 257 neededClasses.addAll(typeTestRegistry.rtiNeededClasses);
258 258
259 // TODO(18175, floitsch): remove once issue 18175 is fixed. 259 // TODO(18175, floitsch): remove once issue 18175 is fixed.
260 if (neededClasses.contains(backend.jsIntClass)) { 260 if (neededClasses.contains(backend.jsIntClass)) {
261 neededClasses.add(compiler.intClass); 261 neededClasses.add(compiler.intClass);
262 } 262 }
263 if (neededClasses.contains(backend.jsDoubleClass)) { 263 if (neededClasses.contains(backend.jsDoubleClass)) {
264 neededClasses.add(compiler.doubleClass); 264 neededClasses.add(compiler.doubleClass);
265 } 265 }
266 if (neededClasses.contains(backend.jsNumberClass)) { 266 if (neededClasses.contains(backend.jsNumberClass)) {
267 neededClasses.add(compiler.numClass); 267 neededClasses.add(compiler.numClass);
268 } 268 }
269 if (neededClasses.contains(backend.jsStringClass)) { 269 if (neededClasses.contains(backend.jsStringClass)) {
270 neededClasses.add(compiler.stringClass); 270 neededClasses.add(compiler.stringClass);
271 } 271 }
272 if (neededClasses.contains(backend.jsBoolClass)) { 272 if (neededClasses.contains(backend.jsBoolClass)) {
273 neededClasses.add(compiler.boolClass); 273 neededClasses.add(compiler.boolClass);
274 } 274 }
275 if (neededClasses.contains(backend.jsArrayClass)) { 275 if (neededClasses.contains(backend.jsArrayClass)) {
276 neededClasses.add(compiler.listClass); 276 neededClasses.add(compiler.listClass);
277 } 277 }
278 278
279 // 5. Finally, sort the classes. 279 // 5. Finally, sort the classes.
280 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); 280 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
281 281
282 for (ClassElement element in sortedClasses) { 282 for (ClassElement element in sortedClasses) {
283 if (Elements.isNativeOrExtendsNative(element) && 283 if (Elements.isNativeOrExtendsNative(element) &&
284 !typeTestEmitter.rtiNeededClasses.contains(element)) { 284 !typeTestRegistry.rtiNeededClasses.contains(element)) {
285 // For now, native classes and related classes cannot be deferred. 285 // For now, native classes and related classes cannot be deferred.
286 nativeClasses.add(element); 286 nativeClasses.add(element);
287 if (!element.isNative) { 287 if (!element.isNative) {
288 assert(invariant(element, 288 assert(invariant(element,
289 !compiler.deferredLoadTask.isDeferred(element))); 289 !compiler.deferredLoadTask.isDeferred(element)));
290 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, 290 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit,
291 () => new List<ClassElement>()).add(element); 291 () => new List<ClassElement>()).add(element);
292 } 292 }
293 } else { 293 } else {
294 outputClassLists.putIfAbsent( 294 outputClassLists.putIfAbsent(
(...skipping 30 matching lines...) Expand all
325 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); 325 backend.generatedCode.keys.forEach(addSurroundingLibraryToSet);
326 neededClasses.forEach(addSurroundingLibraryToSet); 326 neededClasses.forEach(addSurroundingLibraryToSet);
327 } 327 }
328 328
329 void assembleProgram() { 329 void assembleProgram() {
330 measure(() { 330 measure(() {
331 emitter.invalidateCaches(); 331 emitter.invalidateCaches();
332 332
333 // Compute the required type checks to know which classes need a 333 // Compute the required type checks to know which classes need a
334 // 'is$' method. 334 // 'is$' method.
335 typeTestEmitter.computeRequiredTypeChecks(); 335 typeTestRegistry.computeRequiredTypeChecks();
336 336
337 computeNeededDeclarations(); 337 computeNeededDeclarations();
338 computeNeededConstants(); 338 computeNeededConstants();
339 computeNeededStatics(); 339 computeNeededStatics();
340 computeNeededLibraries(); 340 computeNeededLibraries();
341 341
342 342
343 Program program; 343 Program program;
344 if (USE_NEW_EMITTER) { 344 if (USE_NEW_EMITTER) {
345 program = new ProgramBuilder(compiler, namer, this).buildProgram(); 345 program = new ProgramBuilder(compiler, namer, this).buildProgram();
346 } 346 }
347 emitter.emitProgram(program); 347 emitter.emitProgram(program);
348 }); 348 });
349 } 349 }
350 } 350 }
351 351
352 abstract class Emitter { 352 abstract class Emitter {
353 void emitProgram(Program program); 353 void emitProgram(Program program);
354 354
355 jsAst.Expression generateEmbeddedGlobalAccess(String global); 355 jsAst.Expression generateEmbeddedGlobalAccess(String global);
356 jsAst.Expression constantReference(ConstantValue value); 356 jsAst.Expression constantReference(ConstantValue value);
357 357
358 int compareConstants(ConstantValue a, ConstantValue b); 358 int compareConstants(ConstantValue a, ConstantValue b);
359 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant); 359 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant);
360 360
361 void invalidateCaches(); 361 void invalidateCaches();
362 } 362 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/native_emitter.dart ('k') | pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698