Account for ServiceLoaders in field value propagation
Fixes: b/389737060
Change-Id: Ide438a8e1b0541f3ce2385087f06f8b9909ab3c5
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/DefaultFieldValueJoiner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/DefaultFieldValueJoiner.java
index bd2fdb3..3a14982 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/DefaultFieldValueJoiner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/DefaultFieldValueJoiner.java
@@ -330,6 +330,7 @@
throws ExecutionException {
// To simplify the analysis, we currently bail out for non-final classes.
// TODO(b/296030319): Handle non-final classes.
+ Set<DexType> serviceImplementations = appView.appServices().computeAllServiceImplementations();
MapUtils.removeIf(
nonFinalInstanceFields,
(holderType, fields) -> {
@@ -337,7 +338,8 @@
DexProgramClass holder = fields.iterator().next().getHolder();
// If the class is kept it could be instantiated directly, in which case all default field
// values could be live.
- if (appView.getKeepInfo(holder).isPinned(appView.options())) {
+ if (appView.getKeepInfo(holder).isPinned(appView.options())
+ || serviceImplementations.contains(holder.getType())) {
fields.forEach(liveDefaultValueConsumer);
return true;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/DefaultFieldValueJoinerWithServiceLoaderTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/DefaultFieldValueJoinerWithServiceLoaderTest.java
index 62165a4..1efc4cb 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/DefaultFieldValueJoinerWithServiceLoaderTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/DefaultFieldValueJoinerWithServiceLoaderTest.java
@@ -45,8 +45,7 @@
Origin.unknown()))
.setMinApi(parameters)
.run(parameters.getRuntime(), Main.class)
- // TODO(b/389737060): Should be 0, 1, 0, 2.
- .assertSuccessWithOutputLines("1", "1", "2", "2");
+ .assertSuccessWithOutputLines("0", "1", "0", "2");
}
public interface A {