Reland "Load all library and program classes when running R8"
This reverts commit 687e8f3fe8bfd4e38ac3663c26059b164ccdb6bd.
After landing e0e0586bf37899856e1802585f59cdaa551af9b7 r8lib should
work again.
Bug: 120884788
Change-Id: Ic7dbc7a7066765d9a2ddcb19982b991c6c529e53
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 e4f1c8c..012c4a4 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -7,6 +7,7 @@
package com.android.tools.r8.graph;
import com.android.tools.r8.ProgramResourceProvider;
+import com.android.tools.r8.graph.LazyLoadedDexApplication.AllClasses;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.ProgramClassCollection;
import com.android.tools.r8.utils.Timing;
@@ -21,9 +22,11 @@
public class DirectMappedDexApplication extends DexApplication {
+ private final AllClasses allClasses;
private final ImmutableMap<DexType, DexLibraryClass> libraryClasses;
private DirectMappedDexApplication(ClassNameMapper proguardMap,
+ AllClasses allClasses,
ProgramClassCollection programClasses,
ImmutableList<ProgramResourceProvider> programResourceProviders,
ImmutableMap<DexType, DexLibraryClass> libraryClasses,
@@ -32,6 +35,7 @@
Timing timing) {
super(proguardMap, programClasses, programResourceProviders, mainDexList, deadCode,
dexItemFactory, highestSortingString, timing);
+ this.allClasses = allClasses;
this.libraryClasses = libraryClasses;
}
@@ -92,17 +96,21 @@
public static class Builder extends DexApplication.Builder<Builder> {
+ private final AllClasses allClasses;
private final List<DexLibraryClass> libraryClasses = new ArrayList<>();
Builder(LazyLoadedDexApplication application) {
super(application);
// As a side-effect, this will force-load all classes.
- Map<DexType, DexClass> allClasses = application.getFullClassMap();
+ this.allClasses = application.loadAllClasses();
+ Map<DexType, DexClass> allClasses = this.allClasses.getClasses();
+ // TODO(120884788): This filter will only add library classes which are not program classes.
Iterables.filter(allClasses.values(), DexLibraryClass.class).forEach(libraryClasses::add);
}
private Builder(DirectMappedDexApplication application) {
super(application);
+ this.allClasses = application.allClasses;
this.libraryClasses.addAll(application.libraryClasses.values());
}
@@ -116,6 +124,7 @@
// Rebuild the map. This will fail if keys are not unique.
return new DirectMappedDexApplication(
proguardMap,
+ allClasses,
ProgramClassCollection.create(
programClasses, ProgramClassCollection::resolveClassConflictImpl),
ImmutableList.copyOf(programResourceProviders),
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 b648e41..6dea825 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -55,31 +55,67 @@
return clazz;
}
- private Map<DexType, DexClass> forceLoadAllClasses() {
- Map<DexType, DexClass> loaded = new IdentityHashMap<>();
+ static class AllClasses {
+ private Map<DexType, DexClass> libraryClasses;
+ private Map<DexType, DexClass> classpathClasses;
+ private Map<DexType, DexClass> programClasses;
+ private Map<DexType, DexClass> classes;
- // Program classes are supposed to be loaded, but force-loading them is no-op.
- programClasses.forceLoad(type -> true);
- programClasses.getAllClasses().forEach(clazz -> loaded.put(clazz.type, clazz));
+ AllClasses(
+ LibraryClassCollection libraryClasses,
+ ClasspathClassCollection classpathClasses,
+ ProgramClassCollection programClasses) {
+ load(libraryClasses, classpathClasses, programClasses);
- if (classpathClasses != null) {
- classpathClasses.forceLoad(type -> !loaded.containsKey(type));
- classpathClasses.getAllClasses().forEach(clazz -> loaded.putIfAbsent(clazz.type, clazz));
+ // Collect loaded classes in the precedence order program classes, class path classes and
+ // library classes.
+ // TODO(b/120884788): Change this.
+ classes = new IdentityHashMap<>();
+ classes.putAll(this.programClasses);
+ if (classpathClasses != null) {
+ classpathClasses.getAllClasses().forEach(clazz -> classes.putIfAbsent(clazz.type, clazz));
+ }
+ if (libraryClasses != null) {
+ libraryClasses.getAllClasses().forEach(clazz -> classes.putIfAbsent(clazz.type, clazz));
+ }
}
- if (libraryClasses != null) {
- libraryClasses.forceLoad(type -> !loaded.containsKey(type));
- libraryClasses.getAllClasses().forEach(clazz -> loaded.putIfAbsent(clazz.type, clazz));
+ public Map<DexType, DexClass> getLibraryClasses() {
+ return libraryClasses;
}
- return loaded;
+ public Map<DexType, DexClass> getClasspathClasses() {
+ return classpathClasses;
+ }
+
+ public Map<DexType, DexClass> getClasses() {
+ return classes;
+ }
+
+ private void load(
+ LibraryClassCollection libraryClasses,
+ ClasspathClassCollection classpathClasses,
+ ProgramClassCollection programClasses) {
+ if (libraryClasses != null) {
+ libraryClasses.forceLoad(type -> true);
+ this.libraryClasses = libraryClasses.getAllClassesInMap();
+ }
+ if (classpathClasses != null) {
+ classpathClasses.forceLoad(type -> true);
+ this.classpathClasses = classpathClasses.getAllClassesInMap();
+ }
+ assert programClasses != null;
+ // Program classes are supposed to be loaded, but force-loading them is no-op.
+ programClasses.forceLoad(type -> true);
+ this.programClasses = programClasses.getAllClassesInMap();
+ }
}
/**
* Force load all classes and return type -> class map containing all the classes.
*/
- public Map<DexType, DexClass> getFullClassMap() {
- return forceLoadAllClasses();
+ public AllClasses loadAllClasses() {
+ return new AllClasses(libraryClasses, classpathClasses, programClasses);
}
public static class Builder extends DexApplication.Builder<Builder> {
diff --git a/src/main/java/com/android/tools/r8/utils/ClassMap.java b/src/main/java/com/android/tools/r8/utils/ClassMap.java
index 0ebfb9d..33c1bf3 100644
--- a/src/main/java/com/android/tools/r8/utils/ClassMap.java
+++ b/src/main/java/com/android/tools/r8/utils/ClassMap.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Iterator;
@@ -134,6 +135,18 @@
return loadedClasses;
}
+ public Map<DexType, DexClass> getAllClassesInMap() {
+ if (classProvider.get() != null) {
+ throw new Unreachable("Getting all classes from not fully loaded collection.");
+ }
+ ImmutableMap.Builder<DexType, DexClass> builder = ImmutableMap.builder();
+ // This is fully loaded, so the class map will no longer change.
+ for (Map.Entry<DexType, Supplier<T>> entry : classes.entrySet()) {
+ builder.put(entry.getKey(), entry.getValue().get());
+ }
+ return builder.build();
+ }
+
public Iterable<DexType> getAllTypes() {
return classes.keySet();
}