blob: bb5847635a99c6f1857e26b74e8e204fcb8b23d0 [file] [log] [blame]
// Copyright (c) 2022, 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.desugar.jdk8272564;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.examples.jdk18.jdk8272564.Jdk8272564;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class Jdk8272564Test extends TestBase {
@Parameters(name = "{0}")
public static TestParametersCollection data() {
// TODO(b/218293990): Right now the JDK 18 tests are built with -target 17, as our Gradle
// version does not know of -target 18.
return getTestParameters()
.withCfRuntimesStartingFromIncluding(CfVm.JDK17)
.withDexRuntimes()
.withAllApiLevelsAlsoForCf()
.build();
}
@Parameter(0)
public TestParameters parameters;
// With the fix for JDK-8272564 there are no invokevirtual instructions.
private void assertJdk8272564FixedCode(CodeInspector inspector) {
assertTrue(
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("f")
.streamInstructions()
.noneMatch(InstructionSubject::isInvokeVirtual));
assertTrue(
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("g")
.streamInstructions()
.noneMatch(InstructionSubject::isInvokeVirtual));
}
// Without the fix for JDK-8272564 there is one invokeinterface and 2 invokevirtual instructions.
private void assertJdk8272564NotFixedCode(
CodeInspector inspector, int invokeVirtualCount, int getClassCount) {
assertEquals(
1,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("f")
.streamInstructions()
.filter(InstructionSubject::isInvokeInterface)
.count());
assertEquals(
2,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("f")
.streamInstructions()
.filter(InstructionSubject::isInvokeVirtual)
.count());
assertEquals(
2,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("g")
.streamInstructions()
.filter(InstructionSubject::isInvokeInterface)
.count());
assertEquals(
2,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("g")
.streamInstructions()
.filter(InstructionSubject::isInvokeInterface)
.count());
assertEquals(
invokeVirtualCount,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("g")
.streamInstructions()
.filter(InstructionSubject::isInvokeVirtual)
.count());
assertEquals(
getClassCount,
inspector
.clazz(Jdk8272564.Main.typeName())
.uniqueMethodWithOriginalName("g")
.streamInstructions()
.filter(InstructionSubject::isInvoke)
.filter(instruction -> instruction.getMethod().getName().toString().equals("getClass"))
.count());
}
private void assertJdk8272564NotFixedCode(CodeInspector inspector) {
assertJdk8272564NotFixedCode(inspector, 22, 3);
}
private void assertJdk8272564NotFixedCodeR8(CodeInspector inspector) {
assertJdk8272564NotFixedCode(inspector, 19, 0);
}
private boolean isDefaultCfParameters() {
return parameters.isCfRuntime() && parameters.getApiLevel().equals(AndroidApiLevel.B);
}
@Test
// See https://bugs.openjdk.java.net/browse/JDK-8272564.
public void testJdk8272564Compiler() throws Exception {
assumeTrue(isDefaultCfParameters());
// Ensure that the test is running with CF input from fixing JDK-8272564.
assertJdk8272564FixedCode(new CodeInspector(Jdk8272564.jar()));
}
@Test
public void testJvm() throws Exception {
assumeTrue(isDefaultCfParameters());
testForJvm(parameters)
.addRunClasspathFiles(Jdk8272564.jar())
.run(parameters.getRuntime(), Jdk8272564.Main.typeName())
.assertSuccess();
}
@Test
public void testD8() throws Exception {
testForDesugaring(parameters)
.addProgramFiles(Jdk8272564.jar())
.run(parameters.getRuntime(), Jdk8272564.Main.typeName())
.applyIf(
parameters.isDexRuntime() && parameters.getApiLevel().isLessThan(AndroidApiLevel.S),
b -> b.inspect(this::assertJdk8272564NotFixedCode),
b -> b.inspect(this::assertJdk8272564FixedCode))
.assertSuccess();
}
@Test
public void testR8() throws Exception {
parameters.assumeR8TestParameters();
// The R8 lens code rewriter rewrites to the code prior to fixing JDK-8272564.
testForR8(parameters.getBackend())
.addProgramFiles(Jdk8272564.jar())
.setMinApi(parameters)
.noTreeShaking()
.addKeepClassAndMembersRules(Jdk8272564.Main.typeName())
.run(parameters.getRuntime(), Jdk8272564.Main.typeName())
.inspect(this::assertJdk8272564NotFixedCodeR8)
.assertSuccess();
}
}