Restrict classpath amendment to DirectMappedDexApplication
Fixes: 178675555
Change-Id: I751f980375fcabb75eb85e84480687571760085d
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 37b8d28..d5ea16e 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java
@@ -98,8 +98,6 @@
abstract List<DexProgramClass> programClasses();
- abstract List<DexClasspathClass> classpathClasses();
-
public List<DexProgramClass> classes() {
ReorderBox<DexProgramClass> box = new ReorderBox<>(programClasses());
assert box.reorderClasses();
@@ -134,7 +132,6 @@
public abstract static class Builder<T extends Builder<T>> {
private final List<DexProgramClass> programClasses = new ArrayList<>();
- private final List<DexClasspathClass> classpathClasses = new ArrayList<>();
final List<DataResourceProvider> dataResourceProviders = new ArrayList<>();
@@ -157,7 +154,6 @@
public Builder(DexApplication application) {
programClasses.addAll(application.programClasses());
- classpathClasses.addAll(application.classpathClasses());
dataResourceProviders.addAll(application.dataResourceProviders);
proguardMap = application.getProguardMap();
timing = application.timing;
@@ -167,6 +163,14 @@
synthesizedClasses = new ArrayList<>();
}
+ public boolean isDirect() {
+ return false;
+ }
+
+ public DirectMappedDexApplication.Builder asDirect() {
+ return null;
+ }
+
public synchronized T setProguardMap(ClassNameMapper proguardMap) {
assert this.proguardMap == null;
this.proguardMap = proguardMap;
@@ -180,14 +184,6 @@
return self();
}
- public synchronized T replaceClasspathClasses(
- Collection<DexClasspathClass> newClasspathClasses) {
- assert newClasspathClasses != null;
- classpathClasses.clear();
- classpathClasses.addAll(newClasspathClasses);
- return self();
- }
-
public synchronized T addDataResourceProvider(DataResourceProvider provider) {
dataResourceProviders.add(provider);
return self();
@@ -208,16 +204,6 @@
return self();
}
- public synchronized T addClasspathClass(DexClasspathClass clazz) {
- classpathClasses.add(clazz);
- return self();
- }
-
- public synchronized T addClasspathClasses(Collection<DexClasspathClass> classes) {
- classpathClasses.addAll(classes);
- return self();
- }
-
public synchronized T addSynthesizedClass(DexProgramClass synthesizedClass) {
assert synthesizedClass.isProgramClass() : "All synthesized classes must be program classes";
addProgramClass(synthesizedClass);
@@ -229,10 +215,6 @@
return programClasses;
}
- public List<DexClasspathClass> getClasspathClasses() {
- return classpathClasses;
- }
-
public Collection<DexProgramClass> getSynthesizedClasses() {
return synthesizedClasses;
}
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 4f38fb2..86377b3 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
@@ -58,6 +59,10 @@
return allClasses.values();
}
+ public List<DexClasspathClass> classpathClasses() {
+ return classpathClasses;
+ }
+
@Override
List<DexProgramClass> programClasses() {
return programClasses;
@@ -68,11 +73,6 @@
}
@Override
- public List<DexClasspathClass> classpathClasses() {
- return classpathClasses;
- }
-
- @Override
public DexClass definitionFor(DexType type) {
assert type.isClassType() : "Cannot lookup definition for type: " + type;
return allClasses.get(type);
@@ -181,12 +181,16 @@
public static class Builder extends DexApplication.Builder<Builder> {
+ private ImmutableList<DexClasspathClass> classpathClasses;
private ImmutableList<DexLibraryClass> libraryClasses;
+ private final List<DexClasspathClass> pendingClasspathClasses = new ArrayList<>();
+
Builder(LazyLoadedDexApplication application) {
super(application);
// As a side-effect, this will force-load all classes.
AllClasses allClasses = application.loadAllClasses();
+ classpathClasses = allClasses.getClasspathClasses();
libraryClasses = allClasses.getLibraryClasses();
replaceProgramClasses(allClasses.getProgramClasses());
replaceClasspathClasses(allClasses.getClasspathClasses());
@@ -194,14 +198,58 @@
private Builder(DirectMappedDexApplication application) {
super(application);
+ classpathClasses = application.classpathClasses;
libraryClasses = application.libraryClasses;
}
@Override
+ public boolean isDirect() {
+ return true;
+ }
+
+ @Override
+ public Builder asDirect() {
+ return this;
+ }
+
+ @Override
Builder self() {
return this;
}
+ public Builder addClasspathClass(DexClasspathClass clazz) {
+ pendingClasspathClasses.add(clazz);
+ return self();
+ }
+
+ public Builder addClasspathClasses(Collection<DexClasspathClass> classes) {
+ pendingClasspathClasses.addAll(classes);
+ return self();
+ }
+
+ private void commitPendingClasspathClasses() {
+ if (!pendingClasspathClasses.isEmpty()) {
+ classpathClasses =
+ ImmutableList.<DexClasspathClass>builder()
+ .addAll(classpathClasses)
+ .addAll(pendingClasspathClasses)
+ .build();
+ pendingClasspathClasses.clear();
+ }
+ }
+
+ public List<DexClasspathClass> getClasspathClasses() {
+ commitPendingClasspathClasses();
+ return classpathClasses;
+ }
+
+ public Builder replaceClasspathClasses(Collection<DexClasspathClass> newClasspathClasses) {
+ assert newClasspathClasses != null;
+ classpathClasses = ImmutableList.copyOf(newClasspathClasses);
+ pendingClasspathClasses.clear();
+ return self();
+ }
+
public Builder replaceLibraryClasses(Collection<DexLibraryClass> libraryClasses) {
this.libraryClasses = ImmutableList.copyOf(libraryClasses);
return self();
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 ba240f6..7005e06 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -54,12 +54,6 @@
}
@Override
- List<DexClasspathClass> classpathClasses() {
- classpathClasses.forceLoad(t -> true);
- return classpathClasses.getAllClasses();
- }
-
- @Override
public DexClass definitionFor(DexType type) {
assert type.isClassType() : "Cannot lookup definition for type: " + type;
DexClass clazz = null;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index f9d1391..c198197 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -401,9 +401,9 @@
if (definition.isProgramDefinition()) {
committedProgramTypesBuilder.add(definition.getHolder().getType());
appBuilder.addProgramClass(definition.asProgramDefinition().getHolder());
- } else {
+ } else if (appBuilder.isDirect()) {
assert definition.isClasspathDefinition();
- appBuilder.addClasspathClass(definition.asClasspathDefinition().getHolder());
+ appBuilder.asDirect().addClasspathClass(definition.asClasspathDefinition().getHolder());
}
builder.addItem(definition);
}