Support for package based startup classes distribution
Change-Id: I776a4f9a35f37bc7b1f1cdb0d8d17edaaf25f134
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index 65c0f2e..75c4f9d 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -1259,7 +1259,7 @@
}
// Start a new iteration over all files, starting at the current one.
- void restart() {
+ public void restart() {
activeFiles = Iterators.limit(allFilesCyclic, filesForDistribution.size());
}
@@ -1299,7 +1299,7 @@
* <p>The populator cycles through the files until all classes have been successfully placed and
* adds new files to the passed in map if it can't fit in the existing files.
*/
- private static class PackageSplitPopulator {
+ public static class PackageSplitPopulator {
static class PackageSplitClassPartioning {
@@ -1442,8 +1442,7 @@
public void run() {
addStartupClasses();
- List<DexProgramClass> nonPackageClasses = addNonStartupClasses();
- addNonPackageClasses(cycler, nonPackageClasses);
+ distributeClasses(classPartioning.getNonStartupClasses());
}
private void addStartupClasses() {
@@ -1469,7 +1468,7 @@
// If the above failed, then apply the selected multi startup dex distribution strategy.
MultiStartupDexDistributor distributor = MultiStartupDexDistributor.get(options);
- distributor.distribute(classPartioning.getStartupClasses(), cycler, virtualFile);
+ distributor.distribute(classPartioning.getStartupClasses(), this, virtualFile, cycler);
options.reporter.warning(
createStartupClassesOverflowDiagnostic(cycler.filesForDistribution.size()));
@@ -1493,14 +1492,18 @@
}
}
+ public void distributeClasses(List<DexProgramClass> classes) {
+ List<DexProgramClass> nonPackageClasses = addPackageClasses(classes);
+ addNonPackageClasses(cycler, nonPackageClasses);
+ }
+
@SuppressWarnings("ReferenceEquality")
- private List<DexProgramClass> addNonStartupClasses() {
+ private List<DexProgramClass> addPackageClasses(List<DexProgramClass> classes) {
int prefixLength = MINIMUM_PREFIX_LENGTH;
int transactionStartIndex = 0;
String currentPrefix = null;
Object2IntMap<String> packageAssignments = new Object2IntOpenHashMap<>();
VirtualFile current = cycler.ensureFile().next();
- List<DexProgramClass> classes = classPartioning.getNonStartupClasses();
List<DexProgramClass> nonPackageClasses = new ArrayList<>();
for (int classIndex = 0; classIndex < classes.size(); classIndex++) {
DexProgramClass clazz = classes.get(classIndex);
diff --git a/src/main/java/com/android/tools/r8/profile/startup/distribution/MultiStartupDexDistributor.java b/src/main/java/com/android/tools/r8/profile/startup/distribution/MultiStartupDexDistributor.java
index 471ea08..6a3132c 100644
--- a/src/main/java/com/android/tools/r8/profile/startup/distribution/MultiStartupDexDistributor.java
+++ b/src/main/java/com/android/tools/r8/profile/startup/distribution/MultiStartupDexDistributor.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.profile.startup.distribution;
import com.android.tools.r8.dex.VirtualFile;
+import com.android.tools.r8.dex.VirtualFile.PackageSplitPopulator;
import com.android.tools.r8.dex.VirtualFile.VirtualFileCycler;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.DexProgramClass;
@@ -14,7 +15,10 @@
public abstract class MultiStartupDexDistributor {
public abstract void distribute(
- List<DexProgramClass> classes, VirtualFileCycler cycler, VirtualFile virtualFile);
+ List<DexProgramClass> classes,
+ PackageSplitPopulator packageSplitPopulator,
+ VirtualFile virtualFile,
+ VirtualFileCycler virtualFileCycler);
boolean hasSpaceForTransaction(VirtualFile virtualFile) {
return !virtualFile.isFull();
@@ -37,7 +41,7 @@
case "classByNumberOfStartupMethodsMinusNumberOfNonStartupMethods":
throw new Unimplemented();
case "packageByName":
- throw new Unimplemented();
+ return new PackageByNameMultiStartupDexDistributor();
case "packageByNumberOfStartupMethods":
throw new Unimplemented();
default:
@@ -50,7 +54,10 @@
@Override
public void distribute(
- List<DexProgramClass> classes, VirtualFileCycler cycler, VirtualFile virtualFile) {
+ List<DexProgramClass> classes,
+ PackageSplitPopulator packageSplitPopulator,
+ VirtualFile virtualFile,
+ VirtualFileCycler virtualFileCycler) {
// Add the (already sorted) startup classes one by one.
for (DexProgramClass startupClass : classes) {
virtualFile.addClass(startupClass);
@@ -58,7 +65,7 @@
virtualFile.commitTransaction();
} else {
virtualFile.abortTransaction();
- virtualFile = cycler.addFile();
+ virtualFile = virtualFileCycler.addFile();
virtualFile.addClass(startupClass);
assert hasSpaceForTransaction(virtualFile);
virtualFile.commitTransaction();
@@ -66,4 +73,17 @@
}
}
}
+
+ private static class PackageByNameMultiStartupDexDistributor extends MultiStartupDexDistributor {
+
+ @Override
+ public void distribute(
+ List<DexProgramClass> classes,
+ PackageSplitPopulator packageSplitPopulator,
+ VirtualFile virtualFile,
+ VirtualFileCycler virtualFileCycler) {
+ virtualFileCycler.restart();
+ packageSplitPopulator.distributeClasses(classes);
+ }
+ }
}