Use ModularNamer/ModularEmitter to generate code separate from codegen enqueuing

Change-Id: I35dc4c0370622c63f2100e22517149cb0629423e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102367
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/backend_strategy.dart b/pkg/compiler/lib/src/backend_strategy.dart
index cb3b545..7c14557 100644
--- a/pkg/compiler/lib/src/backend_strategy.dart
+++ b/pkg/compiler/lib/src/backend_strategy.dart
@@ -12,7 +12,6 @@
 import 'inferrer/types.dart';
 import 'io/source_information.dart';
 import 'js_backend/inferred_data.dart';
-import 'js_backend/js_backend.dart';
 import 'js_backend/native_data.dart';
 import 'ssa/ssa.dart';
 import 'universe/codegen_world_builder.dart';
@@ -39,12 +38,11 @@
       SelectorConstraintsStrategy selectorConstraintsStrategy);
 
   /// Creates the [WorkItemBuilder] used by the codegen enqueuer.
-  WorkItemBuilder createCodegenWorkItemBuilder(JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults, CodegenInputs codegen);
+  WorkItemBuilder createCodegenWorkItemBuilder();
 
   /// Creates the [SsaBuilder] used for the element model.
-  SsaBuilder createSsaBuilder(CompilerTask task, CodegenInputs codegen,
-      SourceInformationStrategy sourceInformationStrategy);
+  SsaBuilder createSsaBuilder(
+      CompilerTask task, SourceInformationStrategy sourceInformationStrategy);
 
   /// Returns the [SourceInformationStrategy] use for the element model.
   SourceInformationStrategy get sourceInformationStrategy;
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 19291da..eaaa3f1 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -11,6 +11,8 @@
 import '../elements/entities.dart';
 import '../elements/types.dart' show DartType, InterfaceType;
 import '../js/js.dart' as js;
+import '../js_backend/namer.dart' show Namer;
+import '../js_emitter/code_emitter_task.dart' show Emitter;
 import '../native/behavior.dart';
 import '../universe/feature.dart';
 import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
@@ -250,6 +252,103 @@
 
   CodegenResult(
       this.code, this.impact, this.modularNames, this.modularExpressions);
