Add dex checksums to R8 build metadata
Change-Id: If408a65c9aa0ed604e31b4485be1d3820b64b501
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 25a5031..9554f4e 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -647,6 +647,7 @@
((DexIndexedConsumer) consumer)
.accept(virtualFile.getId(), data, virtualFile.getClassDescriptors(), options.reporter);
}
+ virtualFile.calculateChecksumForBuildMetadata(data, options);
timing.end();
// Release use of the backing buffer now that accept has returned.
data.invalidate();
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 b58266c..2d96710 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -8,6 +8,7 @@
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.FeatureSplit;
import com.android.tools.r8.debuginfo.DebugRepresentation;
import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
@@ -47,6 +48,8 @@
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.ArrayList;
@@ -81,6 +84,7 @@
private final DexString primaryClassSynthesizingContextDescriptor;
private DebugRepresentation debugRepresentation;
private boolean startup = false;
+ private HashCode checksumForBuildMetadata;
VirtualFile(int id, AppView<?> appView) {
this(id, appView, null, null, StartupProfile.empty());
@@ -128,6 +132,18 @@
}
}
+ public HashCode getChecksumForBuildMetadata() {
+ return checksumForBuildMetadata;
+ }
+
+ public void calculateChecksumForBuildMetadata(ByteDataView data, InternalOptions options) {
+ if (options.r8BuildMetadataConsumer != null) {
+ checksumForBuildMetadata =
+ Hashing.sha256()
+ .hashBytes(data.getBuffer(), data.getOffset(), data.getOffset() + data.getLength());
+ }
+ }
+
public int getId() {
return id;
}
diff --git a/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java b/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
index 0057ddc..c3f13b0 100644
--- a/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
+++ b/src/main/java/com/android/tools/r8/metadata/R8BuildMetadata.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.metadata.impl.R8StartupOptimizationOptionsImpl;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
+import java.util.List;
@KeepForApi
public interface R8BuildMetadata {
@@ -53,6 +54,11 @@
R8BaselineProfileRewritingOptions getBaselineProfileRewritingOptions();
/**
+ * @return null if not compiling to dex.
+ */
+ List<String> getDexChecksums();
+
+ /**
* @return null if resource optimization is disabled.
*/
R8ResourceOptimizationOptions getResourceOptimizationOptions();
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java b/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
index ef67f53..69e906c 100644
--- a/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
+++ b/src/main/java/com/android/tools/r8/metadata/impl/BuildMetadataFactory.java
@@ -28,6 +28,7 @@
return R8BuildMetadataImpl.builder()
.setOptions(new R8OptionsImpl(options))
.setBaselineProfileRewritingOptions(R8BaselineProfileRewritingOptionsImpl.create(options))
+ .applyIf(options.isGeneratingDex(), builder -> builder.setDexChecksums(virtualFiles))
.setResourceOptimizationOptions(R8ResourceOptimizationOptionsImpl.create(options))
.setStartupOptimizationOptions(
R8StartupOptimizationOptionsImpl.create(options, virtualFiles))
diff --git a/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java b/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
index 8edb511..441146d 100644
--- a/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
+++ b/src/main/java/com/android/tools/r8/metadata/impl/R8BuildMetadataImpl.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.metadata.impl;
+import com.android.tools.r8.dex.VirtualFile;
import com.android.tools.r8.keepanno.annotations.AnnotationPattern;
import com.android.tools.r8.keepanno.annotations.FieldAccessFlags;
import com.android.tools.r8.keepanno.annotations.KeepConstraint;
@@ -13,9 +14,12 @@
import com.android.tools.r8.metadata.R8Options;
import com.android.tools.r8.metadata.R8ResourceOptimizationOptions;
import com.android.tools.r8.metadata.R8StartupOptimizationOptions;
+import com.android.tools.r8.utils.ListUtils;
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.function.Consumer;
@UsedByReflection(
description = "Keep and preserve @SerializedName for correct (de)serialization",
@@ -35,6 +39,10 @@
private final R8BaselineProfileRewritingOptions baselineProfileRewritingOptions;
@Expose
+ @SerializedName("dexChecksums")
+ private final List<String> dexChecksums;
+
+ @Expose
@SerializedName("resourceOptimizationOptions")
private final R8ResourceOptimizationOptions resourceOptimizationOptions;
@@ -49,11 +57,13 @@
public R8BuildMetadataImpl(
R8Options options,
R8BaselineProfileRewritingOptions baselineProfileRewritingOptions,
+ List<String> dexChecksums,
R8ResourceOptimizationOptions resourceOptimizationOptions,
R8StartupOptimizationOptions startupOptimizationOptions,
String version) {
this.options = options;
this.baselineProfileRewritingOptions = baselineProfileRewritingOptions;
+ this.dexChecksums = dexChecksums;
this.resourceOptimizationOptions = resourceOptimizationOptions;
this.startupOptimizationOptions = startupOptimizationOptions;
this.version = version;
@@ -74,6 +84,11 @@
}
@Override
+ public List<String> getDexChecksums() {
+ return dexChecksums;
+ }
+
+ @Override
public R8ResourceOptimizationOptions getResourceOptimizationOptions() {
return resourceOptimizationOptions;
}
@@ -97,10 +112,18 @@
private R8Options options;
private R8BaselineProfileRewritingOptions baselineProfileRewritingOptions;
+ private List<String> dexChecksums;
private R8ResourceOptimizationOptions resourceOptimizationOptions;
private R8StartupOptimizationOptions startupOptimizationOptions;
private String version;
+ public Builder applyIf(boolean condition, Consumer<Builder> thenConsumer) {
+ if (condition) {
+ thenConsumer.accept(this);
+ }
+ return this;
+ }
+
public Builder setOptions(R8Options options) {
this.options = options;
return this;
@@ -112,6 +135,12 @@
return this;
}
+ public Builder setDexChecksums(List<VirtualFile> virtualFiles) {
+ this.dexChecksums =
+ ListUtils.map(virtualFiles, vf -> vf.getChecksumForBuildMetadata().toString());
+ return this;
+ }
+
public Builder setResourceOptimizationOptions(
R8ResourceOptimizationOptions resourceOptimizationOptions) {
this.resourceOptimizationOptions = resourceOptimizationOptions;
@@ -133,6 +162,7 @@
return new R8BuildMetadataImpl(
options,
baselineProfileRewritingOptions,
+ dexChecksums,
resourceOptimizationOptions,
startupOptimizationOptions,
version);