DexFileMerger: don't add marker and keep all markers from input files.
Bug: 77883315
Change-Id: Id12ff2c01fff201ab382d8dfdae46121245dbd7a
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 4a26889..39bdd96 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -135,6 +136,9 @@
if (options.hasMarker()) {
return options.getMarker();
}
+ if (options.testing.dontCreateMarkerInD8) {
+ return null;
+ }
Marker marker = new Marker(Tool.D8)
.setVersion(Version.LABEL)
.setMinApi(options.minApiLevel);
@@ -163,7 +167,14 @@
options.methodsFilter.forEach((m) -> System.out.println(" - " + m));
}
Marker marker = getMarker(options);
- new ApplicationWriter(app, options, marker, null, NamingLens.getIdentityLens(), null, null)
+ new ApplicationWriter(
+ app,
+ options,
+ marker == null ? null : Collections.singletonList(marker),
+ null,
+ NamingLens.getIdentityLens(),
+ null,
+ null)
.write(executor);
options.printWarnings();
} catch (ExecutionException e) {
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index 2e121c3..627d5ef 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
+import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
@@ -16,6 +17,7 @@
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -86,9 +88,10 @@
AppInfo appInfo = new AppInfo(app);
app = D8.optimize(app, appInfo, options, timing, executor);
+ List<Marker> markers = app.dexItemFactory.extractMarkers();
+
assert !options.hasMethodsFilter();
- new ApplicationWriter(
- app, options, D8.getMarker(options), null, NamingLens.getIdentityLens(), null, null)
+ new ApplicationWriter(app, options, markers, null, NamingLens.getIdentityLens(), null, null)
.write(executor);
options.printWarnings();
} catch (ExecutionException e) {
@@ -101,4 +104,11 @@
executor.shutdown();
}
}
+
+ public static void runForTesting(D8Command command, boolean dontCreateMarkerInD8)
+ throws IOException, CompilationException {
+ InternalOptions options = command.getInternalOptions();
+ options.testing.dontCreateMarkerInD8 = dontCreateMarkerInD8;
+ D8.runForTesting(command.getInputApp(), options);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index 8573e0f..8c29ca8 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.DexIndexedConsumer.DirectoryConsumer;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
+import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexApplication.Builder;
@@ -22,6 +23,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -74,10 +76,11 @@
DexIndexedConsumer consumer = new DirectoryConsumer(outputDir);
try {
+ Marker marker = D8.getMarker(options);
new ApplicationWriter(
featureApp,
options,
- D8.getMarker(options),
+ marker == null ? null : Collections.singletonList(marker),
null,
NamingLens.getIdentityLens(),
null,
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 4f12ce1..6821c4e 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -70,6 +70,7 @@
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -195,7 +196,7 @@
new ApplicationWriter(
application,
options,
- marker,
+ marker == null ? null : Collections.singletonList(marker),
deadCode,
namingLens,
proguardSeedsData,
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 30664a2..d5a7013 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -46,7 +46,7 @@
public final NamingLens namingLens;
public final String proguardSeedsData;
public final InternalOptions options;
- public DexString markerString;
+ public List<DexString> markerStrings;
public DexIndexedConsumer programConsumer;
public final ProguardMapSupplier proguardMapSupplier;
@@ -110,7 +110,7 @@
public ApplicationWriter(
DexApplication application,
InternalOptions options,
- Marker marker,
+ List<Marker> markers,
String deadCode,
NamingLens namingLens,
String proguardSeedsData,
@@ -118,7 +118,7 @@
this(
application,
options,
- marker,
+ markers,
deadCode,
namingLens,
proguardSeedsData,
@@ -129,7 +129,7 @@
public ApplicationWriter(
DexApplication application,
InternalOptions options,
- Marker marker,
+ List<Marker> markers,
String deadCode,
NamingLens namingLens,
String proguardSeedsData,
@@ -139,9 +139,12 @@
this.application = application;
assert options != null;
this.options = options;
- this.markerString = (marker == null)
- ? null
- : application.dexItemFactory.createString(marker.toString());
+ if (markers != null && !markers.isEmpty()) {
+ this.markerStrings = new ArrayList<>();
+ for (Marker marker : markers) {
+ this.markerStrings.add(application.dexItemFactory.createString(marker.toString()));
+ }
+ }
this.deadCode = deadCode;
this.namingLens = namingLens;
this.proguardSeedsData = proguardSeedsData;
@@ -174,7 +177,9 @@
insertAttributeAnnotations();
application.dexItemFactory.sort(namingLens);
- assert this.markerString == null || application.dexItemFactory.extractMarker() != null;
+ assert this.markerStrings == null
+ || this.markerStrings.isEmpty()
+ || application.dexItemFactory.extractMarker() != null;
SortAnnotations sortAnnotations = new SortAnnotations();
application.classes().forEach((clazz) -> clazz.addDependencies(sortAnnotations));
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 5369069..ae6acd9 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -275,8 +275,10 @@
mainDexFile = new VirtualFile(0, writer.namingLens);
assert virtualFiles.isEmpty();
virtualFiles.add(mainDexFile);
- if (writer.markerString != null) {
- mainDexFile.transaction.addString(writer.markerString);
+ if (writer.markerStrings != null && !writer.markerStrings.isEmpty()) {
+ for (DexString markerString : writer.markerStrings) {
+ mainDexFile.transaction.addString(markerString);
+ }
mainDexFile.commitTransaction();
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 5fe9134..364c0ee 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -483,7 +483,7 @@
}
// Debugging support to extract marking string.
- synchronized public Marker extractMarker() {
+ public synchronized Marker extractMarker() {
// This is slow but it is not needed for any production code yet.
for (DexString dexString : strings.keySet()) {
Marker result = Marker.parse(dexString.toString());
@@ -494,6 +494,20 @@
return null;
}
+ // Debugging support to extract marking string.
+ // Find all markers.
+ public synchronized List<Marker> extractMarkers() {
+ // This is slow but it is not needed for any production code yet.
+ List<Marker> markers = new ArrayList<>();
+ for (DexString dexString : strings.keySet()) {
+ Marker marker = Marker.parse(dexString.toString());
+ if (marker != null) {
+ markers.add(marker);
+ }
+ }
+ return markers;
+ }
+
synchronized public DexType createType(DexString descriptor) {
assert !sorted;
assert descriptor != null;
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 04c5f72..a8ff665 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -411,6 +411,7 @@
public boolean invertConditionals = false;
public boolean placeExceptionalBlocksLast = false;
+ public boolean dontCreateMarkerInD8 = false;
}
public boolean canUseInvokePolymorphicOnVarHandle() {
diff --git a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java b/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
index e99e696..60edc6d 100644
--- a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
+++ b/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
@@ -8,12 +8,15 @@
import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
+import com.android.tools.r8.DexFileMergerHelper;
+import com.android.tools.r8.ExtractMarker;
import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.ResourceException;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.maindexlist.MainDexListTests;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
@@ -35,16 +38,57 @@
@Rule public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
- @Test
- public void mergeTwoFiles() throws CompilationFailedException, IOException {
+ private Path createMergerInputWithTwoClasses(OutputMode outputMode, boolean dontCreateMarkerInD8)
+ throws CompilationFailedException, CompilationException, IOException {
// Compile Class1 and Class2
Path mergerInputZip = temp.newFolder().toPath().resolve("merger-input.zip");
- D8.run(
+ D8Command command =
D8Command.builder()
- .setOutput(mergerInputZip, OutputMode.DexFilePerClassFile)
+ .setOutput(mergerInputZip, outputMode)
.addProgramFiles(Paths.get(CLASS1_CLASS))
.addProgramFiles(Paths.get(CLASS2_CLASS))
- .build());
+ .build();
+
+ DexFileMergerHelper.runForTesting(command, dontCreateMarkerInD8);
+
+ return mergerInputZip;
+ }
+
+ private void testMarkerPreservedOrNotAdded(boolean testNotAdding)
+ throws CompilationFailedException, CompilationException, IOException, ResourceException,
+ ExecutionException {
+ Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexIndexed, testNotAdding);
+
+ Marker inputMarker = ExtractMarker.extractMarkerFromDexFile(mergerInputZip);
+ assertEquals(inputMarker == null, testNotAdding);
+
+ Path mergerOutputZip = temp.getRoot().toPath().resolve("merger-out.zip");
+ DexFileMerger.main(
+ new String[] {
+ "--input", mergerInputZip.toString(), "--output", mergerOutputZip.toString()
+ });
+
+ Marker outputMarker = ExtractMarker.extractMarkerFromDexFile(mergerOutputZip);
+ assertEquals(outputMarker == null, testNotAdding);
+ }
+
+ @Test
+ public void testMarkerPreserved()
+ throws CompilationFailedException, CompilationException, IOException, ResourceException,
+ ExecutionException {
+ testMarkerPreservedOrNotAdded(false);
+ }
+
+ @Test
+ public void testMarkerNotAdded()
+ throws CompilationFailedException, CompilationException, IOException, ResourceException,
+ ExecutionException {
+ testMarkerPreservedOrNotAdded(true);
+ }
+
+ @Test
+ public void mergeTwoFiles() throws CompilationFailedException, CompilationException, IOException {
+ Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexFilePerClassFile, false);
Path mergerOutputZip = temp.getRoot().toPath().resolve("merger-out.zip");
DexFileMerger.main(