Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); | |
| 20 NativeEmitter nativeEmitter; | 19 NativeEmitter nativeEmitter; |
| 21 OldEmitter oldEmitter; | 20 OldEmitter oldEmitter; |
| 22 Emitter emitter; | 21 Emitter emitter; |
| 23 | 22 |
| 24 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 23 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
| 25 final Map<OutputUnit, List<ClassElement>> outputClassLists = | 24 final Map<OutputUnit, List<ClassElement>> outputClassLists = |
| 26 new Map<OutputUnit, List<ClassElement>>(); | 25 new Map<OutputUnit, List<ClassElement>>(); |
| 27 final Map<OutputUnit, List<Constant>> outputConstantLists = | 26 final Map<OutputUnit, List<Constant>> outputConstantLists = |
| 28 new Map<OutputUnit, List<Constant>>(); | 27 new Map<OutputUnit, List<Constant>>(); |
| 29 final List<ClassElement> nativeClasses = <ClassElement>[]; | 28 final List<ClassElement> nativeClasses = <ClassElement>[]; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 40 | 39 |
| 41 CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap) | 40 CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap) |
| 42 : super(compiler), | 41 : super(compiler), |
| 43 this.namer = namer { | 42 this.namer = namer { |
| 44 oldEmitter = new OldEmitter(compiler, namer, generateSourceMap, this); | 43 oldEmitter = new OldEmitter(compiler, namer, generateSourceMap, this); |
| 45 emitter = USE_NEW_EMITTER | 44 emitter = USE_NEW_EMITTER |
| 46 ? new new_js_emitter.Emitter(compiler, namer, generateSourceMap, this) | 45 ? new new_js_emitter.Emitter(compiler, namer, generateSourceMap, this) |
| 47 : oldEmitter; | 46 : oldEmitter; |
| 48 nativeEmitter = new NativeEmitter(this); | 47 nativeEmitter = new NativeEmitter(this); |
| 49 typeTestEmitter.emitter = this.oldEmitter; | 48 typeTestEmitter.emitter = this.oldEmitter; |
| 50 interceptorEmitter.emitter = this.oldEmitter; | |
| 51 // TODO(18886): Remove this call (and the show in the import) once the | 49 // TODO(18886): Remove this call (and the show in the import) once the |
| 52 // memory-leak in the VM is fixed. | 50 // memory-leak in the VM is fixed. |
| 53 templateManager.clear(); | 51 templateManager.clear(); |
| 54 } | 52 } |
| 55 | 53 |
| 56 | 54 |
| 57 jsAst.Expression generateEmbeddedGlobalAccess(String global) { | 55 jsAst.Expression generateEmbeddedGlobalAccess(String global) { |
| 58 return emitter.generateEmbeddedGlobalAccess(global); | 56 return emitter.generateEmbeddedGlobalAccess(global); |
| 59 } | 57 } |
| 60 | 58 |
| 61 jsAst.Expression constantReference(Constant value) { | 59 jsAst.Expression constantReference(Constant value) { |
| 62 return emitter.constantReference(value); | 60 return emitter.constantReference(value); |
| 63 } | 61 } |
| 64 | 62 |
| 63 Set<ClassElement> interceptorsReferencedFromConstants() { | |
|
floitsch
2014/09/24 14:02:06
Straight copy from `interceptor_emitter.dart`.
| |
| 64 Set<ClassElement> classes = new Set<ClassElement>(); | |
| 65 JavaScriptConstantCompiler handler = backend.constants; | |
| 66 List<Constant> constants = handler.getConstantsForEmission(); | |
| 67 for (Constant constant in constants) { | |
| 68 if (constant is InterceptorConstant) { | |
| 69 InterceptorConstant interceptorConstant = constant; | |
| 70 classes.add(interceptorConstant.dispatchedType.element); | |
| 71 } | |
| 72 } | |
| 73 return classes; | |
| 74 } | |
| 75 | |
| 65 /** | 76 /** |
| 66 * Return a function that returns true if its argument is a class | 77 * Return a function that returns true if its argument is a class |
| 67 * that needs to be emitted. | 78 * that needs to be emitted. |
| 68 */ | 79 */ |
| 69 Function computeClassFilter() { | 80 Function computeClassFilter() { |
| 70 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true; | 81 if (backend.isTreeShakingDisabled) return (ClassElement cls) => true; |
| 71 | 82 |
| 72 Set<ClassElement> unneededClasses = new Set<ClassElement>(); | 83 Set<ClassElement> unneededClasses = new Set<ClassElement>(); |
| 73 // The [Bool] class is not marked as abstract, but has a factory | 84 // The [Bool] class is not marked as abstract, but has a factory |
| 74 // constructor that always throws. We never need to emit it. | 85 // constructor that always throws. We never need to emit it. |
| 75 unneededClasses.add(compiler.boolClass); | 86 unneededClasses.add(compiler.boolClass); |
| 76 | 87 |
| 77 // Go over specialized interceptors and then constants to know which | 88 // Go over specialized interceptors and then constants to know which |
| 78 // interceptors are needed. | 89 // interceptors are needed. |
| 79 Set<ClassElement> needed = new Set<ClassElement>(); | 90 Set<ClassElement> needed = new Set<ClassElement>(); |
| 80 backend.specializedGetInterceptors.forEach( | 91 backend.specializedGetInterceptors.forEach( |
| 81 (_, Iterable<ClassElement> elements) { | 92 (_, Iterable<ClassElement> elements) { |
| 82 needed.addAll(elements); | 93 needed.addAll(elements); |
| 83 } | 94 } |
| 84 ); | 95 ); |
| 85 | 96 |
| 86 // Add interceptors referenced by constants. | 97 // Add interceptors referenced by constants. |
| 87 needed.addAll(interceptorEmitter.interceptorsReferencedFromConstants()); | 98 needed.addAll(interceptorsReferencedFromConstants()); |
| 88 | 99 |
| 89 // Add unneeded interceptors to the [unneededClasses] set. | 100 // Add unneeded interceptors to the [unneededClasses] set. |
| 90 for (ClassElement interceptor in backend.interceptedClasses) { | 101 for (ClassElement interceptor in backend.interceptedClasses) { |
| 91 if (!needed.contains(interceptor) | 102 if (!needed.contains(interceptor) |
| 92 && interceptor != compiler.objectClass) { | 103 && interceptor != compiler.objectClass) { |
| 93 unneededClasses.add(interceptor); | 104 unneededClasses.add(interceptor); |
| 94 } | 105 } |
| 95 } | 106 } |
| 96 | 107 |
| 97 // These classes are just helpers for the backend's type system. | 108 // These classes are just helpers for the backend's type system. |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 } | 285 } |
| 275 | 286 |
| 276 class OldEmitter implements Emitter { | 287 class OldEmitter implements Emitter { |
| 277 final Compiler compiler; | 288 final Compiler compiler; |
| 278 final CodeEmitterTask task; | 289 final CodeEmitterTask task; |
| 279 | 290 |
| 280 final ContainerBuilder containerBuilder = new ContainerBuilder(); | 291 final ContainerBuilder containerBuilder = new ContainerBuilder(); |
| 281 final ClassEmitter classEmitter = new ClassEmitter(); | 292 final ClassEmitter classEmitter = new ClassEmitter(); |
| 282 final NsmEmitter nsmEmitter = new NsmEmitter(); | 293 final NsmEmitter nsmEmitter = new NsmEmitter(); |
| 283 TypeTestEmitter get typeTestEmitter => task.typeTestEmitter; | 294 TypeTestEmitter get typeTestEmitter => task.typeTestEmitter; |
| 284 InterceptorEmitter get interceptorEmitter => task.interceptorEmitter; | 295 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); |
| 285 final MetadataEmitter metadataEmitter = new MetadataEmitter(); | 296 final MetadataEmitter metadataEmitter = new MetadataEmitter(); |
| 286 | 297 |
| 287 final Set<Constant> cachedEmittedConstants; | 298 final Set<Constant> cachedEmittedConstants; |
| 288 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); | 299 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); |
| 289 final Map<Element, ClassBuilder> cachedClassBuilders; | 300 final Map<Element, ClassBuilder> cachedClassBuilders; |
| 290 final Set<Element> cachedElements; | 301 final Set<Element> cachedElements; |
| 291 | 302 |
| 292 bool needsDefineClass = false; | 303 bool needsDefineClass = false; |
| 293 bool needsMixinSupport = false; | 304 bool needsMixinSupport = false; |
| 294 bool needsLazyInitializer = false; | 305 bool needsLazyInitializer = false; |
| (...skipping 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2170 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2181 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2171 if (element.isInstanceMember) { | 2182 if (element.isInstanceMember) { |
| 2172 cachedClassBuilders.remove(element.enclosingClass); | 2183 cachedClassBuilders.remove(element.enclosingClass); |
| 2173 | 2184 |
| 2174 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2185 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2175 | 2186 |
| 2176 } | 2187 } |
| 2177 } | 2188 } |
| 2178 } | 2189 } |
| 2179 } | 2190 } |
| OLD | NEW |