Never consider initialization of classes with a defined finalize trivial.
Bug: 143189461
Change-Id: I6725259ab5f1f22e5e52edb5c3055755669377e9
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 7ce2685..988bf75 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -797,6 +797,10 @@
return false;
}
+ public boolean definesFinalizer(DexItemFactory factory) {
+ return lookupVirtualMethod(factory.objectMethods.finalize) != null;
+ }
+
public boolean defaultValuesForStaticFieldsMayTriggerAllocation() {
return staticFields().stream()
.anyMatch(field -> field.getStaticValue().mayHaveSideEffects());
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 5554025..fb442d1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -376,6 +376,8 @@
// This method defines trivial instance initializer as follows:
//
+ // ** The holder class must not define a finalize method.
+ //
// ** The initializer may call the initializer of the base class, which
// itself must be trivial.
//
@@ -389,6 +391,10 @@
// (Note that this initializer does not have to have zero arguments.)
private TrivialInitializer computeInstanceInitializerInfo(
IRCode code, DexClass clazz, Function<DexType, DexClass> typeToClass) {
+ if (clazz.definesFinalizer(options.itemFactory)) {
+ // Defining a finalize method can observe the side-effect of Object.<init> GC registration.
+ return null;
+ }
Value receiver = code.getThis();
for (Instruction insn : code.instructions()) {
if (insn.isReturn()) {
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/sideeffect/AnonymousObjectWithFinalizeTest.java b/src/test/java/com/android/tools/r8/ir/analysis/sideeffect/AnonymousObjectWithFinalizeTest.java
index 8ae2890..7337693 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/sideeffect/AnonymousObjectWithFinalizeTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/sideeffect/AnonymousObjectWithFinalizeTest.java
@@ -14,6 +14,7 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+// See b/143189461
@RunWith(Parameterized.class)
public class AnonymousObjectWithFinalizeTest extends TestBase {
@@ -84,10 +85,6 @@
.addKeepMainRule(TestClass.class)
.addProgramClassesAndInnerClasses(TestClass.class)
.run(parameters.getRuntime(), TestClass.class)
- // TODO(b/143189461): Update to correct expected output once fixed.
- .assertSuccessWithOutputLines(
- "set up fence",
- "run gc",
- "fence await timed out");
+ .assertSuccessWithOutput(EXPECTED);
}
}