Commit pending dex items before/after reading

Bug: b/422947619
Change-Id: I700d26d978f2b3c4584a033d4d082f57a6048600
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 6d4a086..73aeeee 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -67,7 +67,7 @@
 public class ApplicationReader {
 
   private final InternalOptions options;
-  private final DexItemFactory itemFactory;
+  private final DexItemFactory factory;
   private final Timing timing;
   private final AndroidApp inputApp;
 
@@ -79,7 +79,7 @@
 
   public ApplicationReader(AndroidApp inputApp, InternalOptions options, Timing timing) {
     this.options = options;
-    itemFactory = options.itemFactory;
+    factory = options.itemFactory;
     this.timing = timing;
     this.inputApp = inputApp;
   }
@@ -127,7 +127,7 @@
 
     timing.begin("DexApplication.read");
     LazyLoadedDexApplication.Builder builder = DexApplication.builder(options, timing);
-    TaskCollection<?> tasks = new TaskCollection<>(options, executorService);
+    TaskCollection<?> tasks = createReaderTaskCollection(executorService);
     try {
       // Still preload some of the classes, primarily for two reasons:
       // (a) class lazy loading is not supported for DEX files
@@ -140,7 +140,7 @@
       ClassReader classReader = new ClassReader(tasks);
       classReader.initializeLazyClassCollection(builder);
       classReader.readSources();
-      timing.time("Await read", () -> tasks.await());
+      awaitReaderTaskCollection(tasks);
       flags = classReader.getDexApplicationReadFlags();
       return builder
           .addDataResourceProviders(inputApp.getProgramResourceProviders())
@@ -178,7 +178,7 @@
     timing.begin("DexApplication.readDirect");
     DirectMappedDexApplication.Builder builder =
         DirectMappedDexApplication.directBuilder(options, timing);
-    TaskCollection<?> tasks = new TaskCollection<>(options, executorService);
+    TaskCollection<?> tasks = createReaderTaskCollection(executorService);
     try {
       readProguardMap(inputApp.getProguardMapInputData(), builder, tasks);
       ClassReader classReader = new ClassReader(tasks);
@@ -187,7 +187,7 @@
           allClassesBuilder::setClasspathClasses, allClassesBuilder::setLibraryClasses);
       allClassesBuilder.forceLoadNonProgramClassCollections(options, tasks, timing);
       classReader.readSources();
-      timing.time("Await read", () -> tasks.await());
+      awaitReaderTaskCollection(tasks);
       allClassesBuilder.setProgramClasses(
           ProgramClassCollection.resolveConflicts(classReader.programClasses, options));
       AllClasses allClasses = allClassesBuilder.build(options, timing);
@@ -209,6 +209,18 @@
     }
   }
 
+  private TaskCollection<?> createReaderTaskCollection(ExecutorService executorService) {
+    // Commit all statically known types before starting to read (e.g., java.lang.Object).
+    factory.commitPendingItems();
+    return new TaskCollection<>(options, executorService);
+  }
+
+  private void awaitReaderTaskCollection(TaskCollection<?> tasks) throws ExecutionException {
+    timing.time("Await read", () -> tasks.await());
+    // Commit all references corresponding to program definitions.
+    factory.commitPendingItems();
+  }
+
   public final void dump(DumpInputFlags dumpInputFlags) {
     assert verifyMainDexOptionsCompatible(inputApp, options);
     dumpApplication(dumpInputFlags);
@@ -250,7 +262,7 @@
         if (emitDeprecatedDiagnostics) {
           options.reporter.error(new UnsupportedMainDexListUsageDiagnostic(resource.getOrigin()));
         }
-        addToMainDexClasses(app, builder, MainDexListParser.parseList(resource, itemFactory));
+        addToMainDexClasses(app, builder, MainDexListParser.parseList(resource, factory));
       }
       if (!inputApp.getMainDexClasses().isEmpty()) {
         if (emitDeprecatedDiagnostics) {
@@ -260,7 +272,7 @@
             app,
             builder,
             inputApp.getMainDexClasses().stream()
-                .map(clazz -> itemFactory.createType(DescriptorUtils.javaTypeToDescriptor(clazz)))
+                .map(clazz -> factory.createType(DescriptorUtils.javaTypeToDescriptor(clazz)))
                 .collect(Collectors.toList()));
       }
     }
@@ -435,7 +447,7 @@
         return true;
       }
       DexAnnotation retentionAnnotation =
-          clazz.annotations().getFirstMatching(itemFactory.retentionType);
+          clazz.annotations().getFirstMatching(factory.retentionType);
       // Default is CLASS retention, read if retained.
       if (retentionAnnotation == null) {
         return DexAnnotation.retainCompileTimeAnnotation(clazz.getType(), application.options);