diff --git a/pkg/dev_compiler/lib/src/compiler/module_containers.dart b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
deleted file mode 100644
index 6c76688..0000000
--- a/pkg/dev_compiler/lib/src/compiler/module_containers.dart
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2020, 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.
-
-// @dart = 2.9
-
-import '../compiler/js_names.dart' as js_ast;
-import '../js_ast/js_ast.dart' as js_ast;
-import '../js_ast/js_ast.dart' show js;
-
-/// Represents a top-level property hoisted to a top-level object.
-class ModuleItemData {
-  /// The container that holds this module item in the emitted JS.
-  js_ast.Identifier id;
-
-  /// This module item's key in the emitted JS.
-  ///
-  /// A LiteralString if this object is backed by a JS Object/Map.
-  /// A LiteralNumber if this object is backed by a JS Array.
-  js_ast.Literal jsKey;
-
-  /// This module item's value in the emitted JS.
-  js_ast.Expression jsValue;
-
-  ModuleItemData(this.id, this.jsKey, this.jsValue);
-}
-
-/// Holds variables emitted during code gen.
-///
-/// Associates a [K] with a container-unique JS key and arbitrary JS value.
-/// The container is emitted as a single object:
-/// ```
-/// var C = {
-///   jsKey: jsValue,
-///   ...
-/// };
-/// ```
-class ModuleItemContainer<K> {
-  /// Name of the container in the emitted JS.
-  String name;
-
-  /// If null, this container will be automatically renamed based on [name].
-  js_ast.Identifier containerId;
-
-  final Map<K, ModuleItemData> moduleItems = {};
-
-  /// Holds keys that will not be emitted when calling [emit].
-  final Set<K> _noEmit = {};
-
-  ModuleItemContainer._(this.name, this.containerId);
-
-  /// Creates an automatically sharding container backed by JS Objects.
-  factory ModuleItemContainer.asObject(String name,
-      {String Function(K) keyToString}) {
-    return ModuleItemObjectContainer<K>(name, keyToString);
-  }
-
-  /// Creates a container backed by a JS Array.
-  factory ModuleItemContainer.asArray(String name) {
-    return ModuleItemArrayContainer<K>(name);
-  }
-
-  bool get isNotEmpty => moduleItems.isNotEmpty;
-
-  Iterable<K> get keys => moduleItems.keys;
-
-  int get length => moduleItems.keys.length;
-
-  js_ast.Expression operator [](K key) => moduleItems[key]?.jsValue;
-
-  void operator []=(K key, js_ast.Expression value) {
-    if (moduleItems.containsKey(key)) {
-      moduleItems[key].jsValue = value;
-      return;
-    }
-    var fieldString = '$key';
-    // Avoid shadowing common JS properties.
-    if (js_ast.objectProperties.contains(fieldString)) {
-      fieldString += '\$';
-    }
-    moduleItems[key] = ModuleItemData(
-        containerId, js_ast.LiteralString("'$fieldString'"), value);
-  }
-
-  /// Returns the expression that retrieves [key]'s corresponding JS value via
-  /// a property access through its container.
-  js_ast.Expression access(K key) {
-    return js.call('#.#', [containerId, moduleItems[key].jsKey]);
-  }
-
-  /// Emit the container declaration/initializer.
-  ///
-  /// May be multiple statements if the container is automatically sharded.
-  List<js_ast.Statement> emit() {
-    var properties = <js_ast.Property>[];
-    moduleItems.forEach((k, v) {
-      if (!_noEmit.contains(k)) return;
-      properties.add(js_ast.Property(v.jsKey, v.jsValue));
-    });
-    var containerObject =
-        js_ast.ObjectInitializer(properties, multiline: properties.length > 1);
-    return [
-      js.statement('var # = Object.create(#)', [containerId, containerObject])
-    ];
-  }
-
-  bool contains(K key) => moduleItems.containsKey(key);
-
-  bool canEmit(K key) => !_noEmit.contains(key);
-
-  /// Indicates that [K] should be treated as if it weren't hoisted.
-  ///
-  /// Used when we are managing the variable declarations manually (such as
-  /// unhoisting specific symbols for performance reasons).
-  void setNoEmit(K key) {
-    _noEmit.add(key);
-  }
-}
-
-/// Associates a [K] with a container-unique JS key and arbitrary JS value.
-///
-/// Emitted as a series of JS Objects, splitting them into groups of 500 for
-/// JS optimization purposes:
-/// ```
-/// var C = {
-///   jsKey: jsValue,
-///   ...
-/// };
-/// var C$1 = { ... };
-/// ```
-class ModuleItemObjectContainer<K> extends ModuleItemContainer<K> {
-  /// Holds the TemporaryId for the current container shard.
-  js_ast.Identifier _currentContainerId;
-
-  /// Tracks how often JS emitted field names appear.
-  ///
-  /// [keyToString] may resolve multiple unique keys to the same JS string.
-  /// When this occurs, the resolved JS string will automatically be renamed.
-  final Map<String, int> _nameFrequencies = {};
-
-  /// Transforms a [K] into a valid name for a JS object property key.
-  ///
-  /// Non-unique generated strings are automatically renamed.
-  String Function(K) keyToString;
-
-  ModuleItemObjectContainer(String name, this.keyToString)
-      : super._(name, null);
-
-  @override
-  void operator []=(K key, js_ast.Expression value) {
-    if (this.contains(key)) {
-      moduleItems[key].jsValue = value;
-      return;
-    }
-    if (length % 500 == 0) _currentContainerId = js_ast.TemporaryId(name);
-    // Create a unique name for K when emitted as a JS field.
-    var fieldString = keyToString(key);
-    _nameFrequencies.update(fieldString, (v) {
-      fieldString += '\$${v + 1}';
-      return v + 1;
-    }, ifAbsent: () {
-      // Avoid shadowing common JS properties.
-      if (js_ast.objectProperties.contains(fieldString)) {
-        fieldString += '\$';
-      }
-      return 0;
-    });
-    moduleItems[key] = ModuleItemData(
-        _currentContainerId, js_ast.LiteralString("'$fieldString'"), value);
-  }
-
-  @override
-  js_ast.Expression access(K key) {
-    return js.call('#.#', [moduleItems[key].id, moduleItems[key].jsKey]);
-  }
-
-  @override
-  List<js_ast.Statement> emit() {
-    var containersToProperties = <js_ast.Identifier, List<js_ast.Property>>{};
-    moduleItems.forEach((k, v) {
-      if (_noEmit.contains(k)) return;
-      if (!containersToProperties.containsKey(v.id)) {
-        containersToProperties[v.id] = <js_ast.Property>[];
-      }
-      containersToProperties[v.id].add(js_ast.Property(v.jsKey, v.jsValue));
-    });
-
-    var statements = <js_ast.Statement>[];
-    containersToProperties.forEach((containerId, properties) {
-      var containerObject = js_ast.ObjectInitializer(properties,
-          multiline: properties.length > 1);
-      statements.add(js.statement(
-          'var # = Object.create(#)', [containerId, containerObject]));
-    });
-    return statements;
-  }
-}
-
-/// Associates a unique [K] with an arbitrary JS value.
-///
-/// Emitted as a JS Array:
-/// ```
-/// var C = [
-///   jsValue,
-///   ...
-/// ];
-/// ```
-class ModuleItemArrayContainer<K> extends ModuleItemContainer<K> {
-  ModuleItemArrayContainer(String name)
-      : super._(name, js_ast.TemporaryId(name));
-
-  @override
-  void operator []=(K key, js_ast.Expression value) {
-    if (moduleItems.containsKey(key)) {
-      moduleItems[key].jsValue = value;
-      return;
-    }
-    moduleItems[key] =
-        ModuleItemData(containerId, js_ast.LiteralNumber('$length'), value);
-  }
-
-  @override
-  js_ast.Expression access(K key) {
-    return js.call('#[#]', [containerId, moduleItems[key].jsKey]);
-  }
-
-  @override
-  List<js_ast.Statement> emit() {
-    if (moduleItems.isEmpty) return [];
-    var properties = List<js_ast.Expression>.filled(length, null);
-
-    // If the entire array holds just one value, generate a short initializer.
-    var valueSet = <js_ast.Expression>{};
-    moduleItems.forEach((k, v) {
-      if (_noEmit.contains(k)) return;
-      valueSet.add(v.jsValue);
-      properties[int.parse((v.jsKey as js_ast.LiteralNumber).value)] =
-          v.jsValue;
-    });
-
-    if (valueSet.length == 1 && moduleItems.length > 1) {
-      return [
-        js.statement('var # = Array(#).fill(#)', [
-          containerId,
-          js_ast.LiteralNumber('${properties.length}'),
-          valueSet.first
-        ])
-      ];
-    }
-    // Array containers are not sharded, as we do not expect to hit V8's
-    // dictionary-mode limit of 99999 elements.
-    return [
-      js.statement('var # = #', [
-        containerId,
-        js_ast.ArrayInitializer(properties, multiline: properties.length > 1)
-      ])
-    ];
-  }
-}
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 2fcad3e..e9527d9 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -8,7 +8,6 @@
 import 'package:meta/meta.dart';
 
 import '../compiler/js_names.dart' as js_ast;
