Version 2.13.0-93.0.dev

Merge commit 'dcd57353459f85beb7bbe415a452c54fd6e9833a' into 'dev'
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 5a41db4..a78e3bfc4 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -55,22 +55,22 @@
   final String name;
 
   /// The deferred imports that use the elements in this output unit.
-  final Set<ImportEntity> _imports;
+  final Set<ImportEntity> imports;
 
-  OutputUnit(this.isMainOutput, this.name, this._imports);
+  OutputUnit(this.isMainOutput, this.name, this.imports);
 
   @override
   int compareTo(OutputUnit other) {
     if (identical(this, other)) return 0;
     if (isMainOutput && !other.isMainOutput) return -1;
     if (!isMainOutput && other.isMainOutput) return 1;
-    var size = _imports.length;
-    var otherSize = other._imports.length;
+    var size = imports.length;
+    var otherSize = other.imports.length;
     if (size != otherSize) return size.compareTo(otherSize);
-    var imports = _imports.toList();
-    var otherImports = other._imports.toList();
+    var thisImports = imports.toList();
+    var otherImports = other.imports.toList();
     for (var i = 0; i < size; i++) {
-      var cmp = _compareImportEntities(imports[i], otherImports[i]);
+      var cmp = _compareImportEntities(thisImports[i], otherImports[i]);
       if (cmp != 0) return cmp;
     }
     // TODO(sigmund): make compare stable.  If we hit this point, all imported
@@ -80,17 +80,15 @@
     return name.compareTo(other.name);
   }
 
-  Set<ImportEntity> get importsForTesting => _imports;
-
   void merge(OutputUnit that) {
     assert(this != that);
     // We don't currently support merging code into the main output unit.
     assert(!isMainOutput);
-    this._imports.addAll(that._imports);
+    this.imports.addAll(that.imports);
   }
 
   @override
