Relanding "Immediately write usage/deadcode data to consumer."

This cherry-picks 0bebe46dd63e26857b56e35016dce961b9d37a99
with fixed conflicts.

The change was reverted as part of 523ef9455bab0bd029227982f0ade905d710feeb.

Bug: 140141590
Bug: 134734081
Change-Id: Ib30bac143327453d1e7490f1e64219442b54664b
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 2f9c772..e95a53a 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -213,7 +213,6 @@
               options,
               marker == null ? null : ImmutableList.copyOf(markers),
               app.getChecksums(),
-              null,
               GraphLense.getIdentityLense(),
               PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
                   options, converter.getAdditionalRewritePrefix()),
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index 849eadc..e728f6d 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -101,7 +101,6 @@
                 options,
                 markers,
                 null,
-                null,
                 GraphLense.getIdentityLense(),
                 NamingLens.getIdentityLens(),
                 null);
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index 01db907..595e1e3 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -102,7 +102,6 @@
                   options,
                   markers,
                   null,
-                  null,
                   GraphLense.getIdentityLense(),
                   NamingLens.getIdentityLens(),
                   null,
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 1c72b43..ccd53ca 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -129,7 +129,6 @@
           appView,
           options,
           options.getMarker(Tool.L8),
-          null,
           GraphLense.getIdentityLense(),
           PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
               options, converter.getAdditionalRewritePrefix()),
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index aebcbee..105503e 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -189,7 +189,6 @@
       ExecutorService executorService,
       DexApplication application,
       AppView<?> appView,
-      String deadCode,
       GraphLense graphLense,
       NamingLens namingLens,
       InternalOptions options,
@@ -204,7 +203,6 @@
                 appView,
                 options,
                 marker,
-                deadCode,
                 graphLense,
                 namingLens,
                 proguardMapSupplier)
@@ -216,7 +214,6 @@
                 options,
                 Collections.singletonList(marker),
                 null,
-                deadCode,
                 graphLense,
                 namingLens,
                 proguardMapSupplier)
@@ -668,6 +665,10 @@
 
             TreePruner pruner = new TreePruner(application, appViewWithLiveness);
             application = pruner.run();
+            if (options.usageInformationConsumer != null) {
+              ExceptionUtils.withFinishedResourceHandler(
+                  options.reporter, options.usageInformationConsumer);
+            }
             appViewWithLiveness.setAppInfo(
                 appViewWithLiveness
                     .appInfo()
@@ -814,7 +815,6 @@
           executorService,
           application,
           appView,
-          application.deadCode,
           appView.graphLense(),
           PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
               options, additionalRewritePrefix, namingLens),
diff --git a/src/main/java/com/android/tools/r8/bisect/Bisect.java b/src/main/java/com/android/tools/r8/bisect/Bisect.java
index d54ea1a..6b386c5 100644
--- a/src/main/java/com/android/tools/r8/bisect/Bisect.java
+++ b/src/main/java/com/android/tools/r8/bisect/Bisect.java
@@ -187,7 +187,7 @@
     AndroidAppConsumers compatSink = new AndroidAppConsumers(options);
     ApplicationWriter writer =
         new ApplicationWriter(
-            app, null, options, null, null, null, null, NamingLens.getIdentityLens(), null);
+            app, null, options, null, null, null, NamingLens.getIdentityLens(), null);
     writer.write(executor);
     options.signalFinishedToConsumers();
     compatSink.build().writeToDirectory(output, OutputMode.DexIndexed);
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index eb5fa29..431805b 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -69,7 +69,6 @@
 
   public final DexApplication application;
   public final AppView<?> appView;
-  public final String deadCode;
   public final GraphLense graphLense;
   public final NamingLens namingLens;
   public final InternalOptions options;
@@ -143,7 +142,6 @@
       InternalOptions options,
       List<Marker> markers,
       ClassesChecksum checksums,
