Extend completeness checking for tivi to enum unboxing
Fixes: b/267592755
Change-Id: Icb83c1b92ddb5116f30a9c91036922129f4d6c11
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 6301054..97467f1 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import static com.android.tools.r8.profile.art.ArtProfileCompletenessChecker.CompletenessExceptions.ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS;
import static com.android.tools.r8.utils.AssertionUtils.forTesting;
import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
@@ -533,7 +534,8 @@
new PrimaryR8IRConverter(appViewWithLiveness, timing)
.optimize(appViewWithLiveness, executorService);
- assert ArtProfileCompletenessChecker.verify(appView);
+ assert ArtProfileCompletenessChecker.verify(
+ appView, ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS);
// Clear the reference type lattice element cache to reduce memory pressure.
appView.dexItemFactory().clearTypeElementsCache();
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
index 581db1b..21a7635 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
@@ -4,39 +4,56 @@
package com.android.tools.r8.profile.art;
+import static com.android.tools.r8.profile.art.ArtProfileCompletenessChecker.CompletenessExceptions.ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS;
+
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
public class ArtProfileCompletenessChecker {
- public static boolean verify(AppView<?> appView) {
+ public enum CompletenessExceptions {
+ ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS
+ }
+
+ public static boolean verify(
+ AppView<?> appView, CompletenessExceptions... completenessExceptions) {
if (appView.options().getArtProfileOptions().isCompletenessCheckForTestingEnabled()) {
ArtProfile completeArtProfile = appView.getArtProfileCollection().asNonEmpty().getLast();
- assert verifyProfileIsComplete(appView, completeArtProfile);
+ assert verifyProfileIsComplete(
+ appView, completeArtProfile, Sets.newHashSet(completenessExceptions));
}
return true;
}
- private static boolean verifyProfileIsComplete(AppView<?> appView, ArtProfile artProfile) {
+ private static boolean verifyProfileIsComplete(
+ AppView<?> appView,
+ ArtProfile artProfile,
+ Set<CompletenessExceptions> completenessExceptions) {
assert !appView.getSyntheticItems().hasPendingSyntheticClasses();
List<DexReference> missing = new ArrayList<>();
for (DexProgramClass clazz : appView.appInfo().classesWithDeterministicOrder()) {
if (appView.horizontallyMergedClasses().hasBeenMergedIntoDifferentType(clazz.getType())
|| (appView.hasVerticallyMergedClasses()
- && appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(clazz.getType()))) {
+ && appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(clazz.getType()))
+ || appView.unboxedEnums().isUnboxedEnum(clazz)) {
continue;
}
if (!artProfile.containsClassRule(clazz.getType())) {
- missing.add(clazz.getType());
+ recordMissingDefinition(appView, clazz, completenessExceptions, missing);
}
- for (DexEncodedMethod method : clazz.methods()) {
+ for (ProgramMethod method : clazz.programMethods()) {
if (!artProfile.containsMethodRule(method.getReference())) {
- missing.add(method.getReference());
+ recordMissingDefinition(appView, method, completenessExceptions, missing);
}
}
}
@@ -47,4 +64,26 @@
}
return true;
}
+
+ private static void recordMissingDefinition(
+ AppView<?> appView,
+ ProgramDefinition definition,
+ Set<CompletenessExceptions> completenessExceptions,
+ List<DexReference> missing) {
+ if (completenessExceptions.contains(ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS)) {
+ DexType contextType = definition.getContextType();
+ SyntheticItems syntheticItems = appView.getSyntheticItems();
+ if (syntheticItems.isSynthetic(contextType)) {
+ if (syntheticItems.isSyntheticOfKind(
+ contextType, naming -> naming.ENUM_UNBOXING_CHECK_NOT_ZERO_METHOD)
+ || syntheticItems.isSyntheticOfKind(
+ contextType, naming -> naming.ENUM_UNBOXING_LOCAL_UTILITY_CLASS)
+ || syntheticItems.isSyntheticOfKind(
+ contextType, naming -> naming.ENUM_UNBOXING_SHARED_UTILITY_CLASS)) {
+ return;
+ }
+ }
+ }
+ missing.add(definition.getReference());
+ }
}
diff --git a/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java b/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
index fa4833f..c2d3a03 100644
--- a/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
+++ b/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
@@ -48,7 +48,6 @@
public void testR8() throws Exception {
testForR8(Backend.DEX)
.addProgramFiles(outDirectory.resolve("program.jar"))
- .addOptionsModification(options -> options.enableEnumUnboxing = false)
.addOptionsModification(
options -> options.getArtProfileOptions().setEnableCompletenessCheckForTesting(true))
.apply(this::configure)