-import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 
@@ -26,10 +25,6 @@
   /// Private member names in this module, organized by their library.
   final _privateNames = HashMap<Library, HashMap<String, js_ast.TemporaryId>>();
 
-  /// Holds all top-level JS symbols (used for caching or indexing fields).
-  final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject('S',
-      keyToString: (js_ast.Identifier i) => '${i.name}');
-
   /// Extension member symbols for adding Dart members to JS types.
   ///
   /// These are added to the [extensionSymbolsModule]; see that field for more
@@ -56,18 +51,11 @@
   /// Whether we're currently building the SDK, which may require special
   /// bootstrapping logic.
   ///
-  /// This is initialized by [emitModule], which must be called before
+  /// This is initialized by [startModule], which must be called before
   /// accessing this field.
   @protected
   bool isBuildingSdk;
 
-  /// Whether or not to move top level symbols into top-level containers.
-  ///
-  /// This is set in both [emitModule] and [emitLibrary].
-  /// Depends on [isBuildingSdk].
-  @protected
-  bool containerizeSymbols;
-
   /// The temporary variable that stores named arguments (these are passed via a
   /// JS object literal, to match JS conventions).
   @protected
@@ -262,16 +250,10 @@
       var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
       idName = idName.replaceAll(js_ast.invalidCharInIdentifier, '_');
       id ??= js_ast.TemporaryId(idName);
-      addSymbol(
-          id,
-          js.call('#.privateName(#, #)',
-              [runtimeModule, emitLibraryName(library), js.string(name)]));
-      if (!containerizeSymbols) {
-        // TODO(vsm): Change back to `const`.
-        // See https://github.com/dart-lang/sdk/issues/40380.
-        moduleItems.add(js.statement('var # = #.privateName(#, #)',
-            [id, runtimeModule, emitLibraryName(library), js.string(name)]));
-      }
+      // TODO(vsm): Change back to `const`.
+      // See https://github.com/dart-lang/sdk/issues/40380.
+      moduleItems.add(js.statement('var # = #.privateName(#, #)',
+          [id, runtimeModule, emitLibraryName(library), js.string(name)]));
       return id;
     }
 
