Version 2.0.88
Cherry-pick: Add reproduction of duplicate methods due to staticizer
CL: https://r8-review.googlesource.com/52125
Cherry-pick: Disable moving not processed members to host for
staticizer
CL: https://r8-review.googlesource.com/52142
Bug: 157966650
Bug: 158018192
Change-Id: If0f96a1a9a3782eab457688e4f7ca9170bbe321d
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index ce8b350..28c54ff 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.0.87";
+ public static final String LABEL = "2.0.88";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index 3bc9825..5f510b7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.ir.optimize.staticizer;
+import static com.google.common.base.Predicates.not;
+
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.Descriptor;
@@ -665,7 +667,8 @@
if (candidateClass.type != hostType) {
DexClass hostClass = appView.definitionFor(hostType);
assert hostClass != null;
- if (!classMembersConflict(candidateClass, hostClass)) {
+ if (!classMembersConflict(candidateClass, hostClass)
+ && !hasMembersNotStaticized(candidateClass, staticizedMethods)) {
// Move all members of the candidate class into host class.
moveMembersIntoHost(staticizedMethods,
candidateClass, hostType, hostClass, methodMapping, fieldMapping);
@@ -686,6 +689,16 @@
|| Streams.stream(a.methods()).anyMatch(method -> b.lookupMethod(method.method) != null);
}
+ private boolean hasMembersNotStaticized(
+ DexProgramClass candidateClass, Set<DexEncodedMethod> staticizedMethods) {
+ // TODO(b/159174309): Refine the analysis to allow for fields.
+ if (candidateClass.hasFields()) {
+ return true;
+ }
+ // TODO(b/158018192): Activate again when picking up all references.
+ return candidateClass.methods(not(staticizedMethods::contains)).iterator().hasNext();
+ }
+
private void moveMembersIntoHost(
Set<DexEncodedMethod> staticizedMethods,
DexProgramClass candidateClass,
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/HostWithStaticMethodTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/HostWithStaticMethodTest.java
new file mode 100644
index 0000000..0fcb3ee
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/HostWithStaticMethodTest.java
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.staticizer;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ir.optimize.staticizer.HostWithStaticMethodTest.Outer.SingletonHolder;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+// This is a reproduction of b/158018192.
+public class HostWithStaticMethodTest extends TestBase {
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public HostWithStaticMethodTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testR8() throws ExecutionException, CompilationFailedException, IOException {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Outer.class, SingletonHolder.class, Main.class)
+ .addKeepMainRule(Main.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableNeverClassInliningAnnotations()
+ .enableInliningAnnotations()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("foo", "bar", "foo");
+ }
+
+ @NeverClassInline
+ public static class Outer {
+
+ public static class SingletonHolder {
+
+ public static final Outer outer = new Outer();
+
+ @NeverInline
+ // This method should not be in conflict with any methods in Outer.
+ public static void foo2() {
+ foo();
+ }
+ }
+
+ @NeverInline
+ public static void foo() {
+ System.out.println("foo");
+ }
+
+ @NeverInline
+ public void bar() {
+ System.out.println("bar");
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ Outer.foo();
+ SingletonHolder.outer.bar();
+ SingletonHolder.foo2();
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InstanceInsideCompanionTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InstanceInsideCompanionTest.java
index f28235b..5dabfaf 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InstanceInsideCompanionTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InstanceInsideCompanionTest.java
@@ -46,8 +46,9 @@
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), MAIN)
- .assertSuccessWithOutputLines("Candidate#foo(false)")
- .inspect(this::inspect);
+ .assertSuccessWithOutputLines("Candidate#foo(false)");
+ // TODO(b/159174309): Disable inspection until fixed.
+ // .inspect(this::inspect);
}
private void inspect(CodeInspector inspector) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InvokeStaticWithNullOutvalueTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InvokeStaticWithNullOutvalueTest.java
index e552581..4e3f691 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InvokeStaticWithNullOutvalueTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/InvokeStaticWithNullOutvalueTest.java
@@ -59,11 +59,13 @@
assertThat(instance, not(isPresent()));
ClassSubject companion = inspector.clazz(Host.Companion.class);
- assertThat(companion, not(isPresent()));
+ // TODO(b/158018192): This should not be present.
+ assertThat(companion, isPresent());
// Check if the candidate methods are staticized (if necessary) and migrated.
for (String name : ImmutableList.of("boo", "foo")) {
- MethodSubject oo = host.uniqueMethodWithName(name);
+ // TODO(b/158018192): This should be host and not companion.
+ MethodSubject oo = companion.uniqueMethodWithName(name);
assertThat(oo, isPresent());
assertTrue(oo.isStatic());
assertTrue(