-      String deadCode,
       GraphLense graphLense,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier) {
@@ -153,7 +151,6 @@
         options,
         markers,
         checksums,
-        deadCode,
         graphLense,
         namingLens,
         proguardMapSupplier,
@@ -166,7 +163,6 @@
       InternalOptions options,
       List<Marker> markers,
       ClassesChecksum checksums,
-      String deadCode,
       GraphLense graphLense,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier,
@@ -178,7 +174,6 @@
     this.options = options;
     this.markers = markers;
     this.checksums = checksums;
-    this.deadCode = deadCode;
     this.graphLense = graphLense;
     this.namingLens = namingLens;
     this.proguardMapSupplier = proguardMapSupplier;
@@ -355,7 +350,6 @@
           graphLense,
           namingLens,
           options,
-          deadCode,
           proguardMapAndId == null ? null : proguardMapAndId.map);
     } finally {
       application.timing.end();
@@ -368,7 +362,6 @@
       GraphLense graphLense,
       NamingLens namingLens,
       InternalOptions options,
-      String deadCode,
       String proguardMapContent) {
     if (options.configurationConsumer != null) {
       ExceptionUtils.withConsumeResourceHandler(
@@ -376,12 +369,6 @@
           options.getProguardConfiguration().getParsedConfiguration());
       ExceptionUtils.withFinishedResourceHandler(options.reporter, options.configurationConsumer);
     }
-    if (options.usageInformationConsumer != null && deadCode != null) {
-      ExceptionUtils.withConsumeResourceHandler(
-          options.reporter, options.usageInformationConsumer, deadCode);
-      ExceptionUtils.withFinishedResourceHandler(
-          options.reporter, options.usageInformationConsumer);
-    }
     if (proguardMapContent != null) {
       assert validateProguardMapParses(proguardMapContent);
       ExceptionUtils.withConsumeResourceHandler(
diff --git a/src/main/java/com/android/tools/r8/graph/DexApplication.java b/src/main/java/com/android/tools/r8/graph/DexApplication.java
index 28c5878..c2375c5 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java
@@ -28,7 +28,6 @@
   public final ImmutableList<DataResourceProvider> dataResourceProviders;
 
   public final ImmutableSet<DexType> mainDexList;
-  public final String deadCode;
 
   private final ClassNameMapper proguardMap;
 
@@ -46,7 +45,6 @@
       ClassNameMapper proguardMap,
       ImmutableList<DataResourceProvider> dataResourceProviders,
       ImmutableSet<DexType> mainDexList,
-      String deadCode,
       ClassesChecksum checksums,
       InternalOptions options,
       DexString highestSortingString,
@@ -54,7 +52,6 @@
     this.proguardMap = proguardMap;
     this.dataResourceProviders = dataResourceProviders;
     this.mainDexList = mainDexList;
-    this.deadCode = deadCode;
     this.checksums = checksums;
     this.options = options;
     this.dexItemFactory = options.itemFactory;
@@ -145,7 +142,6 @@
     final Timing timing;
 
     DexString highestSortingString;
-    String deadCode;
     final Set<DexType> mainDexList = Sets.newIdentityHashSet();
     private final Collection<DexProgramClass> synthesizedClasses;
 
@@ -153,7 +149,6 @@
       this.options = options;
       this.dexItemFactory = options.itemFactory;
       this.timing = timing;
-      this.deadCode = null;
       this.synthesizedClasses = new ArrayList<>();
       this.checksums = null;
     }
@@ -169,7 +164,6 @@
       options = application.options;
       dexItemFactory = application.dexItemFactory;
       mainDexList.addAll(application.mainDexList);
-      deadCode = application.deadCode;
       synthesizedClasses = new ArrayList<>();
       checksums = application.checksums;
     }
@@ -192,19 +186,6 @@
       return self();
     }
 