@@ -356,13 +338,9 @@
     var name = js.escapedString(symbolName, "'");
     js_ast.Expression result;
     if (last.startsWith('_')) {
-      var nativeSymbolAccessor =
-          getSymbol(emitPrivateNameSymbol(currentLibrary, last));
-      result = js.call('new #.new(#, #)', [
-        emitConstructorAccess(privateSymbolType),
-        name,
-        nativeSymbolAccessor
-      ]);
+      var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
+      result = js.call('new #.new(#, #)',
+          [emitConstructorAccess(privateSymbolType), name, nativeSymbol]);
     } else {
       result = js.call(
           'new #.new(#)', [emitConstructorAccess(internalSymbolType), name]);
@@ -388,11 +366,12 @@
   /// symbols into the list returned by this method. Finally, [finishModule]
   /// can be called to complete the module and return the resulting JS AST.
   ///
-  /// This also initializes several fields: [runtimeModule],
-  /// [extensionSymbolsModule], and the [_libraries] map needed by
+  /// This also initializes several fields: [isBuildingSdk], [runtimeModule],
+  /// [extensionSymbolsModule], as well as the [_libraries] map needed by
   /// [emitLibraryName].
   @protected
   List<js_ast.ModuleItem> startModule(Iterable<Library> libraries) {
+    isBuildingSdk = libraries.any(isSdkInternalRuntime);
     if (isBuildingSdk) {
       // Don't allow these to be renamed when we're building the SDK.
       // There is JS code in dart:* that depends on their names.
@@ -526,13 +505,9 @@
       if (isBuildingSdk) {
         value = js.call('# = Symbol(#)', [value, js.string('dartx.$name')]);
       }
-      if (!_symbolContainer.canEmit(id)) {
-        // Extension symbols marked with noEmit are managed manually.
-        // TODO(vsm): Change back to `const`.
-        // See https://github.com/dart-lang/sdk/issues/40380.
-        items.add(js.statement('var # = #;', [id, value]));
-      }
-      _symbolContainer[id] = value;
+      // TODO(vsm): Change back to `const`.
+      // See https://github.com/dart-lang/sdk/issues/40380.
+      items.add(js.statement('var # = #;', [id, value]));
     });
   }
 
@@ -559,28 +534,6 @@
         [runtimeModule, js.string(name), module, partMap]));
   }
 
-  /// Returns an accessor for [id] via the symbol container.
-  /// E.g., transforms $sym to S$5.$sym.
-  ///
-  /// A symbol lookup on an id marked no emit omits the symbol accessor.
-  js_ast.Expression getSymbol(js_ast.Identifier id) {
-    return _symbolContainer.canEmit(id) ? _symbolContainer.access(id) : id;
-  }
-
-  /// Returns the raw JS value associated with [id].
-  js_ast.Expression getSymbolValue(js_ast.Identifier id) {
-    return _symbolContainer[id];
-  }
-
-  /// Inserts a symbol into the symbol table.
-  js_ast.Expression addSymbol(js_ast.Identifier id, js_ast.Expression symbol) {
-    _symbolContainer[id] = symbol;
-    if (!containerizeSymbols) {
-      _symbolContainer.setNoEmit(id);
-    }
-    return _symbolContainer[id];
-  }
-
   /// Finishes the module created by [startModule], by combining the preable
   /// [items] with the [moduleItems] that have been emitted.
   ///
@@ -599,9 +552,6 @@
     // code between `startModule` and `finishModule` is very similar in both.
     _emitDebuggerExtensionInfo(moduleName);
 
-    // Emit all top-level JS symbol containers.
-    items.addAll(_symbolContainer.emit());
-
     // Add the module's code (produced by visiting compilation units, above)
     _copyAndFlattenBlocks(items, moduleItems);
     moduleItems.clear();
@@ -632,13 +582,10 @@
   /// handle the many details involved in naming.
   @protected
   js_ast.TemporaryId getExtensionSymbolInternal(String name) {
-    if (!_extensionSymbols.containsKey(name)) {
-      var id = js_ast.TemporaryId(
-          '\$${js_ast.friendlyNameForDartOperator[name] ?? name}');
-      _extensionSymbols[name] = id;
-      addSymbol(id, id);
-    }
-    return _extensionSymbols[name];
+    return _extensionSymbols.putIfAbsent(
+        name,
+        () => js_ast.TemporaryId(
+            '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'));
   }
 
   /// Shorthand for identifier-like property names.
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 8800d4c..db85b79 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -22,7 +22,6 @@
 import '../compiler/js_utils.dart' as js_ast;
 import '../compiler/module_builder.dart'
     show isSdkInternalRuntimeUri, libraryUriToJsIdentifier, pathToJSIdentifier;
-import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../compiler/shared_command.dart' show SharedCompilerOptions;
 import '../compiler/shared_compiler.dart';
 import '../js_ast/js_ast.dart' as js_ast;
@@ -70,14 +69,11 @@
   /// Let variables collected for the given function.
   List<js_ast.TemporaryId> _letVariables;
 
-  final _constTable = js_ast.TemporaryId('CT');
+  final _constTable = _emitTemporaryId('CT');
 
-  /// Constant getters used to populate the constant table.
+  // Constant getters used to populate the constant table.
   final _constLazyAccessors = <js_ast.Method>[];
 