+  void applyModularState(Namer namer, Emitter emitter) {
+    for (ModularName name in modularNames) {
+      switch (name.kind) {
+        case ModularNameKind.rtiField:
+          name.value = namer.rtiFieldJsName;
+          break;
+        case ModularNameKind.runtimeTypeName:
+          name.value = namer.runtimeTypeName(name.data);
+          break;
+        case ModularNameKind.className:
+          name.value = namer.className(name.data);
+          break;
+        case ModularNameKind.aliasedSuperMember:
+          name.value = namer.aliasedSuperMemberPropertyName(name.data);
+          break;
+        case ModularNameKind.staticClosure:
+          name.value = namer.staticClosureName(name.data);
+          break;
+        case ModularNameKind.methodProperty:
+          name.value = namer.methodPropertyName(name.data);
+          break;
+        case ModularNameKind.operatorIs:
+          name.value = namer.operatorIs(name.data);
+          break;
+        case ModularNameKind.operatorIsType:
+          name.value = namer.operatorIsType(name.data);
+          break;
+        case ModularNameKind.substitution:
+          name.value = namer.substitutionName(name.data);
+          break;
+        case ModularNameKind.instanceMethod:
+          name.value = namer.instanceMethodName(name.data);
+          break;
+        case ModularNameKind.instanceField:
+          name.value = namer.instanceFieldPropertyName(name.data);
+          break;
+        case ModularNameKind.invocation:
+          name.value = namer.invocationName(name.data);
+          break;
+        case ModularNameKind.lazyInitializer:
+          name.value = namer.lazyInitializerName(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForClass:
+          name.value = namer.globalPropertyNameForClass(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForType:
+          name.value = namer.globalPropertyNameForType(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForMember:
+          name.value = namer.globalPropertyNameForMember(name.data);
+          break;
+        case ModularNameKind.nameForGetInterceptor:
+          name.value = namer.nameForGetInterceptor(name.set);
+          break;
+        case ModularNameKind.nameForGetOneShotInterceptor:
+          name.value = namer.nameForGetOneShotInterceptor(name.data, name.set);
+          break;
+        case ModularNameKind.asName:
+          name.value = namer.asName(name.data);
+          break;
+      }
+    }
+    for (ModularExpression expression in modularExpressions) {
+      switch (expression.kind) {
+        case ModularExpressionKind.globalObjectForLibrary:
+          expression.value = namer
+              .readGlobalObjectForLibrary(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForClass:
+          expression.value = namer
+              .readGlobalObjectForClass(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForType:
+          expression.value = namer
+              .readGlobalObjectForType(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForMember:
+          expression.value = namer
+              .readGlobalObjectForMember(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.constant:
+          expression.value = emitter
+              .constantReference(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.embeddedGlobalAccess:
+          expression.value = emitter
+              .generateEmbeddedGlobalAccess(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+      }
+    }
+  }
 
   @override
   String toString() {
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index a2c1f14..a0b1e01 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -233,7 +233,7 @@
         performGlobalTypeInference(results.closedWorld);
         return;
       }
-      generateJavaScriptCode(results);
+      emitJavaScriptCode(results);
     } else {
       KernelResult result = await kernelLoader.load(uri);
       reporter.log("Kernel load complete");
@@ -355,19 +355,19 @@
         mainFunction, closedWorld, inferredDataBuilder);
   }
 
-  void generateJavaScriptCode(
-      GlobalTypeInferenceResults globalInferenceResults) {
+  void emitJavaScriptCode(GlobalTypeInferenceResults globalInferenceResults) {
     JClosedWorld closedWorld = globalInferenceResults.closedWorld;
     backendStrategy.registerJClosedWorld(closedWorld);
-    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     if (options.showInternalProgress) reporter.log('Compiling...');
     phase = PHASE_COMPILING;
 
-    CodegenInputs codegen = backend.onCodegenStart(closedWorld);
+    CodegenInputs codegen = backend.onCodegenStart(globalInferenceResults);
+    backend.onCodegenEnqueuerStart(globalInferenceResults, codegen);
     Enqueuer codegenEnqueuer = enqueuer.createCodegenEnqueuer(
         closedWorld, globalInferenceResults, codegen);
     _codegenWorldBuilder = codegenEnqueuer.worldBuilder;
 
+    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     processQueue(closedWorld.elementEnvironment, codegenEnqueuer, mainFunction,
         onProgress: showCodegenProgress);
     codegenEnqueuer.logSummary(reporter.log);
@@ -416,7 +416,7 @@
               worldData);
         }
         if (stopAfterTypeInference) return;
-        generateJavaScriptCode(globalInferenceResults);
+        emitJavaScriptCode(globalInferenceResults);
       }
     });
   }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 3d6e2ca..0b7b8b3 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -21,7 +21,7 @@
 import '../io/source_information.dart' show SourceInformationStrategy;
 import '../js/js.dart' as jsAst;
 import '../js_model/elements.dart';
-import '../js_emitter/js_emitter.dart' show CodeEmitterTask, ModularEmitter;
+import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
 import '../kernel/dart2js_target.dart';
 import '../native/enqueue.dart';
 import '../ssa/ssa.dart' show SsaFunctionCompiler;
@@ -53,14 +53,11 @@
 import 'runtime_types.dart';
 
 abstract class FunctionCompiler {
-  void onCodegenStart(CodegenInputs codegen);
+  void initialize(
+      GlobalTypeInferenceResults globalInferenceResults, CodegenInputs codegen);
 
   /// Generates JavaScript code for [member].
-  CodegenResult compile(
-      MemberEntity member,
-      CodegenInputs codegen,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults);
+  CodegenResult compile(MemberEntity member);
 
   Iterable get tasks;
 }
@@ -326,8 +323,6 @@
 
   RuntimeTypesChecksBuilder _rtiChecksBuilder;
 
-  RuntimeTypesEncoder _rtiEncoder;
-
   /// True if the html library has been loaded.
   bool htmlLibraryIsLoaded = false;
 
@@ -419,25 +414,6 @@
 
   RuntimeTypesChecksBuilder get rtiChecksBuilderForTesting => _rtiChecksBuilder;
 
-  RuntimeTypesEncoder get rtiEncoder {
-    assert(
-        _rtiEncoder != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "RuntimeTypesEncoder has not been created."));
-    return _rtiEncoder;
-  }
-
-  Namer determineNamer(JClosedWorld closedWorld, RuntimeTypeTags rtiTags) {
-    FixedNames fixedNames = compiler.options.enableMinification
-        ? const MinifiedFixedNames()
-        : const FixedNames();
-    return compiler.options.enableMinification
-        ? compiler.options.useFrequencyNamer
-            ? new FrequencyBasedNamer(closedWorld, rtiTags, fixedNames)
-            : new MinifyNamer(closedWorld, rtiTags, fixedNames)
-        : new Namer(closedWorld, rtiTags, fixedNames);
-  }
-
   void validateInterceptorImplementsAllObjectMethods(
       ClassEntity interceptorClass) {
     if (interceptorClass == null) return;
@@ -580,8 +556,7 @@
             closedWorld.nativeData,
             closedWorld,
             compiler.abstractValueStrategy.createSelectorStrategy()),
-        compiler.backendStrategy.createCodegenWorkItemBuilder(
-            closedWorld, globalInferenceResults, codegen),
+        compiler.backendStrategy.createCodegenWorkItemBuilder(),
         new CodegenEnqueuerListener(
             elementEnvironment,
             commonElements,
@@ -594,20 +569,9 @@
 
   Map<MemberEntity, WorldImpact> codegenImpactsForTesting;
 
-  WorldImpact generateCode(
-      WorkItem work,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults,
-      CodegenInputs codegen) {
+  WorldImpact generateCode(WorkItem work) {
     MemberEntity member = work.element;
-    if (member.isConstructor &&
-        member.enclosingClass == closedWorld.commonElements.jsNullClass) {
-      // Work around a problem compiling JSNull's constructor.
-      return const WorldImpact();
-    }
-
-    CodegenResult result = functionCompiler.compile(
-        member, codegen, closedWorld, globalInferenceResults);
+    CodegenResult result = functionCompiler.compile(member);
     if (result.code != null) {
       generatedCode[member] = result.code;
     }
@@ -618,6 +582,7 @@
     WorldImpact worldImpact =
         _codegenImpactTransformer.transformCodegenImpact(result.impact);
     compiler.dumpInfoTask.registerImpact(member, worldImpact);
+    result.applyModularState(_namer, emitterTask.emitter);
     return worldImpact;
   }
 
@@ -658,34 +623,28 @@
     }
   }
 
-  /// Called when the compiler starts running the codegen enqueuer. The
-  /// [WorldImpact] of enabled backend features is returned.
-  CodegenInputs onCodegenStart(JClosedWorld closedWorld) {
+  /// Called when the compiler starts running the codegen.
+  ///
+  /// Returns the [CodegenInputs] objects with the needed data.
+  CodegenInputs onCodegenStart(
+      GlobalTypeInferenceResults globalTypeInferenceResults) {
+    JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
     RuntimeTypeTags rtiTags = const RuntimeTypeTags();
+    FixedNames fixedNames = compiler.options.enableMinification
+        ? const MinifiedFixedNames()
+        : const FixedNames();
+
     OneShotInterceptorData oneShotInterceptorData = new OneShotInterceptorData(
         closedWorld.interceptorData,
         closedWorld.commonElements,
         closedWorld.nativeData);
     Tracer tracer = new Tracer(closedWorld, compiler.outputProvider);
-    _rtiEncoder = new RuntimeTypesEncoderImpl(
+    RuntimeTypesEncoder rtiEncoder = new RuntimeTypesEncoderImpl(
         rtiTags,
         closedWorld.nativeData,
         closedWorld.elementEnvironment,
         closedWorld.commonElements,
         closedWorld.rtiNeed);
-    _nativeCodegenEnqueuer = new NativeCodegenEnqueuer(
-        compiler.options,
-        closedWorld.elementEnvironment,
-        closedWorld.commonElements,
-        closedWorld.dartTypes,
-        emitterTask,
-        closedWorld.liveNativeClasses,
-        closedWorld.nativeData);
-    _namer = determineNamer(closedWorld, rtiTags);
-    emitterTask.createEmitter(_namer, closedWorld);
-    // TODO(johnniwinther): Share the impact object created in
-    // createCodegenEnqueuer.
-    BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements);
     RuntimeTypesSubstitutions rtiSubstitutions;
     if (compiler.options.disableRtiOptimization) {
       rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(closedWorld);
@@ -697,6 +656,38 @@
       rtiSubstitutions = runtimeTypesImpl;
     }
 
+    CodegenInputs codegen = new CodegenInputsImpl(oneShotInterceptorData,
+        rtiSubstitutions, rtiEncoder, tracer, rtiTags, fixedNames);
+
+    functionCompiler.initialize(globalTypeInferenceResults, codegen);
+    return codegen;
+  }
+
+  /// Called before the compiler starts running the codegen enqueuer.
+  void onCodegenEnqueuerStart(
+      GlobalTypeInferenceResults globalTypeInferenceResults,
+      CodegenInputs codegen) {
+    JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
+    RuntimeTypeTags rtiTags = codegen.rtiTags;
+    FixedNames fixedNames = codegen.fixedNames;
+    _namer = compiler.options.enableMinification
+        ? compiler.options.useFrequencyNamer
+            ? new FrequencyBasedNamer(closedWorld, rtiTags, fixedNames)
+            : new MinifyNamer(closedWorld, rtiTags, fixedNames)
+        : new Namer(closedWorld, rtiTags, fixedNames);
+    _nativeCodegenEnqueuer = new NativeCodegenEnqueuer(
+        compiler.options,
+        closedWorld.elementEnvironment,
+        closedWorld.commonElements,
+        closedWorld.dartTypes,
+        emitterTask,
+        closedWorld.liveNativeClasses,
+        closedWorld.nativeData);
+    emitterTask.createEmitter(_namer, codegen, closedWorld);
+    // TODO(johnniwinther): Share the impact object created in
+    // createCodegenEnqueuer.
+    BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements);
+
     _codegenImpactTransformer = new CodegenImpactTransformer(
         compiler.options,
         closedWorld.elementEnvironment,
@@ -707,15 +698,9 @@
         closedWorld.rtiNeed,
         nativeCodegenEnqueuer,
         _namer,
-        oneShotInterceptorData,
+        codegen.oneShotInterceptorData,
         rtiChecksBuilder,
         emitterTask.nativeEmitter);
-
-    CodegenInputs codegen = new CodegenInputsImpl(emitterTask.emitter,
-        oneShotInterceptorData, rtiSubstitutions, rtiEncoder, _namer, tracer);
-
-    functionCompiler.onCodegenStart(codegen);
-    return codegen;
   }
 
   /// Called when code generation has been completed.
@@ -801,21 +786,18 @@
 
 /// Interface for resources only used during code generation.
 abstract class CodegenInputs {
-  ModularEmitter get emitter;
   CheckedModeHelpers get checkedModeHelpers;
   OneShotInterceptorData get oneShotInterceptorData;
   RuntimeTypesSubstitutions get rtiSubstitutions;
   RuntimeTypesEncoder get rtiEncoder;
-  ModularNamer get namer;
   SuperMemberData get superMemberData;
   Tracer get tracer;
+  RuntimeTypeTags get rtiTags;
+  FixedNames get fixedNames;
 }
 
 class CodegenInputsImpl implements CodegenInputs {
   @override
-  final ModularEmitter emitter;
-
-  @override
   final CheckedModeHelpers checkedModeHelpers = new CheckedModeHelpers();
 
   @override
@@ -828,14 +810,17 @@
   final RuntimeTypesEncoder rtiEncoder;
 
   @override
-  final ModularNamer namer;
-
-  @override
   final SuperMemberData superMemberData = new SuperMemberData();
 
   @override
   final Tracer tracer;
 
-  CodegenInputsImpl(this.emitter, this.oneShotInterceptorData,
-      this.rtiSubstitutions, this.rtiEncoder, this.namer, this.tracer);
+  @override
+  final RuntimeTypeTags rtiTags;
+
+  @override
+  final FixedNames fixedNames;
+
+  CodegenInputsImpl(this.oneShotInterceptorData, this.rtiSubstitutions,
+      this.rtiEncoder, this.tracer, this.rtiTags, this.fixedNames);
 }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index b4893ae5..3dd3633 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -686,6 +686,9 @@
       [ShouldEncodeTypedefCallback shouldEncodeTypedef]);
 
   jsAst.Expression getJsInteropTypeArguments(int count);
+
+  /// Fixed strings used for runtime types encoding.
+  RuntimeTypeTags get rtiTags;
 }
 
 /// Common functionality for [_RuntimeTypesNeedBuilder] and [_RuntimeTypes].