-    public T appendDeadCode(String deadCodeAtAnotherRound) {
-      if (deadCodeAtAnotherRound == null) {
-        return self();
-      }
-      if (this.deadCode == null) {
-        this.deadCode = deadCodeAtAnotherRound;
-        return self();
-      }
-      // Concatenate existing deadCode info with next round.
-      this.deadCode += deadCodeAtAnotherRound;
-      return self();
-    }
-
     public synchronized T setHighestSortingString(DexString value) {
       highestSortingString = value;
       return self();
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index b6b4d15..efe63f6 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -41,7 +41,6 @@
       ImmutableList<DexLibraryClass> libraryClasses,
       ImmutableList<DataResourceProvider> dataResourceProviders,
       ImmutableSet<DexType> mainDexList,
-      String deadCode,
       ClassesChecksum checksums,
       InternalOptions options,
       DexString highestSortingString,
@@ -50,7 +49,6 @@
         proguardMap,
         dataResourceProviders,
         mainDexList,
-        deadCode,
         checksums,
         options,
         highestSortingString,
@@ -205,7 +203,6 @@
           libraryClasses,
           ImmutableList.copyOf(dataResourceProviders),
           ImmutableSet.copyOf(mainDexList),
-          deadCode,
           checksums,
           options,
           highestSortingString,
diff --git a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
index db87cbb..0458321 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -36,7 +36,6 @@
       ClasspathClassCollection classpathClasses,
       LibraryClassCollection libraryClasses,
       ImmutableSet<DexType> mainDexList,
-      String deadCode,
       ClassesChecksum checksum,
       InternalOptions options,
       DexString highestSortingString,
@@ -45,7 +44,6 @@
         proguardMap,
         dataResourceProviders,
         mainDexList,
-        deadCode,
         checksum,
         options,
         highestSortingString,
@@ -238,7 +236,6 @@
           classpathClasses,
           libraryClasses,
           ImmutableSet.copyOf(mainDexList),
-          deadCode,
           checksums,
           options,
           highestSortingString,
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 abe34ca..6aee26c 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -75,14 +75,12 @@
   private final Marker marker;
 
   public final ProguardMapSupplier proguardMapSupplier;
-  public final String deadCode;
 
   public CfApplicationWriter(
       DexApplication application,
       AppView<?> appView,
       InternalOptions options,
       Marker marker,
-      String deadCode,
       GraphLense graphLense,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier) {
@@ -94,7 +92,6 @@
     assert marker != null;
     this.marker = marker;
     this.proguardMapSupplier = proguardMapSupplier;
-    this.deadCode = deadCode;
   }
 
   public void write(ClassFileConsumer consumer, ExecutorService executor) {
@@ -128,7 +125,6 @@
         graphLense,
         namingLens,
         options,
-        deadCode,
         proguardMapAndId == null ? null : proguardMapAndId.map);
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/TreePruner.java b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
index b952325..002a898 100644
--- a/src/main/java/com/android/tools/r8/shaking/TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.graph.NestMemberClassAttribute;
 import com.android.tools.r8.graph.PresortedComparable;
 import com.android.tools.r8.logging.Log;
+import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
@@ -37,12 +38,15 @@
   private final Set<DexMethod> methodsToKeepForConfigurationDebugging = Sets.newIdentityHashSet();
 
   public TreePruner(DexApplication application, AppView<AppInfoWithLiveness> appView) {
+    InternalOptions options = appView.options();
     this.application = application;
     this.appView = appView;
-
     this.usagePrinter =
-        appView.options().hasUsageInformationConsumer()
-            ? new UsagePrinter()
+        options.hasUsageInformationConsumer()
+            ? new UsagePrinter(
+                s ->
+                    ExceptionUtils.withConsumeResourceHandler(
+                        options.reporter, options.usageInformationConsumer, s))
             : UsagePrinter.DONT_PRINT;
   }
 
@@ -50,7 +54,7 @@
     application.timing.begin("Pruning application...");
     DexApplication result;
     try {
-      result = removeUnused(application).appendDeadCode(usagePrinter.toStringContent()).build();
+      result = removeUnused(application).build();
     } finally {
       application.timing.end();
     }
diff --git a/src/main/java/com/android/tools/r8/shaking/UsagePrinter.java b/src/main/java/com/android/tools/r8/shaking/UsagePrinter.java
index c224dbd..4c04b52 100644
--- a/src/main/java/com/android/tools/r8/shaking/UsagePrinter.java
+++ b/src/main/java/com/android/tools/r8/shaking/UsagePrinter.java
@@ -7,32 +7,28 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.utils.StringUtils;
-import java.nio.charset.StandardCharsets;
+import java.util.function.Consumer;
 
 class UsagePrinter {
   private static final String INDENT = "    ";
 
   static final UsagePrinter DONT_PRINT = new NoOpUsagePrinter();
 
-  private final StringBuilder writer;
+  private final Consumer<String> consumer;
   private DexProgramClass enclosingClazz = null;
   private boolean clazzPrefixPrinted = false;
 
-  UsagePrinter() {
-    writer = new StringBuilder();
+  UsagePrinter(Consumer<String> consumer) {
+    this.consumer = consumer;
   }
 
-  String toStringContent() {
-    return writer.toString();
-  }
-
-  byte[] toByteArray() {
-    return writer.toString().getBytes(StandardCharsets.UTF_8);
+  void append(String string) {
+    consumer.accept(string);
   }
 
   void printUnusedClass(DexProgramClass clazz) {
-    writer.append(clazz.toSourceString());
-    writer.append(StringUtils.LINE_SEPARATOR);
+    append(clazz.toSourceString());
+    append(StringUtils.LINE_SEPARATOR);
   }
 
   // Visiting methods and fields of the given clazz.
@@ -50,51 +46,54 @@
   private void printClazzPrefixIfNecessary() {
     assert enclosingClazz != null;
     if (!clazzPrefixPrinted) {
-      writer.append(enclosingClazz.toSourceString());
-      writer.append(':');
-      writer.append(StringUtils.LINE_SEPARATOR);
+      append(enclosingClazz.toSourceString());
+      append(":");
+      append(StringUtils.LINE_SEPARATOR);
       clazzPrefixPrinted = true;
     }
   }
 
   void printUnusedMethod(DexEncodedMethod method) {
     printClazzPrefixIfNecessary();
-    writer.append(INDENT);
+    append(INDENT);
     String accessFlags = method.accessFlags.toString();
     if (!accessFlags.isEmpty()) {
-      writer.append(accessFlags).append(' ');
+      append(accessFlags);
+      append(" ");
     }
-    writer.append(method.method.proto.returnType.toSourceString()).append(' ');
-    writer.append(method.method.name.toSourceString());
-    writer.append('(');
+    append(method.method.proto.returnType.toSourceString());
+    append(" ");
+    append(method.method.name.toSourceString());
+    append("(");
     for (int i = 0; i < method.method.proto.parameters.values.length; i++) {
       if (i != 0) {
-        writer.append(',');
+        append(",");
       }
-      writer.append(method.method.proto.parameters.values[i].toSourceString());
+      append(method.method.proto.parameters.values[i].toSourceString());
     }
-    writer.append(')');
-    writer.append(StringUtils.LINE_SEPARATOR);
+    append(")");
+    append(StringUtils.LINE_SEPARATOR);
   }
 
   void printUnusedField(DexEncodedField field) {
     printClazzPrefixIfNecessary();
-    writer.append(INDENT);
+    append(INDENT);
     String accessFlags = field.accessFlags.toString();
     if (!accessFlags.isEmpty()) {
-      writer.append(accessFlags).append(' ');
+      append(accessFlags);
+      append(" ");
     }
-    writer.append(field.field.type.toSourceString()).append(" ");
-    writer.append(field.field.name.toSourceString());
-    writer.append(StringUtils.LINE_SEPARATOR);
+    append(field.field.type.toSourceString());
+    append(" ");
+    append(field.field.name.toSourceString());
+    append(StringUtils.LINE_SEPARATOR);
   }
 
   // Empty implementation to silently ignore printing dead code.
   private static class NoOpUsagePrinter extends UsagePrinter {
 
-    @Override
-    byte[] toByteArray() {
-      return null;
+    public NoOpUsagePrinter() {
+      super(null);
     }
 
     @Override
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index f9636bd..56c10d5 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -2003,7 +2003,6 @@
         Executors.newSingleThreadExecutor(),
         application,
         null,
-        null,
         GraphLense.getIdentityLense(),
         NamingLens.getIdentityLens(),
         options,
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index e67475a..8b40ea9 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -145,7 +145,6 @@
             options,
             null,
             null,
-            null,
             GraphLense.getIdentityLense(),
             NamingLens.getIdentityLens(),
             null);
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index cf84955..fdc4296 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -864,7 +864,6 @@
             options,
             null,
             null,
-            null,
             GraphLense.getIdentityLense(),
             NamingLens.getIdentityLens(),
             null);
diff --git a/src/test/java/com/android/tools/r8/utils/Smali.java b/src/test/java/com/android/tools/r8/utils/Smali.java
index bef0f2a..3d1ec2b 100644
--- a/src/test/java/com/android/tools/r8/utils/Smali.java
+++ b/src/test/java/com/android/tools/r8/utils/Smali.java
@@ -118,7 +118,6 @@
               options,
               null,
               null,
-              null,
               GraphLense.getIdentityLense(),
               NamingLens.getIdentityLens(),
               null);