Revert "L8 Cf to Cf"

This reverts commit 49dbca6424489d4320727bbd731175a310d7aa35.

Reason for revert: potential NPE in LambdaClass$Target.holderIsInterface, resulting in total failures in bots and AOSP build

Change-Id: Ifa34a817c549afa2cff7d50f9ace6d83b14cc111
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 23e4e09..1088e60 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -153,7 +153,7 @@
       final CfgPrinter printer = options.printCfg ? new CfgPrinter() : null;
 
       IRConverter converter = new IRConverter(appInfo, options, timing, printer);
-      app = converter.convert(app, executor);
+      app = converter.convertToDex(app, executor);
 
       if (options.printCfg) {
         if (options.printCfgFile == null || options.printCfgFile.isEmpty()) {
@@ -225,7 +225,7 @@
     final CfgPrinter printer = options.printCfg ? new CfgPrinter() : null;
 
     IRConverter converter = new IRConverter(appInfo, options, timing, printer);
-    application = converter.convert(application, executor);
+    application = converter.convertToDex(application, executor);
 
     if (options.printCfg) {
       if (options.printCfgFile == null || options.printCfgFile.isEmpty()) {
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 2ea9573..4bf785c 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -6,19 +6,20 @@
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
 
 import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.dex.ApplicationWriter;
 import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.GraphLense;
 import com.android.tools.r8.ir.conversion.IRConverter;
-import com.android.tools.r8.jar.CfApplicationWriter;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
+import com.google.common.collect.ImmutableList;
 import java.io.IOException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -59,24 +60,24 @@
 
       AppView<?> appView = AppView.createForL8(appInfo, options);
       IRConverter converter = new IRConverter(appView, timing);
-
-      app = converter.convert(app, executor);
+      app = converter.convertToDex(app, executor);
       assert appView.appInfo() == appInfo;
 
       // Close any internal archive providers now the application is fully processed.
       inputApp.closeInternalArchiveProviders();
 
-      new CfApplicationWriter(
+      new ApplicationWriter(
               app,
-              appView,
+              null,
               options,
-              options.getMarker(Tool.L8),
+              ImmutableList.of(options.getMarker(Tool.L8)),
+              null,
               null,
               GraphLense.getIdentityLense(),
               PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
                   options, converter.getAdditionalRewritePrefix()),
               null)
-          .write(options.getClassFileConsumer(), executor);
+          .write(executor);
       options.printWarnings();
     } catch (ExecutionException e) {
       throw unwrapExecutionException(e);
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 944c2bd..3b23ef5 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -72,8 +72,8 @@
       } else if (!getSpecialLibraryConfiguration().equals("default")) {
         reporter.error("L8 currently requires the special library configuration to be \"default\"");
       }
-      if (getProgramConsumer() instanceof DexIndexedConsumer) {
-        reporter.error("L8 does not support compiling to dex");
+      if (getProgramConsumer() instanceof ClassFileConsumer) {
+        reporter.error("L8 does not support compiling to Java class files");
       }
       if (getProgramConsumer() instanceof DexFilePerClassFileConsumer) {
         reporter.error("L8 does not support compiling to dex per class");
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 4b3ace9..5912651 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -40,7 +40,6 @@
 public class CfCode extends Code implements CfOrJarCode {
 
   public static class LocalVariableInfo {
-
     private final int index;
     private final DebugLocalInfo local;
     private final CfLabel start;
@@ -208,7 +207,8 @@
     for (CfInstruction instruction : instructions) {
       if (instruction instanceof CfFrame
           && (classFileVersion <= 49
-              || (classFileVersion == 50 && !options.shouldKeepStackMapTable()))) {
+              || (classFileVersion == 50
+                  && !options.getProguardConfiguration().getKeepAttributes().stackMapTable))) {
         continue;
       }
       instruction.write(visitor, namingLens);
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index fc5874f..90c15c6 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -78,7 +78,6 @@
 import org.objectweb.asm.Opcodes;
 
 public class DexEncodedMethod extends KeyedDexItem<DexMethod> implements ResolutionResult {
-
   public static final String CONFIGURATION_DEBUGGING_PREFIX = "Shaking error: Missing method in ";
 
   /**
@@ -680,18 +679,6 @@
     }
   }
 
-  public static void setDebugInfoWithFakeThisParameter(Code code, int arity, AppView<?> appView) {
-    if (code.isDexCode()) {
-      DexCode dexCode = code.asDexCode();
-      dexCode.setDebugInfo(dexCode.debugInfoWithFakeThisParameter(appView.dexItemFactory()));
-      assert (dexCode.getDebugInfo() == null)
-          || (arity == dexCode.getDebugInfo().parameters.length);
-    } else {
-      // TODO(b/134732760): Patch Cf debug info.
-      assert appView.options().coreLibraryCompilation;
-    }
-  }
-
   private DexEncodedMethod toMethodThatLogsErrorDexCode(DexItemFactory itemFactory) {
     checkIfObsolete();
     Signature signature = MethodSignature.fromDexMethod(method);
@@ -1079,7 +1066,6 @@
   }
 
   public static class ClassInlinerEligibility {
-
     public final boolean returnsReceiver;
 
     public ClassInlinerEligibility(boolean returnsReceiver) {
@@ -1088,14 +1074,12 @@
   }
 
   public static class TrivialInitializer {
-
     private TrivialInitializer() {
     }
 
     // Defines instance trivial initialized, see details in comments
     // to CodeRewriter::computeInstanceInitializerInfo(...)
     public static final class TrivialInstanceInitializer extends TrivialInitializer {
-
       public static final TrivialInstanceInitializer INSTANCE =
           new TrivialInstanceInitializer();
     }
@@ -1103,7 +1087,6 @@
     // Defines class trivial initialized, see details in comments
     // to CodeRewriter::computeClassInitializerInfo(...)
     public static final class TrivialClassInitializer extends TrivialInitializer {
-
       public final DexField field;
 
       public TrivialClassInitializer(DexField field) {
@@ -1113,7 +1096,6 @@
   }
 
   public static class DefaultMethodOptimizationInfoImpl implements MethodOptimizationInfo {
-
     public static final MethodOptimizationInfo DEFAULT_INSTANCE =
         new DefaultMethodOptimizationInfoImpl();
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 87c976d..484a529 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -132,10 +132,6 @@
   private final GeneratedMessageLiteShrinker generatedMessageLiteShrinker;
   private final LibraryMethodOverrideAnalysis libraryMethodOverrideAnalysis;
   private final StringConcatRewriter stringConcatRewriter;
-  private final StringOptimizer stringOptimizer;
-  private final StringBuilderOptimizer stringBuilderOptimizer;
-  private final IdempotentFunctionCallCanonicalizer idempotentFunctionCallCanonicalizer;
-  private final List<DexString> neverMergePrefixes;
   private final LambdaRewriter lambdaRewriter;
   private final D8NestBasedAccessDesugaring d8NestBasedAccessDesugaring;
   private final InterfaceMethodRewriter interfaceMethodRewriter;
@@ -155,9 +151,13 @@
   private final IdentifierNameStringMarker identifierNameStringMarker;
   private final Devirtualizer devirtualizer;
   private final CovariantReturnTypeAnnotationTransformer covariantReturnTypeAnnotationTransformer;
+  private final StringOptimizer stringOptimizer;
+  private final StringBuilderOptimizer stringBuilderOptimizer;
   private final StringSwitchRemover stringSwitchRemover;
   private final UninstantiatedTypeOptimization uninstantiatedTypeOptimization;
   private final TypeChecker typeChecker;
+  private final IdempotentFunctionCallCanonicalizer idempotentFunctionCallCanonicalizer;
+  private final List<DexString> neverMergePrefixes;
 
   final DeadCodeRemover deadCodeRemover;
 
@@ -187,46 +187,6 @@
     this.classInitializerDefaultsOptimization =
         options.debug ? null : new ClassInitializerDefaultsOptimization(appView, this);
     this.stringConcatRewriter = new StringConcatRewriter(appView);
-    this.stringOptimizer = new StringOptimizer(appView);
-    this.stringBuilderOptimizer = new StringBuilderOptimizer(appView);
-    this.deadCodeRemover = new DeadCodeRemover(appView, codeRewriter);
-    this.idempotentFunctionCallCanonicalizer = new IdempotentFunctionCallCanonicalizer(appView);
-    this.neverMergePrefixes =
-        options.neverMergePrefixes.stream()
-            .map(prefix -> "L" + DescriptorUtils.getPackageBinaryNameFromJavaType(prefix))
-            .map(options.itemFactory::createString)
-            .collect(Collectors.toList());
-    if (options.coreLibraryCompilation) {
-      // Specific L8 Settings.
-      // BackportedMethodRewriter is needed for retarget core library members and backports.
-      // InterfaceMethodRewriter is needed for emulated interfaces.
-      // LambdaRewriter is needed because if it is missing there are invoke custom on
-      // default/static interface methods, and this is not supported by the compiler.
-      // The rest is nulled out.
-      this.backportedMethodRewriter = new BackportedMethodRewriter(appView, this);
-      this.interfaceMethodRewriter = new InterfaceMethodRewriter(appView, this);
-      this.lambdaRewriter = new LambdaRewriter(appView, this);
-      this.twrCloseResourceRewriter = null;
-      this.lambdaMerger = null;
-      this.covariantReturnTypeAnnotationTransformer = null;
-      this.nonNullTracker = null;
-      this.classInliner = null;
-      this.classStaticizer = null;
-      this.dynamicTypeOptimization = null;
-      this.generatedMessageLiteShrinker = null;
-      this.libraryMethodOverrideAnalysis = null;
-      this.inliner = null;
-      this.outliner = null;
-      this.memberValuePropagation = null;
-      this.lensCodeRewriter = null;
-      this.identifierNameStringMarker = null;
-      this.devirtualizer = null;
-      this.uninstantiatedTypeOptimization = null;
-      this.typeChecker = null;
-      this.d8NestBasedAccessDesugaring = null;
-      this.stringSwitchRemover = null;
-      return;
-    }
     this.lambdaRewriter = options.enableDesugaring ? new LambdaRewriter(appView, this) : null;
     this.interfaceMethodRewriter =
         options.isInterfaceMethodDesugaringEnabled()
@@ -245,6 +205,8 @@
         options.processCovariantReturnTypeAnnotations
             ? new CovariantReturnTypeAnnotationTransformer(this, appView.dexItemFactory())
             : null;
+    this.stringOptimizer = new StringOptimizer(appView);
+    this.stringBuilderOptimizer = new StringBuilderOptimizer(appView);
     this.nonNullTracker = options.enableNonNullTracking ? new NonNullTracker(appView) : null;
     if (appView.enableWholeProgramOptimizations()) {
       assert appView.appInfo().hasLiveness();
@@ -303,10 +265,17 @@
       this.d8NestBasedAccessDesugaring =
           options.shouldDesugarNests() ? new D8NestBasedAccessDesugaring(appView) : null;
     }
+    this.deadCodeRemover = new DeadCodeRemover(appView, codeRewriter);
+    this.idempotentFunctionCallCanonicalizer = new IdempotentFunctionCallCanonicalizer(appView);
     this.stringSwitchRemover =
         options.isStringSwitchConversionEnabled()
             ? new StringSwitchRemover(appView, identifierNameStringMarker)
             : null;
+    this.neverMergePrefixes =
+        options.neverMergePrefixes.stream()
+            .map(prefix -> "L" + DescriptorUtils.getPackageBinaryNameFromJavaType(prefix))
+            .map(options.itemFactory::createString)
+            .collect(Collectors.toList());
   }
 
   public Set<DexCallSite> getDesugaredCallSites() {
@@ -421,12 +390,12 @@
     }
   }
 
-  public DexApplication convert(DexApplication application, ExecutorService executor)
+  public DexApplication convertToDex(DexApplication application, ExecutorService executor)
       throws ExecutionException {
     removeLambdaDeserializationMethods();
 
     timing.begin("IR conversion");
-    convertClasses(application.classes(), executor);
+    convertClassesToDex(application.classes(), executor);
 
     // Build a new application with jumbo string info,
     Builder<?> builder = application.builder();
@@ -513,22 +482,22 @@
     }
   }
 
-  private void convertClasses(Iterable<DexProgramClass> classes, ExecutorService executor)
-      throws ExecutionException {
+  private void convertClassesToDex(Iterable<DexProgramClass> classes,
+      ExecutorService executor) throws ExecutionException {
     List<Future<?>> futures = new ArrayList<>();
     for (DexProgramClass clazz : classes) {
-      futures.add(executor.submit(() -> convertMethods(clazz)));
+      futures.add(executor.submit(() -> convertMethodsToDex(clazz)));
     }
     ThreadUtils.awaitFutures(futures);
   }
 
-  private void convertMethods(DexProgramClass clazz) {
+  private void convertMethodsToDex(DexProgramClass clazz) {
     boolean isReachabilitySensitive = clazz.hasReachabilitySensitiveAnnotation(options.itemFactory);
     // When converting all methods on a class always convert <clinit> first.
     for (DexEncodedMethod method : clazz.directMethods()) {
       if (method.isClassInitializer()) {
         method.getMutableOptimizationInfo().setReachabilitySensitive(isReachabilitySensitive);
-        convertMethod(method);
+        convertMethodToDex(method);
         break;
       }
     }
@@ -536,17 +505,17 @@
         method -> {
           if (!method.isClassInitializer()) {
             method.getMutableOptimizationInfo().setReachabilitySensitive(isReachabilitySensitive);
-            convertMethod(method);
+            convertMethodToDex(method);
           }
         });
   }
 
-  private void convertMethod(DexEncodedMethod method) {
+  private void convertMethodToDex(DexEncodedMethod method) {
+    assert options.isGeneratingDex();
     if (method.getCode() != null) {
       boolean matchesMethodFilter = options.methodMatchesFilter(method);
       if (matchesMethodFilter) {
-        if (options.isGeneratingClassFiles()
-            || !(options.passthroughDexCode && method.getCode().isDexCode())) {
+        if (!(options.passthroughDexCode && method.getCode().isDexCode())) {
           // We do not process in call graph order, so anything could be a leaf.
           rewriteCode(method, simpleOptimizationFeedback, x -> true, CallSiteInformation.empty(),
               Outliner::noProcessing);
@@ -561,9 +530,7 @@
             }
           }
         }
-        if (!options.isGeneratingClassFiles()) {
-          updateHighestSortingStrings(method);
-        }
+        updateHighestSortingStrings(method);
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index ff771b7..d534cf6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -239,7 +239,8 @@
       initializeJava9MethodProviders(factory);
       initializeJava11MethodProviders(factory);
 
-      if (!options.retargetCoreLibMember.isEmpty()) {
+      // interface method desugaring also toggles library emulation.
+      if (options.isInterfaceMethodDesugaringEnabled()) {
         initializeRetargetCoreLibraryMembers(appView);
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index 044b50b..752db0e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -126,7 +126,7 @@
         .setReceiver(clazz.type)
         .setTarget(rewriter.defaultAsMethodOfCompanionClass(method))
         .setInvokeType(Invoke.Type.STATIC)
-        .setIsInterface(false); // Holder is companion class, not an interface.
+        .setIsInterface(target.isInterface());
     return new DexEncodedMethod(
         newMethod,
         newFlags,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index c5f5e24..e044477 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexLibraryClass;
@@ -86,7 +87,11 @@
         MethodAccessFlags newFlags = virtual.accessFlags.copy();
         newFlags.unsetBridge();
         newFlags.promoteToStatic();
-        DexEncodedMethod.setDebugInfoWithFakeThisParameter(code, companionMethod.getArity(), appView);
+        DexCode dexCode = code.asDexCode();
+        dexCode.setDebugInfo(dexCode.debugInfoWithFakeThisParameter(rewriter.factory));
+        assert (dexCode.getDebugInfo() == null)
+            || (companionMethod.getArity() == dexCode.getDebugInfo().parameters.length);
+
         DexEncodedMethod implMethod = new DexEncodedMethod(
             companionMethod, newFlags, virtual.annotations, virtual.parameterAnnotationsList, code);
         virtual.setDefaultInterfaceMethodImplementation(implMethod);
@@ -138,7 +143,11 @@
             throw new CompilationError("Code is missing for private instance "
                 + "interface method: " + oldMethod.toSourceString(), iface.origin);
           }
-          DexEncodedMethod.setDebugInfoWithFakeThisParameter(code, companionMethod.getArity(), appView);
+          DexCode dexCode = code.asDexCode();
+          dexCode.setDebugInfo(dexCode.debugInfoWithFakeThisParameter(rewriter.factory));
+          assert (dexCode.getDebugInfo() == null)
+              || (companionMethod.getArity() == dexCode.getDebugInfo().parameters.length);
+
           companionMethods.add(new DexEncodedMethod(companionMethod,
               newFlags, direct.annotations, direct.parameterAnnotationsList, code));
           graphLensBuilder.move(oldMethod, companionMethod);
@@ -223,7 +232,7 @@
       forwardSourceCodeBuilder
           .setTarget(origMethod)
           .setInvokeType(Type.STATIC)
-          .setIsInterface(false); // We forward to the Companion class, not an interface.
+          .setIsInterface(true);
       DexEncodedMethod newEncodedMethod =
           new DexEncodedMethod(
               newMethod,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 1c7132a..5be5a81 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.graph.ClassAccessFlags;
 import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
@@ -38,19 +39,22 @@
 import java.util.function.Supplier;
 
 /**
- * Represents lambda class generated for a lambda descriptor in context of lambda instantiation
- * point.
+ * Represents lambda class generated for a lambda descriptor in context
+ * of lambda instantiation point.
  *
- * <p>Even though call sites, and thus lambda descriptors, are canonicalized across the application,
- * the context may require several lambda classes to be generated for the same lambda descriptor.
+ * Even though call sites, and thus lambda descriptors, are canonicalized
+ * across the application, the context may require several lambda classes
+ * to be generated for the same lambda descriptor.
  *
- * <p>One reason is that we always generate a lambda class in the same package lambda instantiation
- * point is located in, so if same call site is used in two classes from different packages (which
- * can happen if same public method is being references via method reference expression) we generate
- * separate lambda classes in those packages.
+ * One reason is that we always generate a lambda class in the same package
+ * lambda instantiation point is located in, so if same call site is used in
+ * two classes from different packages (which can happen if same public method
+ * is being references via method reference expression) we generate separate
+ * lambda classes in those packages.
  *
- * <p>Another reason is that if we generate an accessor, we generate it in the class referencing the
- * call site, and thus two such classes will require two separate lambda classes.
+ * Another reason is that if we generate an accessor, we generate it in the
+ * class referencing the call site, and thus two such classes will require two
+ * separate lambda classes.
  */
 final class LambdaClass {
 
@@ -393,11 +397,9 @@
       // To avoid potential conflicts on the name of the lambda method once dispatch becomes virtual
       // we add the method-holder name as suffix to the lambda-method name.
       return new InstanceLambdaImplTarget(
-          rewriter.factory.createMethod(
-              implMethod.holder,
-              implMethod.proto,
-              rewriter.factory.createString(
-                  implMethod.name.toString() + "$" + implMethod.holder.getName())));
+            rewriter.factory.createMethod(implMethod.holder, implMethod.proto,
+                rewriter.factory.createString(
+                    implMethod.name.toString() + "$" + implMethod.holder.getName())));
     }
   }
 
@@ -508,13 +510,6 @@
     DexProgramClass programDefinitionFor(DexType type) {
       return rewriter.converter.appView.appInfo().app().programDefinitionFor(type);
     }
-
-    boolean holderIsInterface() {
-      DexMethod implMethod = descriptor.implHandle.asMethod();
-      DexClass implMethodHolder = definitionFor(implMethod.holder);
-      assert implMethodHolder != null;
-      return implMethodHolder.isInterface();
-    }
   }
 
   // Used for targeting methods referenced directly without creating accessors.
@@ -586,9 +581,10 @@
                   encodedMethod.getCode());
           newMethod.copyMetadata(encodedMethod);
           rewriter.methodMapping.put(encodedMethod.method, callTarget);
-
-          DexEncodedMethod.setDebugInfoWithFakeThisParameter(
-              newMethod.getCode(), callTarget.getArity(), rewriter.converter.appView);
+          DexCode dexCode = newMethod.getCode().asDexCode();
+          dexCode.setDebugInfo(dexCode.debugInfoWithFakeThisParameter(rewriter.factory));
+          assert (dexCode.getDebugInfo() == null)
+              || (callTarget.getArity() == dexCode.getDebugInfo().parameters.length);
           implMethodHolder.setDirectMethod(i, newMethod);
           return true;
         }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
index a5cf917..99112d7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
@@ -232,7 +232,7 @@
                 methodToCall.proto,
                 argValueTypes,
                 argRegisters,
-                target.holderIsInterface()));
+                false /* isInterface */));
 
     // Does the method have return value?
     if (enforcedReturnType.isVoidType()) {
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index ed86c65..5699977 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -117,7 +117,7 @@
     }
     String markerString = marker.toString();
     for (DexProgramClass clazz : application.classes()) {
-      if (clazz.getSynthesizedFrom().isEmpty() || options.coreLibraryCompilation) {
+      if (clazz.getSynthesizedFrom().isEmpty()) {
         writeClass(clazz, consumer, markerString);
       } else {
         throw new Unimplemented("No support for synthetics in the Java bytecode backend.");
@@ -205,8 +205,7 @@
     if (!method.hasClassFileVersion()) {
       // In this case bridges have been introduced for the Cf back-end,
       // which do not have class file version.
-      assert options.testing.enableForceNestBasedAccessDesugaringForTest
-          || options.coreLibraryCompilation;
+      assert options.testing.enableForceNestBasedAccessDesugaringForTest;
       return 0;
     }
     return method.getClassFileVersion();
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 7e788e1..b914026 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -286,10 +286,6 @@
     throw new UnsupportedOperationException("Cannot find internal output mode.");
   }
 
-  public boolean shouldKeepStackMapTable() {
-    return coreLibraryCompilation || getProguardConfiguration().getKeepAttributes().stackMapTable;
-  }
-
   public boolean isGeneratingDex() {
     return isGeneratingDexIndexed() || isGeneratingDexFilePerClassFile();
   }
diff --git a/src/test/examplesJava9/stream/ProgramRewritingTestClass.java b/src/test/examplesJava9/stream/TestClass.java
similarity index 98%
rename from src/test/examplesJava9/stream/ProgramRewritingTestClass.java
rename to src/test/examplesJava9/stream/TestClass.java
index 7eedeb9..f29a4c8 100644
--- a/src/test/examplesJava9/stream/ProgramRewritingTestClass.java
+++ b/src/test/examplesJava9/stream/TestClass.java
@@ -17,7 +17,7 @@
 import java.util.Set;
 import java.util.stream.IntStream;
 
-public class ProgramRewritingTestClass {
+public class TestClass {
 
   // Each print to the console is immediately followed by the expected result so the tests
   // can assert the results by checking the lines 2 by 2.
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
index ab28e74..fc2e5df 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
@@ -10,22 +10,15 @@
 import com.android.tools.r8.L8Command;
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestCompileResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
 import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
 
 public class CoreLibDesugarTestBase extends TestBase {
 
-  private static Map<CacheEntry, TestCompileResult> computedLibraryCache =
-      new ConcurrentHashMap<>();
-
   protected boolean requiresCoreLibDesugaring(TestParameters parameters) {
     // TODO(b/134732760): Use the two other APIS instead.
     return requiresEmulatedInterfaceCoreLibDesugaring(parameters)
@@ -40,45 +33,10 @@
     return parameters.getApiLevel().getLevel() < AndroidApiLevel.P.getLevel();
   }
 
-  protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel) throws RuntimeException {
-    return buildDesugaredLibrary(apiLevel, "", false);
-  }
-
-  protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel, String keepRules)
-      throws RuntimeException {
-    return buildDesugaredLibrary(apiLevel, keepRules, true);
-  }
-
-  protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel, String keepRules, boolean shrink)
-      throws RuntimeException {
-    return buildDesugaredLibrary(apiLevel, keepRules, shrink, ImmutableList.of());
-  }
-
   protected Path buildDesugaredLibrary(
-      AndroidApiLevel apiLevel, String keepRules, boolean shrink, List<Path> additionalProgramFiles)
-      throws RuntimeException {
-    // We wrap exceptions in a RuntimeException to call this from a lambda.
+      AndroidApiLevel apiLevel, List<Path> additionalProgramFiles) {
     try {
-      Path output = temp.newFolder().toPath().resolve("desugar_jdk_libs_dex.zip");
-      CacheEntry cacheEntry = new CacheEntry(apiLevel, keepRules, shrink, additionalProgramFiles);
-      TestCompileResult testCompileResult =
-          computedLibraryCache.computeIfAbsent(
-              cacheEntry,
-              key -> compileDesugaredLibrary(apiLevel, keepRules, shrink, additionalProgramFiles));
-      testCompileResult.writeToZip(output);
-      return output;
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private TestCompileResult compileDesugaredLibrary(
-      AndroidApiLevel apiLevel, String keepRules, boolean shrink, List<Path> additionalProgramFiles)
-      throws RuntimeException {
-    // We wrap exceptions in a RuntimeException to call this from a lambda.
-    try {
-      // TODO(b/138922694): Known performance issue here.
-      Path cfDesugaredLib = temp.newFolder().toPath().resolve("desugar_jdk_libs_cf.zip");
+      Path output = temp.newFolder().toPath().resolve("desugar_jdk_libs.zip");
       L8.run(
           L8Command.builder()
               .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
@@ -86,64 +44,16 @@
               .addProgramFiles(additionalProgramFiles)
               .addSpecialLibraryConfiguration("default")
               .setMinApiLevel(apiLevel.getLevel())
-              .setOutput(cfDesugaredLib, OutputMode.ClassFile)
+              .setOutput(output, OutputMode.DexIndexed)
               .build());
-      if (shrink) {
-        return testForR8(Backend.DEX)
-            .addProgramFiles(cfDesugaredLib)
-            .noMinification()
-            .addKeepRules(keepRules)
-            // We still need P+ library files to resolve classes.
-            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-            .setMinApi(apiLevel)
-            .compile();
-      }
-      return testForD8()
-          .addProgramFiles(cfDesugaredLib)
-          .setMinApi(apiLevel)
-          // We still need P+ library files to resolve classes.
-          .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-          .compile();
+      return output;
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
   }
 
-  private static class CacheEntry {
-
-    private int apiLevel;
-    private String keepRules;
-    private boolean shrink;
-    private List<Path> additionalProgramFiles;
-
-    private CacheEntry(
-        AndroidApiLevel apiLevel,
-        String keepRules,
-        boolean shrink,
-        List<Path> additionalProgramFiles) {
-      this.apiLevel = apiLevel.getLevel();
-      this.keepRules = keepRules;
-      this.shrink = shrink;
-      this.additionalProgramFiles = additionalProgramFiles;
-    }
-
-    @Override
-    public int hashCode() {
-      // In practice there are only 2 sets of additionalProgramFiles with different sizes.
-      return Objects.hash(apiLevel, keepRules, shrink, additionalProgramFiles.size());
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (!(o instanceof CacheEntry)) {
-        return false;
-      }
-      CacheEntry other = (CacheEntry) o;
-      return apiLevel == other.apiLevel
-          && keepRules.equals(other.keepRules)
-          && shrink == other.shrink
-          && additionalProgramFiles.equals(other.additionalProgramFiles);
-    }
+  protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel) {
+    return buildDesugaredLibrary(apiLevel, ImmutableList.of());
   }
 
   protected void assertLines2By2Correct(String stdOut) {
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/DesugaredLibraryContentTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/DesugaredLibraryContentTest.java
index 20d4868..5d803bd 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/DesugaredLibraryContentTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/DesugaredLibraryContentTest.java
@@ -19,7 +19,6 @@
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
 import com.google.common.collect.ImmutableSet;
 import java.util.stream.Collectors;
-import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -40,7 +39,6 @@
 
   @Test
   public void test() throws Exception {
-    Assume.assumeTrue(requiresCoreLibDesugaring(parameters));
     CodeInspector inspector = new CodeInspector(buildDesugaredLibrary(parameters.getApiLevel()));
     assertThat(inspector.clazz("j$.util.Optional"), isPresent());
     assertThat(inspector.clazz("j$.util.OptionalInt"), isPresent());
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/EmulateLibraryInterfaceTest.java
similarity index 76%
rename from src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
rename to src/test/java/com/android/tools/r8/desugar/corelib/EmulateLibraryInterfaceTest.java
index 8aeddab..19763ad 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/EmulateLibraryInterfaceTest.java
@@ -16,111 +16,80 @@
 import com.android.tools.r8.D8TestRunResult;
 import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
 import java.nio.file.Paths;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class ProgramRewritingTest extends CoreLibDesugarTestBase {
-
-  private static final String TEST_CLASS = "stream.ProgramRewritingTestClass";
+public class EmulateLibraryInterfaceTest extends CoreLibDesugarTestBase {
 
   private final TestParameters parameters;
-  private final boolean shrinkCoreLibrary;
 
-  @Parameters(name = "{1}, shrinkCoreLibrary: {0}")
-  public static List<Object[]> data() {
-    return buildParameters(
-        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
   }
 
-  public ProgramRewritingTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
-    this.shrinkCoreLibrary = shrinkDesugaredLibrary;
+  public EmulateLibraryInterfaceTest(TestParameters parameters) {
     this.parameters = parameters;
   }
 
   @Test
-  public void testProgramD8() throws Exception {
-    Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
-    Box<String> keepRulesHolder = new Box<>("");
-    D8TestRunResult d8TestRunResult =
-        testForD8()
-            .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
-            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-            .setMinApi(parameters.getApiLevel())
-            .addOptionsModification(
-                options ->
-                    options.testing.desugaredLibraryKeepRuleConsumer =
-                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
-            .enableCoreLibraryDesugaring()
-            .compile()
-            .inspect(this::checkRewrittenInvokes)
-            .addRunClasspathFiles(
-                buildDesugaredLibrary(
-                    parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
-            .run(parameters.getRuntime(), TEST_CLASS)
-            .assertSuccess();
-    assertLines2By2Correct(d8TestRunResult.getStdOut());
-    assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
-    String stdErr = d8TestRunResult.getStdErr();
-    if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
-      // Flaky: There might be a missing method on lambda deserialization.
+  public void testDispatchClasses() throws Exception {
+    CodeInspector inspector = new CodeInspector(buildDesugaredLibrary(parameters.getApiLevel()));
+    List<FoundClassSubject> dispatchClasses =
+        inspector.allClasses().stream()
+            .filter(
+                clazz ->
+                    clazz
+                        .getOriginalName()
+                        .contains(InterfaceMethodRewriter.EMULATE_LIBRARY_CLASS_NAME_SUFFIX))
+            .collect(Collectors.toList());
+    int numDispatchClasses = requiresCoreLibDesugaring(parameters) ? 9 : 0;
+    assertEquals(numDispatchClasses, dispatchClasses.size());
+    for (FoundClassSubject clazz : dispatchClasses) {
       assertTrue(
-          !stdErr.contains("Could not find method")
-              || stdErr.contains("Could not find method java.lang.invoke.SerializedLambda"));
-    } else {
-      assertFalse(stdErr.contains("Could not find method"));
+          clazz.allMethods().stream()
+              .allMatch(
+                  method ->
+                      method.isStatic()
+                          && method
+                              .streamInstructions()
+                              .anyMatch(InstructionSubject::isInstanceOf)));
     }
-  }
-
-  @Test
-  public void testProgramR8() throws Exception {
-    Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
-    for (Boolean minifying : BooleanUtils.values()) {
-      Box<String> keepRulesHolder = new Box<>("");
-      R8TestRunResult r8TestRunResult =
-          testForR8(parameters.getBackend())
-              .minification(minifying)
-              .addKeepMainRule(TEST_CLASS)
-              .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
-              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-              .setMinApi(parameters.getApiLevel())
-              .addOptionsModification(
-                  options ->
-                      options.testing.desugaredLibraryKeepRuleConsumer =
-                          (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
-              .enableCoreLibraryDesugaring()
-              .compile()
-              .inspect(this::checkRewrittenInvokes)
-              .addRunClasspathFiles(
-                  buildDesugaredLibrary(
-                      parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
-              .run(parameters.getRuntime(), TEST_CLASS)
-              .assertSuccess();
-      assertLines2By2Correct(r8TestRunResult.getStdOut());
-      assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
-      if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
-        // Flaky: There might be a missing method on lambda deserialization.
-        r8TestRunResult.assertStderrMatches(
-            anyOf(
-                not(containsString("Could not find method")),
-                containsString("Could not find method java.lang.invoke.SerializedLambda")));
-      } else {
-        r8TestRunResult.assertStderrMatches(not(containsString("Could not find method")));
+    if (requiresCoreLibDesugaring(parameters)) {
+      DexClass collectionDispatch = inspector.clazz("j$.util.Collection$-EL").getDexClass();
+      for (DexEncodedMethod method : collectionDispatch.methods()) {
+        int numCheckCast =
+            (int)
+                Stream.of(method.getCode().asDexCode().instructions)
+                    .filter(Instruction::isCheckCast)
+                    .count();
+        if (method.qualifiedName().contains("spliterator")) {
+          assertEquals(5, numCheckCast);
+        } else {
+          assertEquals(1, numCheckCast);
+        }
       }
     }
   }
@@ -129,7 +98,7 @@
     if (!requiresCoreLibDesugaring(parameters)) {
       return;
     }
-    ClassSubject classSubject = inspector.clazz(TEST_CLASS);
+    ClassSubject classSubject = inspector.clazz("stream.TestClass");
     assertThat(classSubject, isPresent());
     List<InstructionSubject> invokes =
         classSubject
@@ -171,6 +140,74 @@
     assertTrue(invokes.get(i).toString().contains(s));
   }
 
+  @Test
+  public void testProgramD8() throws Exception {
+    Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
+    Box<String> keepRulesHolder = new Box<>("");
+    D8TestRunResult d8TestRunResult =
+        testForD8()
+            .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
+            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
+            .setMinApi(parameters.getApiLevel())
+            .addOptionsModification(
+                options ->
+                    options.testing.desugaredLibraryKeepRuleConsumer =
+                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
+            .enableCoreLibraryDesugaring()
+            .compile()
+            .inspect(this::checkRewrittenInvokes)
+            .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+            .run(parameters.getRuntime(), "stream.TestClass")
+            .assertSuccess();
+    assertLines2By2Correct(d8TestRunResult.getStdOut());
+    assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+    String stdErr = d8TestRunResult.getStdErr();
+    if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
+      // Flaky: There might be a missing method on lambda deserialization.
+      assertTrue(
+          !stdErr.contains("Could not find method")
+              || stdErr.contains("Could not find method java.lang.invoke.SerializedLambda"));
+    } else {
+      assertFalse(stdErr.contains("Could not find method"));
+    }
+  }
+
+  @Test
+  public void testProgramR8() throws Exception {
+    Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
+    for (Boolean minifying : BooleanUtils.values()) {
+      Box<String> keepRulesHolder = new Box<>("");
+      R8TestRunResult r8TestRunResult =
+          testForR8(parameters.getBackend())
+              .minification(minifying)
+              .addKeepMainRule("stream.TestClass")
+              .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
+              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
+              .setMinApi(parameters.getApiLevel())
+              .addOptionsModification(
+                  options ->
+                      options.testing.desugaredLibraryKeepRuleConsumer =
+                          (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
+              .enableCoreLibraryDesugaring()
+              .compile()
+              .inspect(this::checkRewrittenInvokes)
+              .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+              .run(parameters.getRuntime(), "stream.TestClass")
+              .assertSuccess();
+      assertLines2By2Correct(r8TestRunResult.getStdOut());
+      assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+      if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
+        // Flaky: There might be a missing method on lambda deserialization.
+        r8TestRunResult.assertStderrMatches(
+            anyOf(
+                not(containsString("Could not find method")),
+                containsString("Could not find method java.lang.invoke.SerializedLambda")));
+      } else {
+        r8TestRunResult.assertStderrMatches(not(containsString("Could not find method")));
+      }
+    }
+  }
+
   private void assertGeneratedKeepRulesAreCorrect(String keepRules) {
     String expectedResult =
         StringUtils.lines(
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/EmulatedInterfacesTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/EmulatedInterfacesTest.java
deleted file mode 100644
index cc3a1b0..0000000
--- a/src/test/java/com/android/tools/r8/desugar/corelib/EmulatedInterfacesTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2019, the R8 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.
-
-package com.android.tools.r8.desugar.corelib;
-
-import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertTrue;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
-import com.android.tools.r8.utils.BooleanUtils;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
-import com.android.tools.r8.utils.codeinspector.InstructionSubject;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class EmulatedInterfacesTest extends CoreLibDesugarTestBase {
-
-  private final TestParameters parameters;
-  private final boolean shrinkCoreLibrary;
-
-  @Parameters(name = "{1}, shrinkCoreLibrary: {0}")
-  public static List<Object[]> data() {
-    return buildParameters(
-        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
-  }
-
-  public EmulatedInterfacesTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
-    this.shrinkCoreLibrary = shrinkDesugaredLibrary;
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testEmulatedInterface() throws Exception {
-    Assume.assumeTrue((requiresCoreLibDesugaring(parameters)));
-    CodeInspector inspector =
-        new CodeInspector(
-            buildDesugaredLibrary(
-                parameters.getApiLevel(), "-keep class **$-EL", shrinkCoreLibrary));
-    assertEmulateInterfaceClassesPresentWithDispatchMethods(inspector);
-    assertCollectionMethodsPresentWithCorrectDispatch(inspector);
-  }
-
-  private void assertEmulateInterfaceClassesPresentWithDispatchMethods(CodeInspector inspector) {
-    List<FoundClassSubject> dispatchClasses =
-        inspector.allClasses().stream()
-            .filter(
-                clazz ->
-                    clazz
-                        .getOriginalName()
-                        .contains(InterfaceMethodRewriter.EMULATE_LIBRARY_CLASS_NAME_SUFFIX))
-            .collect(Collectors.toList());
-    int numDispatchClasses = 9;
-    assertEquals(numDispatchClasses, dispatchClasses.size());
-    for (FoundClassSubject clazz : dispatchClasses) {
-      assertTrue(
-          clazz.allMethods().stream()
-              .allMatch(
-                  method ->
-                      method.isStatic()
-                          && method
-                              .streamInstructions()
-                              .anyMatch(InstructionSubject::isInstanceOf)));
-    }
-  }
-
-  private void assertCollectionMethodsPresentWithCorrectDispatch(CodeInspector inspector) {
-    DexClass collectionDispatch = inspector.clazz("j$.util.Collection$-EL").getDexClass();
-    for (DexEncodedMethod method : collectionDispatch.methods()) {
-      int numCheckCast =
-          (int)
-              Stream.of(method.getCode().asDexCode().instructions)
-                  .filter(Instruction::isCheckCast)
-                  .count();
-      if (method.qualifiedName().contains("spliterator")) {
-        assertEquals(5, numCheckCast);
-      } else {
-        assertEquals(1, numCheckCast);
-      }
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/MergingJ$Test.java b/src/test/java/com/android/tools/r8/desugar/corelib/MergingJ$Test.java
index f4f5807..36561cb 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/MergingJ$Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/MergingJ$Test.java
@@ -47,27 +47,20 @@
   }
 
   private Path buildSplitDesugaredLibraryPart1() throws Exception {
-    Path outputCf = temp.newFolder().toPath().resolve("merger-input-cf.zip");
-    Path outputDex = temp.newFolder().toPath().resolve("merger-input-dex.zip");
+    Path output = temp.newFolder().toPath().resolve("merger-input.zip");
     L8.run(
         L8Command.builder()
             .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
             .addProgramFiles(ToolHelper.getDesugarJDKLibs())
             .addSpecialLibraryConfiguration("default")
             .setMinApiLevel(AndroidApiLevel.B.getLevel())
-            .setOutput(outputCf, OutputMode.ClassFile)
+            .setOutput(output, OutputMode.DexIndexed)
             .build());
-    testForD8()
-        .addProgramFiles(outputCf)
-        .setMinApi(AndroidApiLevel.B)
-        .compile()
-        .writeToZip(outputDex);
-    return outputDex;
+    return output;
   }
 
   private Path buildSplitDesugaredLibraryPart2() throws Exception {
-    Path outputCf = temp.newFolder().toPath().resolve("merger-input-split-cf.zip");
-    Path outputDex = temp.newFolder().toPath().resolve("merger-input-split-dex.zip");
+    Path output = temp.newFolder().toPath().resolve("merger-input-split.zip");
     L8.run(
         L8Command.builder()
             .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
@@ -75,13 +68,8 @@
             .addClasspathFiles(ToolHelper.getDesugarJDKLibs())
             .addSpecialLibraryConfiguration("default")
             .setMinApiLevel(AndroidApiLevel.B.getLevel())
-            .setOutput(outputCf, OutputMode.ClassFile)
+            .setOutput(output, OutputMode.DexIndexed)
             .build());
-    testForD8()
-        .addProgramFiles(outputCf)
-        .setMinApi(AndroidApiLevel.B)
-        .compile()
-        .writeToZip(outputDex);
-    return outputDex;
+    return output;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11CoreLibTestBase.java b/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11CoreLibTestBase.java
index 169c7f9..f77099a 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11CoreLibTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11CoreLibTestBase.java
@@ -103,6 +103,6 @@
   protected Path buildDesugaredLibraryWithJavaBaseExtension(AndroidApiLevel apiLevel)
       throws Exception {
     return buildDesugaredLibrary(
-        apiLevel, "", false, ImmutableList.copyOf(JDK_11_JAVA_BASE_EXTENSION_COMPILED_FILES));
+        apiLevel, ImmutableList.copyOf(JDK_11_JAVA_BASE_EXTENSION_COMPILED_FILES));
   }
 }