Fix collection of startup data items
Change-Id: I24bde513e3ef08debd7993b397ce3c9095045130
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index a939e1a..2c9ca25 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -1076,7 +1076,7 @@
private final Map<DexProgramClass, DexEncodedArray> classToStaticFieldValues =
new IdentityHashMap<>();
- private final AndroidApiLevel minApiLevel;
+ private final InternalOptions options;
private static <T> Object2IntMap<T> createObject2IntMap() {
Object2IntMap<T> result = new Object2IntLinkedOpenHashMap<>();
@@ -1091,7 +1091,7 @@
}
private MixedSectionOffsets(InternalOptions options) {
- this.minApiLevel = options.getMinApiLevel();
+ this.options = options;
}
private <T> boolean add(Object2IntMap<T> map, T item) {
@@ -1122,9 +1122,7 @@
@Override
public boolean add(DexAnnotationSet annotationSet) {
- // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
- // work around a DALVIK bug. See b/36951668.
- if (minApiLevel.isGreaterThanOrEqualTo(AndroidApiLevel.J_MR1) && annotationSet.isEmpty()) {
+ if (!options.canHaveDalvikEmptyAnnotationSetBug() && annotationSet.isEmpty()) {
return false;
}
return add(annotationSets, annotationSet);
@@ -1281,9 +1279,7 @@
}
public int getOffsetFor(DexAnnotationSet annotationSet) {
- // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
- // work around a DALVIK bug. See b/36951668.
- if ((minApiLevel.isGreaterThanOrEqualTo(AndroidApiLevel.J_MR1)) && annotationSet.isEmpty()) {
+ if (!options.canHaveDalvikEmptyAnnotationSetBug() && annotationSet.isEmpty()) {
return 0;
}
return lookup(annotationSet, annotationSets);
@@ -1332,9 +1328,7 @@
}
void setOffsetFor(DexAnnotationSet annotationSet, int offset) {
- // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
- // work around a DALVIK bug. See b/36951668.
- assert (minApiLevel.isLessThan(AndroidApiLevel.J_MR1)) || !annotationSet.isEmpty();
+ assert options.canHaveDalvikEmptyAnnotationSetBug() || !annotationSet.isEmpty();
setOffsetFor(annotationSet, offset, annotationSets);
}
diff --git a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
index 11a22f6..b5ccc6b 100644
--- a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
+++ b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
@@ -143,17 +143,35 @@
private class StartupIndexedItemCollection implements IndexedItemCollection {
+ private void addAnnotation(DexAnnotation annotation) {
+ annotationLayout.add(annotation);
+ }
+
+ private void addAnnotationSet(DexAnnotationSet annotationSet) {
+ if (appView.options().canHaveDalvikEmptyAnnotationSetBug() || !annotationSet.isEmpty()) {
+ annotationSetLayout.add(annotationSet);
+ }
+ }
+
+ private void addAnnotationSetRefList(ParameterAnnotationsList annotationSetRefList) {
+ if (!annotationSetRefList.isEmpty()) {
+ annotationSetRefListLayout.add(annotationSetRefList);
+ }
+ }
+
@Override
public boolean addClass(DexProgramClass clazz) {
- classDataLayout.add(clazz);
- typeListLayout.add(clazz.getInterfaces());
+ if (clazz.hasMethodsOrFields()) {
+ classDataLayout.add(clazz);
+ }
+ addTypeList(clazz.getInterfaces());
clazz.forEachProgramMethodMatching(DexEncodedMethod::hasCode, codeLayout::add);
DexAnnotationDirectory annotationDirectory =
mixedSectionOffsets.getAnnotationDirectoryForClass(clazz);
if (annotationDirectory != null) {
annotationDirectoryLayout.add(annotationDirectory);
annotationDirectory.visitAnnotations(
- annotationLayout::add, annotationSetLayout::add, annotationSetRefListLayout::add);
+ this::addAnnotation, this::addAnnotationSet, this::addAnnotationSetRefList);
}
DexEncodedArray staticFieldValues = mixedSectionOffsets.getStaticFieldValuesForClass(clazz);
if (staticFieldValues != null) {
@@ -179,7 +197,7 @@
@Override
public boolean addProto(DexProto proto) {
- typeListLayout.add(proto.getParameters());
+ addTypeList(proto.getParameters());
return true;
}
@@ -188,6 +206,12 @@
return true;
}
+ private void addTypeList(DexTypeList typeList) {
+ if (!typeList.isEmpty()) {
+ typeListLayout.add(typeList);
+ }
+ }
+
@Override
public boolean addCallSite(DexCallSite callSite) {
encodedArrayLayout.add(callSite.getEncodedArray());
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 06a3be7..95120b2 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -2517,4 +2517,10 @@
public boolean canHaveInvokeInterfaceToObjectMethodBug() {
return isGeneratingDex() && getMinApiLevel().isLessThan(AndroidApiLevel.P);
}
+
+ // Until we fully drop support for API levels < 16, we have to emit an empty annotation set to
+ // work around a DALVIK bug. See b/36951668.
+ public boolean canHaveDalvikEmptyAnnotationSetBug() {
+ return minApiLevel.isLessThan(AndroidApiLevel.J_MR1);
+ }
}