-  /// Container for holding the results of lazily-evaluated constants.
-  final _constTableCache = ModuleItemContainer<String>.asArray('C');
-
   /// Tracks the index in [moduleItems] where the const table must be inserted.
   /// Required for SDK builds due to internal circular dependencies.
   /// E.g., dart.constList depends on JSArray.
@@ -220,7 +216,7 @@
   final constAliasCache = HashMap<Constant, js_ast.Expression>();
 
   /// Maps uri strings in asserts and elsewhere to hoisted identifiers.
-  final _uriContainer = ModuleItemContainer<String>.asArray('I');
+  final _uriMap = HashMap<String, js_ast.Identifier>();
 
   final Class _jsArrayClass;
   final Class _privateSymbolClass;
@@ -327,32 +323,7 @@
 
     var libraries = component.libraries;
 
-    // Initialize library variables.
-    isBuildingSdk = libraries.any(isSdkInternalRuntime);
-
-    // For runtime performance reasons, we only containerize SDK symbols in web
-    // libraries. Otherwise, we use a 600-member cutoff before a module is
-    // containerized. This is somewhat arbitrary but works promisingly for the
-    // SDK and Flutter Web.
-    if (!isBuildingSdk) {
-      // The number of DDC top-level symbols scales with the number of
-      // non-static class members across an entire module.
-      var uniqueNames = HashSet<String>();
-      libraries.forEach((Library l) {
-        l.classes.forEach((Class c) {
-          c.members.forEach((m) {
-            var isStatic =
-                m is Field ? m.isStatic : (m is Procedure ? m.isStatic : false);
-            if (isStatic) return;
-            var name = js_ast.toJSIdentifier(
-                m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_'));
-            uniqueNames.add(name);
-          });
-        });
-      });
-      containerizeSymbols = uniqueNames.length > 600;
-    }
-
+    // Initialize our library variables.
     var items = startModule(libraries);
     _nullableInference.allowNotNullDeclarations = isBuildingSdk;
     _typeTable = TypeTable(runtimeModule);
@@ -364,12 +335,10 @@
       _pendingClasses.addAll(l.classes);
     }
 
-    // Record a safe index after the declaration of type generators and
-    // top-level symbols but before the declaration of any functions.
-    // Various preliminary data structures must be inserted here prior before
-    // referenced by the rest of the module.
-    var safeDeclarationIndex = moduleItems.length;
-    _constTableInsertionIndex = safeDeclarationIndex;
+    // TODO(markzipan): Don't emit this when compiling the SDK.
+    moduleItems
+        .add(js.statement('const # = Object.create(null);', [_constTable]));
+    _constTableInsertionIndex = moduleItems.length;
 
     // Add implicit dart:core dependency so it is first.
     emitLibraryName(_coreTypes.coreLibrary);
@@ -381,25 +350,22 @@
     // This is done by forward declaring items.
     libraries.forEach(_emitLibrary);
 
-    // Emit hoisted assert strings
-    moduleItems.insertAll(safeDeclarationIndex, _uriContainer.emit());
-
-    if (_constTableCache.isNotEmpty) {
-      moduleItems.insertAll(safeDeclarationIndex, _constTableCache.emit());
-    }
-
     // This can cause problems if it's ever true during the SDK build, as it's
     // emitted before dart.defineLazy.
     if (_constLazyAccessors.isNotEmpty) {
-      var constTableDeclaration =
-          js.statement('const # = Object.create(null);', [_constTable]);
       var constTableBody = runtimeStatement(
           'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]);
-      moduleItems.insertAll(
-          _constTableInsertionIndex, [constTableDeclaration, constTableBody]);
+      moduleItems.insert(_constTableInsertionIndex, constTableBody);
       _constLazyAccessors.clear();
     }
 
+    // Add assert locations
+    _uriMap.forEach((location, id) {
+      var value = location == null ? 'null' : js.escapedString(location);
+      moduleItems.insert(
+          _constTableInsertionIndex, js.statement('var # = #;', [id, value]));
+    });
+
     moduleItems.addAll(afterClassDefItems);
     afterClassDefItems.clear();
 
@@ -409,8 +375,9 @@
     // Declare imports and extension symbols
     emitImportsAndExtensionSymbols(items);
 
-    // Emit the hoisted type table cache variables
-    items.addAll(_typeTable.dischargeBoundTypes());
+    // Discharge the type table cache variables and
+    // hoisted definitions.
+    items.addAll(_typeTable.discharge());
 
     return finishModule(items, _options.moduleName);
   }
@@ -475,10 +442,6 @@
     _currentLibrary = library;
     _staticTypeContext.enterLibrary(_currentLibrary);
 
-    if (isBuildingSdk) {
-      containerizeSymbols = _isWebLibrary(library.importUri);
-    }
-
     if (isSdkInternalRuntime(library)) {
       // `dart:_runtime` uses a different order for bootstrapping.
       //
@@ -603,29 +566,10 @@
     _classProperties =
         ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c);
 
-    var body = <js_ast.Statement>[];
-
-    // ClassPropertyModel.build introduces symbols for virtual field accessors.
-    _classProperties.virtualFields.forEach((field, virtualField) {
-      // TODO(vsm): Clean up this logic.
-      //
-      // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
-      // is called multiple times, that symbol is cached.  If the former,
-      // assign directly to [virtualField].  If the latter, copy the old
-      // variable to [virtualField].
-      var symbol = emitClassPrivateNameSymbol(c.enclosingLibrary,
-          getLocalClassName(c), field.name.text, virtualField);
-      if (symbol != virtualField) {
-        addSymbol(virtualField, getSymbolValue(symbol));
-        if (!containerizeSymbols) {
-          body.add(js.statement('const # = #;', [virtualField, symbol]));
-        }
-      }
-    });
-
     var jsCtors = _defineConstructors(c, className);
     var jsMethods = _emitClassMethods(c);
 