@@ -2201,8 +2204,10 @@
   final CommonElements commonElements;
   final TypeRepresentationGenerator _representationGenerator;
   final RuntimeTypesNeed _rtiNeed;
+  @override
+  final RuntimeTypeTags rtiTags;
 
-  RuntimeTypesEncoderImpl(RuntimeTypeTags rtiTags, NativeBasicData nativeData,
+  RuntimeTypesEncoderImpl(this.rtiTags, NativeBasicData nativeData,
       this._elementEnvironment, this.commonElements, this._rtiNeed)
       : _representationGenerator =
             new TypeRepresentationGenerator(rtiTags, nativeData);
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 35cca02..f0ed8a1 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -11,9 +11,9 @@
 import '../deferred_load.dart' show OutputUnit;
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
-import '../js_backend/js_backend.dart'
-    show CodegenInputs, JavaScriptBackend, Namer;
+import '../js_backend/backend.dart' show CodegenInputs, JavaScriptBackend;
 import '../js_backend/inferred_data.dart';
+import '../js_backend/namer.dart' show Namer;
 import '../universe/codegen_world_builder.dart';
 import '../world.dart' show JClosedWorld;
 import 'program_builder/program_builder.dart';
@@ -76,7 +76,8 @@
   }
 
   /// Creates the [Emitter] for this task.