-  String toString() => "OutputUnit($name, $_imports)";
+  String toString() => "OutputUnit($name, $imports)";
 }
 
 class _DeferredLoadTaskMetrics implements Metrics {
@@ -713,7 +711,7 @@
       hunksToLoad[_importDeferName[import]] = [];
       for (OutputUnit outputUnit in sortedOutputUnits) {
         if (outputUnit == _mainOutputUnit) continue;
-        if (outputUnit._imports.contains(import)) {
+        if (outputUnit.imports.contains(import)) {
           hunksToLoad[_importDeferName[import]].add(outputUnit);
           metrics.hunkListElements.add(1);
         }
@@ -874,7 +872,7 @@
     for (var outputUnit in _allOutputUnits) {
       if (!outputUnit.isMainOutput) {
         List<int> representation = List.filled(id, 0);
-        for (var entity in outputUnit._imports) {
+        for (var entity in outputUnit.imports) {
           representation[importMap[entity]] = 1;
         }
         graph.add(representation.join());
@@ -997,7 +995,7 @@
         unitText.write(' <MAIN UNIT>');
       } else {
         unitText.write(' imports:');
-        var imports = outputUnit._imports
+        var imports = outputUnit.imports
             .map((i) => '${i.enclosingLibraryUri.resolveUri(i.uri)}')
             .toList();
         for (var i in imports..sort()) {
@@ -1556,7 +1554,7 @@
       outputUnitIndices[outputUnit] = outputUnitIndices.length;
       sink.writeBool(outputUnit.isMainOutput);
       sink.writeString(outputUnit.name);
-      sink.writeImports(outputUnit._imports);
+      sink.writeImports(outputUnit.imports);
     });
     sink.writeInt(outputUnitIndices[mainOutputUnit]);
     sink.writeClassMap(_classToUnit, (OutputUnit outputUnit) {
@@ -1654,7 +1652,7 @@
     OutputUnit outputUnitTo = outputUnitForMember(to);
     if (outputUnitTo == mainOutputUnit) return true;
     if (outputUnitFrom == mainOutputUnit) return false;
-    return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
+    return outputUnitTo.imports.containsAll(outputUnitFrom.imports);
   }
 
   /// Returns `true` if constant [to] is reachable from element [from] without
@@ -1669,7 +1667,7 @@
     OutputUnit outputUnitTo = outputUnitForConstant(to);
     if (outputUnitTo == mainOutputUnit) return true;
     if (outputUnitFrom == mainOutputUnit) return false;
-    return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
+    return outputUnitTo.imports.containsAll(outputUnitFrom.imports);
   }
 
   /// Returns `true` if class [to] is reachable from element [from] without
@@ -1683,7 +1681,7 @@
     OutputUnit outputUnitTo = outputUnitForClass(to);
     if (outputUnitTo == mainOutputUnit) return true;
     if (outputUnitFrom == mainOutputUnit) return false;
-    return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
+    return outputUnitTo.imports.containsAll(outputUnitFrom.imports);
   }
 
   /// Registers that a constant is used in the same deferred output unit as
@@ -1707,7 +1705,7 @@
 
   /// Returns the names associated with each deferred import in [unit].
   Iterable<String> getImportNames(OutputUnit unit) {
-    return unit._imports.map((i) => _importDeferName[i]);
+    return unit.imports.map((i) => _importDeferName[i]);
   }
 
   /// Returns a json-style map for describing what files that are loaded by a
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
index 576f4ee..4802555 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
@@ -68,11 +68,8 @@
     }
   }
 
-  void mergeAfter(PreFragment that) {
+  PreFragment mergeAfter(PreFragment that) {
     assert(this != that);
-    assert(
-        (that.predecessors.length == 1 && that.predecessors.single == this) ||
-            (this.successors.length == 1 && this.successors.single == that));
     this.fragments.addAll(that.fragments);
     this.classPrototypes.addAll(that.classPrototypes);
     this.closurePrototypes.addAll(that.closurePrototypes);
@@ -98,6 +95,7 @@
     });
     this.predecessors.addAll(that.predecessors);
     this.size += that.size;
+    return this;
   }
 
   FinalizedFragment finalize(
@@ -173,12 +171,17 @@
 
   String debugName() {
     List<String> names = [];
-    this.fragments.forEach((fragment) => names.add(fragment.name));
-    return names.join(',');
-  }
-
-  static int compare(PreFragment l, PreFragment r) {
-    return l.size.compareTo(r.size);
+    this.fragments.forEach(
+        (fragment) => names.add(fragment.outputUnit.imports.toString()));
+    var outputUnitStrings = [];
+    for (var fragment in fragments) {
+      var importString = [];
+      for (var import in fragment.outputUnit.imports) {
+        importString.add(import.name);
+      }
+      outputUnitStrings.add('{${importString.join(', ')}}');
+    }
+    return "${outputUnitStrings.join('+')}";
   }
 }
 
@@ -246,6 +249,16 @@
   }
 }
 
+class _Partition {
+  int size = 0;
+  List<PreFragment> fragments = [];
+
+  void add(PreFragment that) {
+    size += that.size;
+    fragments.add(that);
+  }
+}
+
 class FragmentMerger {
   final CompilerOptions _options;
 
@@ -285,88 +298,50 @@
     });
   }
 