+    var body = <js_ast.Statement>[];
     _emitSuperHelperSymbols(body);
     // Deferred supertypes must be evaluated lazily while emitting classes to
     // prevent evaluating a JS expression for a deferred type from influencing
@@ -649,6 +593,7 @@
     // Attach caches on all canonicalized types.
     body.add(runtimeStatement('addTypeCaches(#)', [className]));
 
+    _emitVirtualFieldSymbols(c, body);
     _emitClassSignature(c, className, body);
     _initExtensionSymbols(c);
     if (!c.isMixinDeclaration) {
@@ -699,7 +644,7 @@
 
     var typeConstructor = js.call('(#) => { #; #; return #; }', [
       jsFormals,
-      _typeTable.dischargeFreeTypes(formals),
+      _typeTable.discharge(formals),
       body,
       className ?? _emitIdentifier(name)
     ]);
@@ -1580,13 +1525,7 @@
 
     var body = <js_ast.Statement>[];
     void emitFieldInit(Field f, Expression initializer, TreeNode hoverInfo) {
-      var virtualField = _classProperties.virtualFields[f];
-
-      // Avoid calling getSymbol on _declareMemberName since _declareMemberName
-      // calls _emitMemberName downstream, which already invokes getSymbol.
-      var access = virtualField == null
-          ? _declareMemberName(f)
-          : getSymbol(virtualField);
+      var access = _classProperties.virtualFields[f] ?? _declareMemberName(f);
       var jsInit = _visitInitializer(initializer, f.annotations);
       body.add(jsInit
           .toAssignExpression(js.call('this.#', [access])
@@ -1973,16 +1912,14 @@
   /// wrong behavior if a new field was declared.
   List<js_ast.Method> _emitVirtualFieldAccessor(Field field) {
     var virtualField = _classProperties.virtualFields[field];
-    var virtualFieldSymbol = getSymbol(virtualField);
     var name = _declareMemberName(field);
 
-    var getter = js.fun('function() { return this[#]; }', [virtualFieldSymbol]);
+    var getter = js.fun('function() { return this[#]; }', [virtualField]);
     var jsGetter = js_ast.Method(name, getter, isGetter: true)
       ..sourceInformation = _nodeStart(field);
 
-    var args = field.isFinal
-        ? [js_ast.Super(), name]
-        : [js_ast.This(), virtualFieldSymbol];
+    var args =
+        field.isFinal ? [js_ast.Super(), name] : [js_ast.This(), virtualField];
 
     js_ast.Expression value = _emitIdentifier('value');
     if (!field.isFinal && isCovariantField(field)) {
@@ -2298,13 +2235,13 @@
       var memberLibrary = member?.name?.library ??
           memberClass?.enclosingLibrary ??
           _currentLibrary;
-      return getSymbol(emitPrivateNameSymbol(memberLibrary, name));
+      return emitPrivateNameSymbol(memberLibrary, name);
     }
 
     useExtension ??= _isSymbolizedMember(memberClass, name);
     name = js_ast.memberNameForDartMember(name, _isExternal(member));
     if (useExtension) {
-      return getSymbol(getExtensionSymbolInternal(name));
+      return getExtensionSymbolInternal(name);
     }
     return propertyName(name);
   }
@@ -2921,7 +2858,7 @@
 
       js_ast.Expression addTypeFormalsAsParameters(
           List<js_ast.Expression> elements) {
-        var names = _typeTable.dischargeFreeTypes(typeFormals);
+        var names = _typeTable.discharge(typeFormals);
         return names.isEmpty
             ? js.call('(#) => [#]', [tf, elements])
             : js.call('(#) => {#; return [#];}', [tf, names, elements]);
@@ -3069,8 +3006,9 @@
     // Issue: https://github.com/dart-lang/sdk/issues/43288
     var fun = _emitFunction(functionNode, name);
 
-    var types = _typeTable?.dischargeFreeTypes();
+    var types = _typeTable.discharge();
     var constants = _dischargeConstTable();
+
     var body = js_ast.Block([...?types, ...?constants, ...fun.body.statements]);
     return js_ast.Fun(fun.params, body);
   }
@@ -3164,6 +3102,22 @@
     return result;
   }
 
+  void _emitVirtualFieldSymbols(Class c, List<js_ast.Statement> body) {
+    _classProperties.virtualFields.forEach((field, virtualField) {
+      // TODO(vsm): Clean up this logic.  See comments on the following method.
+      //
+      // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
+      // is called multiple times, that symbol is cached.  If the former,
+      // assign directly to [virtualField].  If the latter, copy the old
+      // variable to [virtualField].
+      var symbol = emitClassPrivateNameSymbol(c.enclosingLibrary,
+          getLocalClassName(c), field.name.text, virtualField);
+      if (symbol != virtualField) {
+        body.add(js.statement('const # = #;', [virtualField, symbol]));
+      }
+    });
+  }
+
   List<js_ast.Identifier> _emitTypeFormals(List<TypeParameter> typeFormals) {
     return typeFormals
         .map((t) => _emitIdentifier(getTypeParameterName(t)))
@@ -3690,11 +3644,14 @@
 
   // Replace a string `uri` literal with a cached top-level variable containing
   // the value to reduce overall code size.
-  js_ast.Expression _cacheUri(String uri) {
-    if (!_uriContainer.contains(uri)) {
-      _uriContainer[uri] = js_ast.LiteralString('"$uri"');
+  js_ast.Identifier _cacheUri(String uri) {
+    var id = _uriMap[uri];
+    if (id == null) {
+      var name = 'L${_uriMap.length}';
+      id = js_ast.TemporaryId(name);
+      _uriMap[uri] = id;
     }
-    return _uriContainer.access(uri);
+    return id;
   }
 
   @override
@@ -5047,7 +5004,7 @@
           return _emitType(firstArg.type);
         }
         if (name == 'extensionSymbol' && firstArg is StringLiteral) {
-          return getSymbol(getExtensionSymbolInternal(firstArg.value));
+          return getExtensionSymbolInternal(firstArg.value);
         }
 
         if (name == 'compileTimeFlag' && firstArg is StringLiteral) {
@@ -5923,19 +5880,19 @@
     }
     var constAliasString = 'C${constAliasCache.length}';
     var constAliasProperty = propertyName(constAliasString);
-
-    _constTableCache[constAliasString] = js.call('void 0');
-    var constAliasAccessor = _constTableCache.access(constAliasString);
-
-    var constAccessor = js.call(
-        '# || #.#', [constAliasAccessor, _constTable, constAliasProperty]);
+    var constAliasId = _emitTemporaryId(constAliasString);
+    var constAccessor =
+        js.call('# || #.#', [constAliasId, _constTable, constAliasProperty]);
     constAliasCache[node] = constAccessor;
     var constJs = super.visitConstant(node);
+    // TODO(vsm): Change back to `let`.
+    // See https://github.com/dart-lang/sdk/issues/40380.
+    moduleItems.add(js.statement('var #;', [constAliasId]));
 
     var func = js_ast.Fun(
         [],
         js_ast.Block([
-          js.statement('return # = #;', [constAliasAccessor, constJs])
+          js.statement('return # = #;', [constAliasId, constJs])
         ]));
     var accessor = js_ast.Method(constAliasProperty, func, isGetter: true);
     _constLazyAccessors.add(accessor);
@@ -6021,8 +5978,8 @@
       // was overridden.
       var symbol = cls.isEnum
           ? _emitMemberName(member.name.text, member: member)
-          : getSymbol(emitClassPrivateNameSymbol(
-              cls.enclosingLibrary, getLocalClassName(cls), member.name.text));
+          : emitClassPrivateNameSymbol(
+              cls.enclosingLibrary, getLocalClassName(cls), member.name.text);
       return js_ast.Property(symbol, constant);
     }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index b9b73fd..ddaf27f 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -4,17 +4,13 @@
 
 // @dart = 2.9
 
-import 'dart:collection';
-
 import 'package:kernel/kernel.dart';
 
 import '../compiler/js_names.dart' as js_ast;
-import '../compiler/module_containers.dart' show ModuleItemContainer;
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import 'kernel_helpers.dart';
 
-/// Returns all non-locally defined type parameters referred to by [t].
 Set<TypeParameter> freeTypeParameters(DartType t) {
   assert(isKnownDartTypeImplementor(t));
   var result = <TypeParameter>{};
@@ -40,144 +36,160 @@
   return result;
 }
 
-/// A name for a type made of JS identifier safe characters.
-///
-/// 'L' and 'N' are prepended to a type name to represent a legacy or nullable
-/// flavor of a type.
-String _typeString(DartType type, {bool flat = false}) {
-  var nullability = type.declaredNullability == Nullability.legacy
-      ? 'L'
-      : type.declaredNullability == Nullability.nullable
-          ? 'N'
-          : '';
-  assert(isKnownDartTypeImplementor(type));
-  if (type is InterfaceType) {
-    var name = '${type.classNode.name}$nullability';
-    var typeArgs = type.typeArguments;
-    if (typeArgs == null) return name;
-    if (typeArgs.every((p) => p == const DynamicType())) return name;
-    return "${name}Of${typeArgs.map(_typeString).join("\$")}";
-  }
-  if (type is FutureOrType) {
-    var name = 'FutureOr$nullability';
-    if (type.typeArgument == const DynamicType()) return name;
-    return '${name}Of${_typeString(type.typeArgument)}';
-  }
-  if (type is TypedefType) {
-    var name = '${type.typedefNode.name}$nullability';
-    var typeArgs = type.typeArguments;
-    if (typeArgs == null) return name;
-    if (typeArgs.every((p) => p == const DynamicType())) return name;
-    return "${name}Of${typeArgs.map(_typeString).join("\$")}";
-  }
-  if (type is FunctionType) {
-    if (flat) return 'Fn';
-    var rType = _typeString(type.returnType, flat: true);
-    var params = type.positionalParameters
-        .take(3)
-        .map((p) => _typeString(p, flat: true));
-    var paramList = params.join('And');
-    var count = type.positionalParameters.length;
-    if (count > 3 || type.namedParameters.isNotEmpty) {
-      paramList = '${paramList}__';
-    } else if (count == 0) {
-      paramList = 'Void';
+/// _CacheTable tracks cache variables for variables that
+/// are emitted in place with a hoisted variable for a cache.
+class _CacheTable {
+  /// Mapping from types to their canonical names.
+  // Use a LinkedHashMap to maintain key insertion order so the generated code
+  // is stable under slight perturbation.  (If this is not good enough we could
+  // sort by name to canonicalize order.)
+  final _names = <DartType, js_ast.TemporaryId>{};
+  Iterable<DartType> get keys => _names.keys.toList();
+
+  js_ast.Statement _dischargeType(DartType type) {
+    var name = _names.remove(type);
+    if (name != null) {
+      return js.statement('let #;', [name]);
     }
-    return '${paramList}To$nullability$rType';
+    return null;
   }
-  if (type is TypeParameterType) return '${type.parameter.name}$nullability';
-  if (type is DynamicType) return 'dynamic';
-  if (type is VoidType) return 'void';
-  if (type is NeverType) return 'Never$nullability';
-  if (type is BottomType) return 'bottom';
-  if (type is NullType) return 'Null';
-  return 'invalid';
+
+  /// Emit a list of statements declaring the cache variables for
+  /// types tracked by this table.  If [typeFilter] is given,
+  /// only emit the types listed in the filter.
+  List<js_ast.Statement> discharge([Iterable<DartType> typeFilter]) {
+    var decls = <js_ast.Statement>[];
+    var types = typeFilter ?? keys;
+    for (var t in types) {
+      var stmt = _dischargeType(t);
+      if (stmt != null) decls.add(stmt);
+    }
+    return decls;
+  }
+
+  bool isNamed(DartType type) => _names.containsKey(type);
+
+  /// A name for a type made of JS identifier safe characters.
+  ///
+  /// 'L' and 'N' are prepended to a type name to represent a legacy or nullable
+  /// flavor of a type.
+  String _typeString(DartType type, {bool flat = false}) {
+    var nullability = type.declaredNullability == Nullability.legacy
+        ? 'L'
+        : type.declaredNullability == Nullability.nullable
+            ? 'N'
+            : '';
+    assert(isKnownDartTypeImplementor(type));
+    if (type is InterfaceType) {
+      var name = '${type.classNode.name}$nullability';
+      var typeArgs = type.typeArguments;
+      if (typeArgs == null) return name;
+      if (typeArgs.every((p) => p == const DynamicType())) return name;
+      return "${name}Of${typeArgs.map(_typeString).join("\$")}";
+    }
+    if (type is FutureOrType) {
+      var name = 'FutureOr$nullability';
+      if (type.typeArgument == const DynamicType()) return name;
+      return '${name}Of${_typeString(type.typeArgument)}';
+    }
+    if (type is TypedefType) {
+      var name = '${type.typedefNode.name}$nullability';
+      var typeArgs = type.typeArguments;
+      if (typeArgs == null) return name;
+      if (typeArgs.every((p) => p == const DynamicType())) return name;
+      return "${name}Of${typeArgs.map(_typeString).join("\$")}";
+    }
+    if (type is FunctionType) {
+      if (flat) return 'Fn';
+      var rType = _typeString(type.returnType, flat: true);
+      var params = type.positionalParameters
+          .take(3)
+          .map((p) => _typeString(p, flat: true));
+      var paramList = params.join('And');
+      var count = type.positionalParameters.length;
+      if (count > 3 || type.namedParameters.isNotEmpty) {
+        paramList = '${paramList}__';
+      } else if (count == 0) {
+        paramList = 'Void';
+      }
+      return '${paramList}To$nullability$rType';
+    }
+    if (type is TypeParameterType) return '${type.parameter.name}$nullability';
+    if (type is DynamicType) return 'dynamic';
+    if (type is VoidType) return 'void';
+    if (type is NeverType) return 'Never$nullability';
+    if (type is BottomType) return 'bottom';
+    if (type is NullType) return 'Null';
+    return 'invalid';
+  }
+
+  /// Heuristically choose a good name for the cache and generator
+  /// variables.
+  js_ast.TemporaryId chooseTypeName(DartType type) {
+    return js_ast.TemporaryId(escapeIdentifier(_typeString(type)));
+  }
+}
+
+/// _GeneratorTable tracks types which have been
+/// named and hoisted.
+class _GeneratorTable extends _CacheTable {
+  final _defs = <DartType, js_ast.Expression>{};
+
+  final js_ast.Identifier _runtimeModule;
+
+  _GeneratorTable(this._runtimeModule);
+
+  @override
+  js_ast.Statement _dischargeType(DartType t) {
+    var name = _names.remove(t);
+    if (name != null) {
+      var init = _defs.remove(t);
+      assert(init != null);
+      // TODO(vsm): Change back to `let`.
+      // See https://github.com/dart-lang/sdk/issues/40380.
+      return js.statement('var # = () => ((# = #.constFn(#))());',
+          [name, name, _runtimeModule, init]);
+    }
+    return null;
+  }
+
+  /// If [type] does not already have a generator name chosen for it,
+  /// assign it one, using [typeRep] as the initializer for it.
+  /// Emit the generator name.
+  js_ast.TemporaryId _nameType(DartType type, js_ast.Expression typeRep) {
+    var temp = _names[type];
+    if (temp == null) {
+      _names[type] = temp = chooseTypeName(type);
+      _defs[type] = typeRep;
+    }
+    return temp;
+  }
 }
 
 class TypeTable {
+  /// Generator variable names for hoisted types.
+  final _GeneratorTable _generators;
+
   /// Mapping from type parameters to the types which must have their
   /// cache/generator variables discharged at the binding site for the
   /// type variable since the type definition depends on the type
   /// parameter.
   final _scopeDependencies = <TypeParameter, List<DartType>>{};
 
-  /// Contains types with any free type parameters and maps them to a unique
-  /// JS identifier.
-  ///
-  /// Used to reference types hoisted to the top of a generic class or generic
-  /// function (as opposed to the top of the entire module).
-  final _unboundTypeIds = HashMap<DartType, js_ast.Identifier>();
-
-  /// Holds JS type generators keyed by their underlying DartType.
-  final typeContainer = ModuleItemContainer<DartType>.asObject('T',
-      keyToString: (DartType t) => escapeIdentifier(_typeString(t)));
-
-  final js_ast.Identifier _runtimeModule;
-
-  TypeTable(this._runtimeModule);
-
-  /// Returns true if [type] is already recorded in the table.
-  bool _isNamed(DartType type) =>
-      typeContainer.contains(type) || _unboundTypeIds.containsKey(type);
-
-  /// Emit the initializer statements for the type container, which contains
-  /// all named types with fully bound type parameters.
-  List<js_ast.Statement> dischargeBoundTypes() {
-    for (var t in typeContainer.keys) {
-      typeContainer[t] = js.call('() => ((# = #.constFn(#))())',
-          [typeContainer.access(t), _runtimeModule, typeContainer[t]]);
-    }
-    return typeContainer.emit();
-  }
-
-  js_ast.Statement _dischargeFreeType(DartType type) {
-    typeContainer.setNoEmit(type);
-    var init = typeContainer[type];
-    var id = _unboundTypeIds[type];
-    // TODO(vsm): Change back to `let`.
-    // See https://github.com/dart-lang/sdk/issues/40380.
-    return js.statement('var # = () => ((# = #.constFn(#))());',
-        [id, id, _runtimeModule, init]);
-  }
+  TypeTable(js_ast.Identifier runtime) : _generators = _GeneratorTable(runtime);
 
   /// Emit a list of statements declaring the cache variables and generator
-  /// definitions tracked by the table so far.
-  ///
-  /// If [formals] is present, only emit the definitions which depend on the
-  /// formals.
-  List<js_ast.Statement> dischargeFreeTypes([Iterable<TypeParameter> formals]) {
-    var decls = <js_ast.Statement>[];
-    var types = formals == null
-        ? typeContainer.keys.where((p) => freeTypeParameters(p).isNotEmpty)
-        : formals.expand((p) => _scopeDependencies[p] ?? <DartType>[]).toSet();
-
-    for (var t in types) {
-      var stmt = _dischargeFreeType(t);
-      if (stmt != null) decls.add(stmt);
-    }
-    return decls;
+  /// definitions tracked by the table.  If [formals] is present, only
+  /// emit the definitions which depend on the formals.
+  List<js_ast.Statement> discharge([List<TypeParameter> formals]) {
+    var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]);
+    var stmts = _generators.discharge(filter);
+    formals?.forEach(_scopeDependencies.remove);
+    return stmts;
   }
 
-  /// Emit a JS expression that evaluates to the generator for [type].
-  ///
-  /// If [type] does not already have a generator name chosen for it,
-  /// assign it one, using [typeRep] as its initializer.
-  js_ast.Expression _nameType(DartType type, js_ast.Expression typeRep) {
-    if (!typeContainer.contains(type)) {
-      typeContainer[type] = typeRep;
-    }
-    return _unboundTypeIds[type] ?? typeContainer.access(type);
-  }
-
-  /// Record the dependencies of the type on its free variables.
-  ///
-  /// Returns true if [type] is a free type parameter (but not a bound) and so
-  /// is not locally hoisted.
+  /// Record the dependencies of the type on its free variables
   bool recordScopeDependencies(DartType type) {
-    if (_isNamed(type)) {
-      return false;
-    }
-
     var freeVariables = freeTypeParameters(type);
     // TODO(leafp): This is a hack to avoid trying to hoist out of
     // generic functions and generic function types.  This often degrades
@@ -188,17 +200,6 @@
       return true;
     }
 
-    // This is only reached when [type] is itself a bound that depends on a
-    // free type parameter.
-    // TODO(markzipan): Bounds are locally hoisted to their own JS identifiers,
-    // but we don't do this this for other types that depend on free variables,
-    // resulting in some duplicated runtime code. We may get some performance
-    // wins if we just locally hoist everything.
-    if (freeVariables.isNotEmpty) {
-      _unboundTypeIds[type] =
-          js_ast.TemporaryId(escapeIdentifier(_typeString(type)));
-    }
-
     for (var free in freeVariables) {
       // If `free` is a promoted type parameter, get the original one so we can
       // find it in our map.
@@ -211,10 +212,10 @@
   /// add the type and its representation to the table, returning an
   /// expression which implements the type (but which caches the value).
   js_ast.Expression nameType(DartType type, js_ast.Expression typeRep) {
-    if (recordScopeDependencies(type)) {
+    if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
       return typeRep;
     }
-    var name = _nameType(type, typeRep);
+    var name = _generators._nameType(type, typeRep);
     return js.call('#()', [name]);
   }
 
@@ -227,10 +228,10 @@
   js_ast.Expression nameFunctionType(
       FunctionType type, js_ast.Expression typeRep,
       {bool lazy = false}) {
-    if (recordScopeDependencies(type)) {
+    if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
       return lazy ? js_ast.ArrowFun([], typeRep) : typeRep;
     }
-    var name = _nameType(type, typeRep);
+    var name = _generators._nameType(type, typeRep);
     return lazy ? name : js.call('#()', [name]);
   }
 }
diff --git a/tools/VERSION b/tools/VERSION
index 4bb1af7..028a34a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 12
 PATCH 0
 PRERELEASE 133
-PRERELEASE_PATCH 1
\ No newline at end of file
+PRERELEASE_PATCH 2
\ No newline at end of file