-  void createEmitter(Namer namer, JClosedWorld closedWorld) {
+  void createEmitter(
+      Namer namer, CodegenInputs codegen, JClosedWorld closedWorld) {
     measure(() {
       _nativeEmitter =
           new NativeEmitter(this, closedWorld, _backend.nativeCodegenEnqueuer);
@@ -87,7 +88,7 @@
           _compiler.dumpInfoTask,
           namer,
           closedWorld,
-          _backend.rtiEncoder,
+          codegen.rtiEncoder,
           _backend.sourceInformationStrategy,
           this,
           _generateSourceMap);
@@ -95,7 +96,7 @@
           _compiler.options,
           _compiler.reporter,
           _emitter,
-          _backend.rtiEncoder,
+          codegen.rtiEncoder,
           closedWorld.elementEnvironment);
       typeTestRegistry = new TypeTestRegistry(
           _compiler.options, closedWorld.elementEnvironment);
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 1dc1c0b..6eafe83 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -25,10 +25,9 @@
 import '../js/js_source_mapping.dart';
 import '../js_backend/backend.dart';
 import '../js_backend/inferred_data.dart';
-import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
-import '../js_backend/runtime_types.dart';
-import '../js_emitter/code_emitter_task.dart';
+import '../js_backend/namer.dart' show ModularNamer;
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../kernel/kernel_strategy.dart';
 import '../native/behavior.dart';
 import '../options.dart';
@@ -36,7 +35,6 @@
 import '../ssa/nodes.dart';
 import '../ssa/ssa.dart';
 import '../ssa/types.dart';
-import '../tracer.dart';
 import '../universe/codegen_world_builder.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
@@ -99,8 +97,8 @@
   }
 
   @override
-  SsaBuilder createSsaBuilder(CompilerTask task, CodegenInputs codegen,
-      SourceInformationStrategy sourceInformationStrategy) {
+  SsaBuilder createSsaBuilder(
+      CompilerTask task, SourceInformationStrategy sourceInformationStrategy) {
     return new KernelSsaBuilder(
         task,
         _compiler.options,
@@ -108,20 +106,12 @@
         _compiler.dumpInfoTask,
         // ignore:deprecated_member_use_from_same_package
         elementMap,
-        codegen.namer,
-        codegen.emitter,
-        codegen.tracer,
-        codegen.rtiEncoder,
         sourceInformationStrategy);
   }
 
   @override
-  WorkItemBuilder createCodegenWorkItemBuilder(
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults,
-      CodegenInputs codegen) {
-    return new KernelCodegenWorkItemBuilder(
-        _compiler.backend, closedWorld, globalInferenceResults, codegen);
+  WorkItemBuilder createCodegenWorkItemBuilder() {
+    return new KernelCodegenWorkItemBuilder(_compiler.backend);
   }
 
   @override
@@ -147,36 +137,26 @@
 
 class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
   final JavaScriptBackend _backend;
-  final JClosedWorld _closedWorld;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-  final CodegenInputs _codegen;
 
-  KernelCodegenWorkItemBuilder(this._backend, this._closedWorld,
-      this._globalInferenceResults, this._codegen);
+  KernelCodegenWorkItemBuilder(this._backend);
 
   @override
   WorkItem createWorkItem(MemberEntity entity) {
     if (entity.isAbstract) return null;
-    return new KernelCodegenWorkItem(
-        _backend, _closedWorld, _globalInferenceResults, _codegen, entity);
+    return new KernelCodegenWorkItem(_backend, entity);
   }
 }
 
 class KernelCodegenWorkItem extends WorkItem {
   final JavaScriptBackend _backend;
-  final JClosedWorld _closedWorld;
   @override
   final MemberEntity element;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-  final CodegenInputs _codegen;
 
-  KernelCodegenWorkItem(this._backend, this._closedWorld,
-      this._globalInferenceResults, this._codegen, this.element);
+  KernelCodegenWorkItem(this._backend, this.element);
 
   @override
   WorldImpact run() {
-    return _backend.generateCode(
-        this, _closedWorld, _globalInferenceResults, _codegen);
+    return _backend.generateCode(this);
   }
 }
 
@@ -187,31 +167,24 @@
   final DiagnosticReporter _reporter;
   final DumpInfoTask _dumpInfoTask;
   final JsToElementMap _elementMap;
-  final ModularNamer _namer;
-  final ModularEmitter _emitter;
-  final Tracer _tracer;
-  final RuntimeTypesEncoder _rtiEncoder;
   final SourceInformationStrategy _sourceInformationStrategy;
 
   // TODO(johnniwinther,sra): Inlining decisions should not be based on the
   // order in which ssa graphs are built.
   FunctionInlineCache _inlineCache;
 
-  KernelSsaBuilder(
-      this._task,
-      this._options,
-      this._reporter,
-      this._dumpInfoTask,
-      this._elementMap,
-      this._namer,
-      this._emitter,
-      this._tracer,
-      this._rtiEncoder,
-      this._sourceInformationStrategy);
+  KernelSsaBuilder(this._task, this._options, this._reporter,
+      this._dumpInfoTask, this._elementMap, this._sourceInformationStrategy);
 
   @override
-  HGraph build(MemberEntity member, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results, CodegenRegistry registry) {
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults results,
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     _inlineCache ??= new FunctionInlineCache(closedWorld.annotationsData);
     return _task.measure(() {
       KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
@@ -224,10 +197,10 @@
           results,
           closedWorld,
           registry,
-          _namer,
-          _emitter,
-          _tracer,
-          _rtiEncoder,
+          namer,
+          emitter,
+          codegen.tracer,
+          codegen.rtiEncoder,
           _sourceInformationStrategy,
           _inlineCache);
       return builder.build();
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index f4b339c..86f367a 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -21,7 +21,7 @@
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
 import '../js_backend/interceptor_data.dart';
-import '../js_backend/backend.dart';
+import '../js_backend/backend.dart' show CodegenInputs, SuperMemberData;
 import '../js_backend/checked_mode_helpers.dart';
 import '../js_backend/native_data.dart';
 import '../js_backend/namer.dart' show ModularNamer;
@@ -83,12 +83,15 @@
       HGraph graph,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
-      CodegenRegistry registry) {
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     if (member.isField) {
       return generateLazyInitializer(
-          member, graph, codegen, closedWorld, registry);
+          member, graph, codegen, closedWorld, registry, namer, emitter);
     } else {
-      return generateMethod(member, graph, codegen, closedWorld, registry);
+      return generateMethod(
+          member, graph, codegen, closedWorld, registry, namer, emitter);
     }
   }
 
@@ -97,7 +100,9 @@
       HGraph graph,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
-      CodegenRegistry registry) {
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     return measure(() {
       codegen.tracer.traceGraph("codegen", graph);
       SourceInformation sourceInformation = sourceInformationStrategy
@@ -106,12 +111,12 @@
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
           _options,
-          codegen.emitter,
+          emitter,
           codegen.checkedModeHelpers,
           codegen.oneShotInterceptorData,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
-          codegen.namer,
+          namer,
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
@@ -127,7 +132,9 @@
       HGraph graph,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
-      CodegenRegistry registry) {
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     return measure(() {
       if (method.asyncMarker != AsyncMarker.SYNC) {
         registry.registerAsyncMarker(method.asyncMarker);
@@ -135,12 +142,12 @@
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
           _options,
-          codegen.emitter,
+          emitter,
           codegen.checkedModeHelpers,
           codegen.oneShotInterceptorData,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
-          codegen.namer,
+          namer,
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index c1ee6cb..7639921 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -5,7 +5,8 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../inferrer/abstract_value_domain.dart';
-import '../js_backend/js_backend.dart';
+import '../js_backend/js_backend.dart'
+    show SuperMemberData, SyntheticConstantKind;
 import '../js_backend/interceptor_data.dart';
 import '../options.dart';
 import '../universe/selector.dart' show Selector;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 9e87a54..8852a01 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -15,7 +15,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
-import '../js_backend/js_backend.dart';
+import '../js_backend/backend.dart' show SyntheticConstantKind;
 import '../native/behavior.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index f49e608..b605866 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -15,7 +15,7 @@
 import '../inferrer/types.dart';
 import '../js_backend/field_analysis.dart'
     show FieldAnalysisData, JFieldAnalysis;
-import '../js_backend/backend.dart';
+import '../js_backend/backend.dart' show CodegenInputs, SyntheticConstantKind;
 import '../js_backend/native_data.dart' show NativeData;
 import '../js_backend/runtime_types.dart';
 import '../native/behavior.dart';
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 59f4ff7..12f1db9 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -16,6 +16,9 @@
 import '../js/js.dart' as js;
 import '../js/rewrite_async.dart';
 import '../js_backend/backend.dart' show CodegenInputs, FunctionCompiler;
+import '../js_backend/namer.dart' show ModularNamer, ModularNamerImpl;
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
+import '../js_emitter/startup_emitter/emitter.dart' show ModularEmitterImpl;
 import '../js_model/elements.dart';
 import '../options.dart';
 import '../universe/call_structure.dart' show CallStructure;
@@ -27,56 +30,70 @@
 import 'optimize.dart';
 
 class SsaFunctionCompiler implements FunctionCompiler {
+  final CompilerOptions _options;
   final DiagnosticReporter _reporter;
   final SsaCodeGeneratorTask generator;
   final SsaBuilderTask _builder;
   final SsaOptimizerTask optimizer;
   final SourceInformationStrategy sourceInformationStrategy;
+  GlobalTypeInferenceResults _globalInferenceResults;
+  CodegenInputs _codegen;
 
   SsaFunctionCompiler(
-      CompilerOptions options,
+      this._options,
       this._reporter,
       BackendStrategy backendStrategy,
       Measurer measurer,
       this.sourceInformationStrategy)
       : generator = new SsaCodeGeneratorTask(
-            measurer, options, sourceInformationStrategy),
+            measurer, _options, sourceInformationStrategy),
         _builder = new SsaBuilderTask(
             measurer, backendStrategy, sourceInformationStrategy),
-        optimizer = new SsaOptimizerTask(measurer, options);
+        optimizer = new SsaOptimizerTask(measurer, _options);
 
   @override
-  void onCodegenStart(CodegenInputs codegen) {
-    _builder.onCodegenStart(codegen);
+  void initialize(GlobalTypeInferenceResults globalInferenceResults,
+      CodegenInputs codegen) {
+    _globalInferenceResults = globalInferenceResults;
+    _codegen = codegen;
+    _builder.onCodegenStart();
   }
 
-  /// Generates JavaScript code for `work.element`.
+  /// Generates JavaScript code for [member].
   /// Using the ssa builder, optimizer and code generator.
   @override
-  CodegenResult compile(
-      MemberEntity member,
-      CodegenInputs codegen,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
+  CodegenResult compile(MemberEntity member) {
+    JClosedWorld closedWorld = _globalInferenceResults.closedWorld;
     CodegenRegistry registry =
         new CodegenRegistry(closedWorld.elementEnvironment, member);
-    HGraph graph =
-        _builder.build(member, closedWorld, globalInferenceResults, registry);
+    ModularNamer namer = new ModularNamerImpl(registry,
+        closedWorld.commonElements, _codegen.rtiTags, _codegen.fixedNames);
+    ModularEmitter emitter = new ModularEmitterImpl(namer, registry, _options);
+    if (member.isConstructor &&
+        member.enclosingClass == closedWorld.commonElements.jsNullClass) {
+      // Work around a problem compiling JSNull's constructor.
+      return registry.close(null);
+    }
+
+    HGraph graph = _builder.build(member, closedWorld, _globalInferenceResults,
+        _codegen, registry, namer, emitter);
     if (graph == null) {
       return registry.close(null);
     }
-    optimizer.optimize(
-        member, graph, codegen, closedWorld, globalInferenceResults, registry);
-    js.Expression result =
-        generator.generateCode(member, graph, codegen, closedWorld, registry);
+    optimizer.optimize(member, graph, _codegen, closedWorld,
+        _globalInferenceResults, registry);
+    js.Expression result = generator.generateCode(
+        member, graph, _codegen, closedWorld, registry, namer, emitter);
     if (graph.needsAsyncRewrite) {
       SourceInformationBuilder sourceInformationBuilder =
           sourceInformationStrategy.createBuilderForContext(member);
       result = _rewriteAsync(
-          codegen,
+          _codegen,
           closedWorld.commonElements,
           closedWorld.elementEnvironment,
           registry,
+          namer,
+          emitter,
           member,
           result,
           graph.asyncElementType,
@@ -96,6 +113,8 @@
       CommonElements commonElements,
       JElementEnvironment elementEnvironment,
       CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter,
       FunctionEntity element,
       js.Expression code,
       DartType asyncTypeParameter,
@@ -104,7 +123,7 @@
     if (element.asyncMarker == AsyncMarker.SYNC) return code;
 
     AsyncRewriterBase rewriter = null;
-    js.Name name = codegen.namer.methodPropertyName(
+    js.Name name = namer.methodPropertyName(
         element is JGeneratorBody ? element.function : element);
 
     switch (element.asyncMarker) {
@@ -114,6 +133,8 @@
             commonElements,
             elementEnvironment,
             registry,
+            namer,
+            emitter,
             element,
             code,
             asyncTypeParameter,
@@ -121,18 +142,18 @@
         break;
       case AsyncMarker.SYNC_STAR:
         rewriter = new SyncStarRewriter(_reporter, element,
-            endOfIteration: codegen.emitter
-                .staticFunctionAccess(commonElements.endOfIteration),
-            iterableFactory: codegen.emitter
+            endOfIteration:
+                emitter.staticFunctionAccess(commonElements.endOfIteration),
+            iterableFactory: emitter
                 .staticFunctionAccess(commonElements.syncStarIterableFactory),
             iterableFactoryTypeArguments:
-                _fetchItemType(codegen, asyncTypeParameter),
+                _fetchItemType(codegen, emitter, asyncTypeParameter),
             yieldStarExpression:
-                codegen.emitter.staticFunctionAccess(commonElements.yieldStar),
-            uncaughtErrorExpression: codegen.emitter
+                emitter.staticFunctionAccess(commonElements.yieldStar),
+            uncaughtErrorExpression: emitter
                 .staticFunctionAccess(commonElements.syncStarUncaughtError),
-            safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-            bodyName: codegen.namer.deriveAsyncBodyName(name));
+            safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+            bodyName: namer.deriveAsyncBodyName(name));
         registry.registerStaticUse(new StaticUse.staticInvoke(
             commonElements.syncStarIterableFactory,
             const CallStructure.unnamed(1, 1), [
@@ -141,22 +162,21 @@
         break;
       case AsyncMarker.ASYNC_STAR:
         rewriter = new AsyncStarRewriter(_reporter, element,
-            asyncStarHelper: codegen.emitter
-                .staticFunctionAccess(commonElements.asyncStarHelper),
-            streamOfController: codegen.emitter
-                .staticFunctionAccess(commonElements.streamOfController),
-            wrapBody:
-                codegen.emitter.staticFunctionAccess(commonElements.wrapBody),
-            newController: codegen.emitter.staticFunctionAccess(
+            asyncStarHelper:
+                emitter.staticFunctionAccess(commonElements.asyncStarHelper),
+            streamOfController:
+                emitter.staticFunctionAccess(commonElements.streamOfController),
+            wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
+            newController: emitter.staticFunctionAccess(
                 commonElements.asyncStarStreamControllerFactory),
             newControllerTypeArguments:
-                _fetchItemType(codegen, asyncTypeParameter),
-            safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-            yieldExpression: codegen.emitter
-                .staticFunctionAccess(commonElements.yieldSingle),
+                _fetchItemType(codegen, emitter, asyncTypeParameter),
+            safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+            yieldExpression:
+                emitter.staticFunctionAccess(commonElements.yieldSingle),
             yieldStarExpression:
-                codegen.emitter.staticFunctionAccess(commonElements.yieldStar),
-            bodyName: codegen.namer.deriveAsyncBodyName(name));
+                emitter.staticFunctionAccess(commonElements.yieldStar),
+            bodyName: namer.deriveAsyncBodyName(name));
         registry.registerStaticUse(new StaticUse.staticInvoke(
             commonElements.asyncStarStreamControllerFactory,
             const CallStructure.unnamed(1, 1), [
@@ -172,10 +192,10 @@
   /// added as a function parameter to the rewritten code.
   // TODO(sra): We could also return an empty list if the generator takes no
   // type (e.g. due to rtiNeed optimization).
-  List<js.Expression> _fetchItemType(CodegenInputs codegen, DartType type) {
+  List<js.Expression> _fetchItemType(
+      CodegenInputs codegen, ModularEmitter emitter, DartType type) {
     if (type == null) return null;
-    var ast =
-        codegen.rtiEncoder.getTypeRepresentation(codegen.emitter, type, null);
+    var ast = codegen.rtiEncoder.getTypeRepresentation(emitter, type, null);
     return <js.Expression>[ast];
   }
 
@@ -184,6 +204,8 @@
       CommonElements commonElements,
       JElementEnvironment elementEnvironment,
       CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter,
       FunctionEntity element,
       js.Expression code,
       DartType elementType,
@@ -192,22 +214,21 @@
     FunctionEntity completerFactory = commonElements.asyncAwaitCompleterFactory;
 
     List<js.Expression> itemTypeExpression =
-        _fetchItemType(codegen, elementType);
+        _fetchItemType(codegen, emitter, elementType);
 
     AsyncRewriter rewriter = new AsyncRewriter(_reporter, element,
-        asyncStart: codegen.emitter.staticFunctionAccess(startFunction),
-        asyncAwait: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperAwait),
-        asyncReturn: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperReturn),
-        asyncRethrow: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperRethrow),
-        wrapBody: codegen.emitter.staticFunctionAccess(commonElements.wrapBody),
-        completerFactory:
-            codegen.emitter.staticFunctionAccess(completerFactory),
+        asyncStart: emitter.staticFunctionAccess(startFunction),
+        asyncAwait:
+            emitter.staticFunctionAccess(commonElements.asyncHelperAwait),
+        asyncReturn:
+            emitter.staticFunctionAccess(commonElements.asyncHelperReturn),
+        asyncRethrow:
+            emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
+        wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
+        completerFactory: emitter.staticFunctionAccess(completerFactory),
         completerFactoryTypeArguments: itemTypeExpression,
-        safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-        bodyName: codegen.namer.deriveAsyncBodyName(name));
+        safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+        bodyName: namer.deriveAsyncBodyName(name));
 
     registry.registerStaticUse(new StaticUse.staticInvoke(
         completerFactory,
@@ -230,7 +251,10 @@
       MemberEntity member,
       JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults,
-      CodegenRegistry registry);
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter);
 }
 
 class SsaBuilderTask extends CompilerTask {
@@ -245,9 +269,9 @@
   @override
   String get name => 'SSA builder';
 
-  void onCodegenStart(CodegenInputs codegen) {
-    _builder = _backendStrategy.createSsaBuilder(
-        this, codegen, _sourceInformationFactory);
+  void onCodegenStart() {
+    _builder =
+        _backendStrategy.createSsaBuilder(this, _sourceInformationFactory);
   }
 
   /// Creates the [HGraph] for [member] or returns `null` if no code is needed
@@ -256,8 +280,11 @@
       MemberEntity member,
       JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults,
-      CodegenRegistry registry) {
-    return _builder.build(
-        member, closedWorld, globalInferenceResults, registry);
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
+    return _builder.build(member, closedWorld, globalInferenceResults, codegen,
+        registry, namer, emitter);
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
index bebc7e6..1733898 100644
--- a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
+++ b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import 'package:kernel/ast.dart' as ir;
 
 /// Helper class that traverses a kernel AST subtree to see if it has any
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index a9f6e39..33f1006 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../common.dart';
-import '../js_backend/js_backend.dart';
+import '../js_backend/namer.dart' show ModularNamer;
 import 'codegen.dart' show CodegenPhase;
 import 'nodes.dart';
 
@@ -450,7 +450,7 @@
 /// Allocates variable names for instructions, making sure they don't collide.
 class VariableNamer {
   final VariableNames names;
-  final Namer _namer;
+  final ModularNamer _namer;
   final Set<String> usedNames;
   final List<String> freeTemporaryNames;
   int temporaryIndex = 0;
@@ -570,7 +570,7 @@
 /// instruction, and allocates a name to the instruction. For each phi,
 /// it adds a copy to the CopyHandler of the corresponding predecessor.
 class SsaVariableAllocator extends HBaseVisitor with CodegenPhase {
-  final Namer _namer;
+  final ModularNamer _namer;
   final Map<HBasicBlock, LiveEnvironment> liveInstructions;
   final Map<HInstruction, LiveInterval> liveIntervals;
   final Set<HInstruction> generateAtUseSite;
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index 3cb288c..082edeb 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -20,12 +20,10 @@
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/apiimpl.dart' as apiimpl;
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/inferrer/types.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/null_compiler_output.dart';
 import 'package:compiler/src/options.dart' show CompilerOptions;
 import 'package:compiler/src/universe/world_impact.dart';
-import 'package:compiler/src/world.dart';
 import 'diagnostic_reporter_helper.dart';
 
 class TestCompiler extends apiimpl.CompilerImpl {
@@ -110,10 +108,9 @@
             useNewSourceInfo: compiler.options.useNewSourceInfo);
 
   @override
-  WorldImpact generateCode(WorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results, CodegenInputs codegen) {
+  WorldImpact generateCode(WorkItem work) {
     compiler.test('Compiler.codegen');
-    return super.generateCode(work, closedWorld, results, codegen);
+    return super.generateCode(work);
   }
 }
 
diff --git a/tests/compiler/dart2js/serialization/serialization_test_helper.dart b/tests/compiler/dart2js/serialization/serialization_test_helper.dart
index 9f48d01..43ee996 100644
--- a/tests/compiler/dart2js/serialization/serialization_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/serialization_test_helper.dart
@@ -60,7 +60,7 @@
 
   Map<OutputType, Map<String, String>> output = collector1.clear();
 
-  compiler.generateJavaScriptCode(newGlobalInferenceResults);
+  compiler.emitJavaScriptCode(newGlobalInferenceResults);
   Map<OutputType, Map<String, String>> newOutput = collector2.clear();
 
   Expect.setEquals(output.keys, newOutput.keys, "Output type mismatch.");