-  // Iterates through preDeferredFragments making as many merges as possible
-  // until either there are no more valid merges to make, or until there are
-  // only mergeFragmentsThreshold remaining.
+  /// A trivial greedy merge that uses the sorted order of the output units to
+  /// merge contiguous runs of fragments without creating cycles.
+  /// ie, if our sorted output units look like:
+  ///   {a}, {b}, {c}, {a, b}, {b, c}, {a, b, c},
+  /// Assuming singletons have size 3, doubles have size 2, and triples have
+  /// size 1, total size would be 14. If we want 3 fragments, we have an ideal
+  /// fragment size of 5. Our final partitions would look like:
+  ///   {a}, {b}, {c}+{a, b}, {b, c}+{a, b, c}.
   List<PreFragment> mergeFragments(List<PreFragment> preDeferredFragments) {
-    Set<PreFragment> fragmentsBySize = {};
+    // Sort PreFragments by their initial OutputUnit so they are in canonical
+    // order.
+    preDeferredFragments.sort((a, b) {
+      return a.fragments.single.outputUnit
+          .compareTo(b.fragments.single.outputUnit);
+    });
+    int desiredNumberOfFragment = _options.mergeFragmentsThreshold;
 
-    // We greedily look for a valid merge which results in the smallest
-    // possible increase in size. Currently, we only merge fragments in two
-    // cases:
-    // 1) We will merge two fragments A and B if B is A's single dependent.
-    // 2) We will merge two fragments C and D if C is D's single dependency.
-    bool mergeTwo() {
-      PreFragment aFragment = null;
-      PreFragment bFragment = null;
-      PreFragment cFragment = null;
-      PreFragment dFragment = null;
-      for (var fragment in fragmentsBySize) {
-        if (fragment.successors.length == 1 &&
-            (aFragment == null && bFragment == null ||
-                (fragment.size + fragment.successors.single.size <
-                    aFragment.size + bFragment.size))) {
-          aFragment = fragment;
-          bFragment = fragment.successors.single;
-        }
-        if (fragment.predecessors.length == 1 &&
-            (cFragment == null && dFragment == null ||
-                (fragment.size + fragment.predecessors.single.size <
-                    cFragment.size + dFragment.size))) {
-          cFragment = fragment.predecessors.single;
-          dFragment = fragment;
-        }
-      }
-      assert((aFragment != null &&
-              bFragment != null &&
-              aFragment != bFragment &&
-              aFragment.successors.single == bFragment) ||
-          (cFragment != null &&
-              dFragment != null &&
-              cFragment != dFragment &&
-              dFragment.predecessors.single == cFragment) ||
-          (aFragment == null &&
-              bFragment == null &&
-              cFragment == null &&
-              dFragment == null));
-      int mergeSentinel = 0x10000000000;
-      bool abCanMerge = aFragment != null && bFragment != null;
-      bool cdCanMerge = cFragment != null && dFragment != null;
-      int abMergeSize =
-          abCanMerge ? aFragment.size + bFragment.size : mergeSentinel;
-      int cdMergeSize =
-          cdCanMerge ? cFragment.size + dFragment.size : mergeSentinel;
-      bool abShouldMerge() => abCanMerge && abMergeSize <= cdMergeSize;
-      bool cdShouldMerge() => cdCanMerge && cdMergeSize <= abMergeSize;
-      void innerMerge(PreFragment a, PreFragment b) {
-        fragmentsBySize.remove(a);
-        fragmentsBySize.remove(b);
-        a.mergeAfter(b);
-        fragmentsBySize.add(a);
-      }
-
-      bool merged = abShouldMerge() || cdShouldMerge();
-      if (abShouldMerge()) {
-        innerMerge(aFragment, bFragment);
-      } else if (cdShouldMerge()) {
-        innerMerge(cFragment, dFragment);
-      } else {
-        assert(aFragment == null &&
-            bFragment == null &&
-            cFragment == null &&
-            dFragment == null);
-      }
-      return merged;
+    // TODO(joshualitt): Precalculate totalSize when computing dependencies.
+    int totalSize = 0;
+    for (var preFragment in preDeferredFragments) {
+      totalSize += preFragment.size;
     }
 
-    fragmentsBySize.addAll(preDeferredFragments);
-    var numFragments = preDeferredFragments.length;
-    while (numFragments-- > _options.mergeFragmentsThreshold) {
-      if (!mergeTwo()) {
-        // No further valid merges can be made.
-        break;
+    int idealFragmentSize = (totalSize / desiredNumberOfFragment).ceil();
+    List<_Partition> partitions = [];
+    void add(PreFragment next) {
+      // Create a new partition if the current one grows too large, otherwise
+      // just add to the most recent partition.
+      if (partitions.isEmpty ||
+          partitions.last.size + next.size > idealFragmentSize) {
+        partitions.add(_Partition());
       }
+      partitions.last.add(next);
     }
-    return fragmentsBySize.toList();
+
+    // Greedily group fragments into partitions.
+    preDeferredFragments.forEach(add);
+
+    // Reduce fragments by merging fragments with fewer imports into fragments
+    // with more imports.
+    List<PreFragment> merged = [];
+    for (var partition in partitions) {
+      merged.add(partition.fragments.reduce((a, b) => b.mergeAfter(a)));
+    }
+    return merged;
   }
 }
diff --git a/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart b/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
index 1da36d1..d50cc23 100644
--- a/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [1{lib1, lib2}], usedBy: [2, 3], needs: []},
   f2: {units: [2{lib1}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   lib2=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [1{lib1, lib2}, 2{lib1}], usedBy: [2], needs: []},
-  f2: {units: [3{lib2}], usedBy: [], needs: [1]}],
- steps=[
-  lib1=(f1),
-  lib2=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 import 'lib1.dart' deferred as lib1;
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
index 963d421..ce14794 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [2{b, c}], usedBy: [2, 3], needs: []},
   f2: {units: [1{b}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   c=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [2{b, c}, 1{b}], usedBy: [2], needs: []},
-  f2: {units: [3{c}], usedBy: [], needs: [1]}],
- steps=[
-  b=(f1),
-  c=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 // Test instantiations with different type argument count used only in two
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
index 53cbbdb..0aba5e2 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [1{b, c}], usedBy: [2, 3], needs: []},
   f2: {units: [2{b}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   c=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [1{b, c}, 2{b}], usedBy: [2], needs: []},
-  f2: {units: [3{c}], usedBy: [], needs: [1]}],
- steps=[
-  b=(f1),
-  c=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 // Test instantiations with the same type argument count used only in two
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
index c6b601b..1629521 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [2{b, c}], usedBy: [2, 3], needs: []},
   f2: {units: [1{b}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   c=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [2{b, c}, 1{b}], usedBy: [2], needs: []},
-  f2: {units: [3{c}], usedBy: [], needs: [1]}],
- steps=[
-  b=(f1),
-  c=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 // Test instantiations with different type argument count used only in two
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
index 8dbfaf1..768282f 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [1{b, c}], usedBy: [2, 3], needs: []},
   f2: {units: [2{b}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   c=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [1{b, c}, 2{b}], usedBy: [2], needs: []},
-  f2: {units: [3{c}], usedBy: [], needs: [1]}],
- steps=[
-  b=(f1),
-  c=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 // Test instantiations with the same type argument count used only in two
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
index 4cd9f15..120b83c 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
@@ -4,18 +4,25 @@
 
 // @dart = 2.7
 
-/*class: Foo:
+/*spec|three-frag.class: Foo:
  class_unit=1{libB},
  type_unit=3{libA, libB, libC}
 */
+/*two-frag.class: Foo:
+ class_unit=1{libB, libA},
+ type_unit=3{libA, libB, libC}
+*/
 class Foo {
-  /*member: Foo.x:member_unit=1{libB}*/
+  /*spec|three-frag.member: Foo.x:member_unit=1{libB}*/
+  /*two-frag.member: Foo.x:member_unit=1{libB, libA}*/
   int x;
-  /*member: Foo.:member_unit=1{libB}*/
+  /*spec|three-frag.member: Foo.:member_unit=1{libB}*/
+  /*two-frag.member: Foo.:member_unit=1{libB, libA}*/
   Foo() {
     x = DateTime.now().millisecond;
   }
-  /*member: Foo.method:member_unit=1{libB}*/
+  /*spec|three-frag.member: Foo.method:member_unit=1{libB}*/
+  /*two-frag.member: Foo.method:member_unit=1{libB, libA}*/
   int method() => x;
 }
 
@@ -24,7 +31,8 @@
   return o is Foo;
 }
 
-/*member: callFooMethod:member_unit=1{libB}*/
+/*spec|three-frag.member: callFooMethod:member_unit=1{libB}*/
+/*two-frag.member: callFooMethod:member_unit=1{libB, libA}*/
 int callFooMethod() {
   return Foo().method();
 }
@@ -56,10 +64,14 @@
 /*member: Coo.:member_unit=2{libC}*/
 class Coo<T> {}
 
-/*class: Doo:
+/*spec|three-frag.class: Doo:
  class_unit=2{libC},
  type_unit=5{libB, libC}
 */
+/*two-frag.class: Doo:
+ class_unit=2{libC},
+ type_unit=5{libB, libC, libA}
+*/
 /*member: Doo.:member_unit=2{libC}*/
 class Doo<T> extends Coo<T> with Boo<T> {}
 
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
index 20c2423..7c98f96 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
@@ -6,14 +6,18 @@
 
 import 'lib.dart' as lib;
 
-/*member: callFooMethod:member_unit=1{libB}*/
+/*spec|three-frag.member: callFooMethod:member_unit=1{libB}*/
+/*two-frag.member: callFooMethod:member_unit=1{libB, libA}*/
 int callFooMethod() => lib.callFooMethod();
 
-/*member: isFoo:member_unit=1{libB}*/
+/*spec|three-frag.member: isFoo:member_unit=1{libB}*/
+/*two-frag.member: isFoo:member_unit=1{libB, libA}*/
 bool isFoo(o) => lib.isFoo(o);
 
-/*member: isFunFunFoo:member_unit=1{libB}*/
+/*spec|three-frag.member: isFunFunFoo:member_unit=1{libB}*/
+/*two-frag.member: isFunFunFoo:member_unit=1{libB, libA}*/
 bool isFunFunFoo(o) => lib.isFunFunFoo(o);
 
-/*member: isDooFunFunFoo:member_unit=1{libB}*/
+/*spec|three-frag.member: isDooFunFunFoo:member_unit=1{libB}*/
+/*two-frag.member: isDooFunFunFoo:member_unit=1{libB, libA}*/
 bool isDooFunFunFoo(o) => o is lib.Doo<lib.FunFunFoo>;
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
index 441c28d..6e80197 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
@@ -18,23 +18,25 @@
 
 /*two-frag.library: 
  output_units=[
-  f1: {units: [3{libA, libB, libC}, 5{libB, libC}, 4{libA, libC}, 6{libA}, 1{libB}], usedBy: [2], needs: []},
-  f2: {units: [2{libC}], usedBy: [], needs: [1]}],
+  f1: {units: [3{libA, libB, libC}], usedBy: [2], needs: []},
+  f2: {units: [5{libB, libC, libA}, 4{libA, libC}, 2{libC}], usedBy: [3], needs: [1]},
+  f3: {units: [1{libB, libA}, 6{libA}], usedBy: [], needs: [2]}],
  steps=[
-  libA=(f1),
-  libB=(f1),
+  libA=(f1, f2, f3),
+  libB=(f1, f2, f3),
   libC=(f1, f2)]
 */
 
 /*three-frag.library: 
  output_units=[
-  f1: {units: [3{libA, libB, libC}, 5{libB, libC}, 4{libA, libC}, 6{libA}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{libB}], usedBy: [], needs: [1]},
-  f3: {units: [2{libC}], usedBy: [], needs: [1]}],
+  f1: {units: [3{libA, libB, libC}, 5{libB, libC}, 4{libA, libC}], usedBy: [3, 2, 4], needs: []},
+  f2: {units: [6{libA}], usedBy: [], needs: [1]},
+  f3: {units: [1{libB}], usedBy: [], needs: [1]},
+  f4: {units: [2{libC}], usedBy: [], needs: [1]}],
  steps=[
-  libA=(f1),
-  libB=(f1, f2),
-  libC=(f1, f3)]
+  libA=(f1, f2),
+  libB=(f1, f3),
+  libC=(f1, f4)]
 */
 
 // @dart = 2.7
@@ -43,7 +45,7 @@
 import 'libb.dart' deferred as libB;
 import 'libc.dart' deferred as libC;
 
-/*member: foo:
+/*spec|three-frag.member: foo:
  constants=[
   FunctionConstant(callFooMethod)=1{libB},
   FunctionConstant(createB2)=2{libC},
@@ -60,6 +62,23 @@
   FunctionConstant(isMega)=6{libA}],
  member_unit=main{}
 */
+/*two-frag.member: foo:
+ constants=[
+  FunctionConstant(callFooMethod)=1{libB, libA},
+  FunctionConstant(createB2)=2{libC},
+  FunctionConstant(createC3)=2{libC},
+  FunctionConstant(createD3)=2{libC},
+  FunctionConstant(createDooFunFunFoo)=2{libC},
+  FunctionConstant(isDooFunFunFoo)=1{libB, libA},
+  FunctionConstant(isFoo)=1{libB, libA},
+  FunctionConstant(isFoo)=2{libC},
+  FunctionConstant(isFoo)=6{libA},
+  FunctionConstant(isFunFunFoo)=1{libB, libA},
+  FunctionConstant(isFunFunFoo)=2{libC},
+  FunctionConstant(isFunFunFoo)=6{libA},
+  FunctionConstant(isMega)=6{libA}],
+ member_unit=main{}
+*/
 void foo() async {
   await libA.loadLibrary();
   await libB.loadLibrary();
diff --git a/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart b/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
index 85002e0..64e287e 100644
--- a/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
+++ b/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
@@ -35,12 +35,13 @@
 f_010_11(Set<String> u, int b) => v(u, '01011', b);
 
 @pragma('dart2js:noInline')
-/*spec|two-frag.member: f_011_01:member_unit=8{b1, b3, b4}*/
-/*three-frag.member: f_011_01:member_unit=8{b1, b3, b4, b2, b5}*/
+/*spec|three-frag.member: f_011_01:member_unit=8{b1, b3, b4}*/
+/*two-frag.member: f_011_01:member_unit=8{b1, b3, b4, b2, b5}*/
 f_011_01(Set<String> u, int b) => v(u, '01101', b);
 
 @pragma('dart2js:noInline')
-/*member: f_011_11:member_unit=9{b1, b2, b3, b4}*/
+/*spec|two-frag.member: f_011_11:member_unit=9{b1, b2, b3, b4}*/
+/*three-frag.member: f_011_11:member_unit=9{b1, b2, b3, b4, b5}*/
 f_011_11(Set<String> u, int b) => v(u, '01111', b);
 
 @pragma('dart2js:noInline')
@@ -52,8 +53,7 @@
 f_100_11(Set<String> u, int b) => v(u, '10011', b);
 
 @pragma('dart2js:noInline')
-/*spec|three-frag.member: f_101_01:member_unit=12{b1, b3, b5}*/
-/*two-frag.member: f_101_01:member_unit=12{b1, b3, b5, b4, b2}*/
+/*member: f_101_01:member_unit=12{b1, b3, b5}*/
 f_101_01(Set<String> u, int b) => v(u, '10101', b);
 
 @pragma('dart2js:noInline')
@@ -105,7 +105,8 @@
 f_110_10(Set<String> u, int b) => v(u, '11010', b);
 
 @pragma('dart2js:noInline')
-/*member: f_111_10:member_unit=24{b2, b3, b4, b5}*/
+/*spec.member: f_111_10:member_unit=24{b2, b3, b4, b5}*/
+/*two-frag|three-frag.member: f_111_10:member_unit=24{b2, b3, b4, b5, b1}*/
 f_111_10(Set<String> u, int b) => v(u, '11110', b);
 
 @pragma('dart2js:noInline')
@@ -113,7 +114,8 @@
 f_001_00(Set<String> u, int b) => v(u, '00100', b);
 
 @pragma('dart2js:noInline')
-/*member: f_011_00:member_unit=26{b3, b4}*/
+/*spec|two-frag.member: f_011_00:member_unit=26{b3, b4}*/
+/*three-frag.member: f_011_00:member_unit=26{b3, b4, b2, b5, b1}*/
 f_011_00(Set<String> u, int b) => v(u, '01100', b);
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
index 0fc9253..6f86ab9 100644
--- a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
@@ -45,27 +45,29 @@
 
 /*three-frag.library: 
  output_units=[
-  f1: {units: [1{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}], usedBy: [2, 3], needs: []},
-  f2: {units: [12{b1, b3, b5}], usedBy: [3], needs: [1]},
-  f3: {units: [8{b1, b3, b4, b2, b5}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 31{b5}, 6{b1, b4}, 29{b4}, 4{b1, b3}, 25{b3}, 3{b1, b2}, 2{b1}, 17{b2}], usedBy: [], needs: [2, 1]}],
+  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [2], needs: []},
+  f2: {units: [24{b2, b3, b4, b5, b1}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [3], needs: [1]},
+  f3: {units: [9{b1, b2, b3, b4, b5}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [4], needs: [2]},
+  f4: {units: [26{b3, b4, b2, b5, b1}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [], needs: [3]}],
  steps=[
-  b1=(f1, f2, f3),
-  b2=(f1, f3),
-  b3=(f1, f2, f3),
-  b4=(f1, f3),
-  b5=(f1, f2, f3)]
+  b1=(f1, f2, f3, f4),
+  b2=(f1, f2, f3, f4),
+  b3=(f1, f2, f3, f4),
+  b4=(f1, f2, f3, f4),
+  b5=(f1, f2, f3, f4)]
 */
 
 /*two-frag.library: 
  output_units=[
-  f1: {units: [1{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}], usedBy: [2], needs: []},
-  f2: {units: [12{b1, b3, b5, b4, b2}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 31{b5}, 6{b1, b4}, 29{b4}, 4{b1, b3}, 25{b3}, 3{b1, b2}, 2{b1}, 17{b2}], usedBy: [], needs: [1]}],
+  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [2], needs: []},
+  f2: {units: [24{b2, b3, b4, b5, b1}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}], usedBy: [3], needs: [1]},
+  f3: {units: [8{b1, b3, b4, b2, b5}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [], needs: [2]}],
  steps=[
-  b1=(f1, f2),
-  b2=(f1, f2),
-  b3=(f1, f2),
-  b4=(f1, f2),
-  b5=(f1, f2)]
+  b1=(f1, f2, f3),
+  b2=(f1, f2, f3),
+  b3=(f1, f2, f3),
+  b4=(f1, f2, f3),
+  b5=(f1, f2, f3)]
 */
 
 import 'lib1.dart';
diff --git a/pkg/compiler/test/deferred_loading/data/static_separate/main.dart b/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
index 78990e9..9c8dd2f 100644
--- a/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [2{lib1, lib2}], usedBy: [2, 3], needs: []},
   f2: {units: [1{lib1}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   lib2=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [2{lib1, lib2}, 1{lib1}], usedBy: [2], needs: []},
-  f2: {units: [3{lib2}], usedBy: [], needs: [1]}],
- steps=[
-  lib1=(f1),
-  lib2=(f1, f2)]
-*/
-
 // @dart = 2.7
 
 // The class lib1.C is referenced via lib1
diff --git a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
index 4cad65c..42fed69 100644
--- a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*spec|three-frag.library: 
+/*library: 
  output_units=[
   f1: {units: [3{lib1, lib3}], usedBy: [2, 3], needs: []},
   f2: {units: [1{lib1}], usedBy: [], needs: [1]},
@@ -12,15 +12,6 @@
   lib3=(f1, f3)]
 */
 
-/*two-frag.library: 
- output_units=[
-  f1: {units: [3{lib1, lib3}, 2{lib3}], usedBy: [2], needs: []},
-  f2: {units: [1{lib1}], usedBy: [], needs: [1]}],
- steps=[
-  lib1=(f1, f2),
-  lib3=(f1)]
-*/
-
 // @dart = 2.7
 
 import 'lib1.dart' deferred as lib1;
diff --git a/pkg/compiler/test/deferred_loading/deferred_loading_test.dart b/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
index e261408..e64d305 100644
--- a/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
+++ b/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
@@ -55,7 +55,7 @@
 String importPrefixString(OutputUnit unit) {
   StringBuffer sb = StringBuffer();
   bool first = true;
-  for (ImportEntity import in unit.importsForTesting) {
+  for (ImportEntity import in unit.imports) {
     if (!first) sb.write(', ');
     sb.write('${import.name}');
     first = false;
diff --git a/tools/VERSION b/tools/VERSION
index d8acf1f..91462d4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 92
+PRERELEASE 93
 PRERELEASE_PATCH 0
\ No newline at end of file