jdk-24/test/hotspot/jtreg/compiler/c2/unloaded/TestInlineUnloaded.java
Evgeny Nikitin 5394f57f00 8330621: Make 5 compiler tests use ProcessTools.executeProcess
Reviewed-by: chagedorn, stefank, thartmann
2024-04-22 07:41:06 +00:00

229 lines
8.5 KiB
Java

/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8294609
* @requires vm.compiler2.enabled & vm.flagless
*
* @library /test/lib
*
* @build compiler.c2.unloaded.TestInlineUnloaded
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar launcher.jar
* compiler.c2.unloaded.TestInlineUnloaded
* compiler.c2.unloaded.TestInlineUnloaded$Launcher
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar parent.jar
* compiler.c2.unloaded.TestInlineUnloaded$Parent
* compiler.c2.unloaded.TestInlineUnloaded$Parent$U
* compiler.c2.unloaded.TestInlineUnloaded$Parent$TestCase
* compiler.c2.unloaded.TestInlineUnloaded$Parent$Invoker
* compiler.c2.unloaded.TestInlineUnloaded$Parent$TestNull
* compiler.c2.unloaded.TestInlineUnloaded$Parent$TestLoadedRemotely
* compiler.c2.unloaded.TestInlineUnloaded$Parent$TestUnloaded
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar caller.jar
* compiler.c2.unloaded.TestInlineUnloaded$Caller
* compiler.c2.unloaded.TestInlineUnloaded$Caller$TestNull
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar callee.jar
* compiler.c2.unloaded.TestInlineUnloaded$Callee
* compiler.c2.unloaded.TestInlineUnloaded$Callee$TestNull
*
* @run driver compiler.c2.unloaded.TestInlineUnloaded
*/
package compiler.c2.unloaded;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.function.Consumer;
public class TestInlineUnloaded {
static final String THIS_CLASS = TestInlineUnloaded.class.getName();
public static class Parent {
public class U {
}
public interface TestCase {
U test(Invoker obj, U arg);
void testArg(Invoker obj, U arg);
U testRet(Invoker obj);
void test(Invoker obj);
}
public interface Invoker {
void invokeArg(U obj);
U invokeRet();
U invoke(U obj);
}
private static class TestNull implements Runnable {
final TestCase test;
final Invoker recv;
public TestNull(TestCase test, Invoker recv) {
this.test = test;
this.recv = recv;
}
@Override
public void run() {
test.testArg(recv, null);
test.testRet(recv);
test.test(recv, null);
}
}
public static class TestLoadedRemotely extends TestNull {
public TestLoadedRemotely(TestCase test, Invoker recv) throws Exception {
super(test, recv);
Class.forName(U.class.getName()); // preload in parent context
}
}
public static class TestUnloaded extends TestNull {
public TestUnloaded(TestCase test, Invoker recv) {
super(test, recv);
}
}
}
public static class Caller {
public static class TestNull implements Parent.TestCase {
public TestNull() {}
public Parent.U test(Parent.Invoker obj, Parent.U arg) {
return obj.invoke(arg);
}
public void testArg(Parent.Invoker obj, Parent.U arg) {
obj.invokeArg(arg);
}
public Parent.U testRet(Parent.Invoker obj) {
return obj.invokeRet();
}
public void test(Parent.Invoker obj) {
test(obj, null);
}
}
}
public static class Callee {
public static class TestNull implements Parent.Invoker {
public void invokeArg(Parent.U obj) {}
public Parent.U invokeRet() {
return null;
}
public Parent.U invoke(Parent.U obj) {
return obj;
}
}
}
public static class Launcher {
public static void main(String... args) throws Exception {
final String testName = args[0];
URLClassLoader parentCL = new URLClassLoader("parent", new URL[] { new URL("file:parent.jar") }, ClassLoader.getSystemClassLoader());
URLClassLoader callerCL = new URLClassLoader("caller", new URL[] { new URL("file:caller.jar") }, parentCL);
URLClassLoader calleeCL = new URLClassLoader("callee", new URL[] { new URL("file:callee.jar") }, parentCL);
Object caller = Class.forName(THIS_CLASS + "$Caller$TestNull", false, callerCL)
.getDeclaredConstructor().newInstance();
Object callee = Class.forName(THIS_CLASS + "$Callee$TestNull", false, calleeCL)
.getDeclaredConstructor().newInstance();
Class<?> testClass = Class.forName(THIS_CLASS + "$Parent$TestCase", false, parentCL);
Class<?> invClass = Class.forName(THIS_CLASS + "$Parent$Invoker", false, parentCL);
Class<?> test = Class.forName(THIS_CLASS + "$Parent$" + testName, false, parentCL);
Runnable r = (Runnable) test.getDeclaredConstructor(testClass, invClass)
.newInstance(caller, callee);
for (int i = 0; i < 20_000; i ++) {
r.run();
}
}
}
static void run(String testCaseName, Consumer<OutputAnalyzer> processor) throws Exception {
ProcessBuilder pb = new ProcessBuilder();
pb.command(JDKToolFinder.getJDKTool("java"),
"-cp", "launcher.jar",
"-XX:+IgnoreUnrecognizedVMOptions", "-showversion",
"-XX:-TieredCompilation", "-Xbatch",
"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining",
"-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,*TestNull::run",
Launcher.class.getName(), testCaseName);
System.out.println("Command line: [" + pb.command() + "]");
OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
analyzer.shouldHaveExitValue(0);
// The test is applicable only to C2 (present in Server VM).
analyzer.stderrShouldContain("Server VM");
analyzer.shouldContain("TestNull::run"); // ensure that relevant method is compiled
processor.accept(analyzer); // test-specific checks
}
public static void main(String[] args) throws Exception {
run("TestUnloaded", output -> {
output.shouldMatch("TestNull::testArg .* unloaded signature classes");
output.shouldMatch("TestNull::testRet .* unloaded signature classes");
output.shouldMatch("TestNull::test .* unloaded signature classes");
output.shouldMatch("TestNull::testArg .* failed to inline");
output.shouldMatch("TestNull::testRet .* failed to inline");
output.shouldMatch("TestNull::test .* failed to inline");
});
run("TestLoadedRemotely", output -> {
output.shouldMatch("TestNull::testArg .* inline");
output.shouldMatch("TestNull::testRet .* inline");
output.shouldMatch("TestNull::test .* inline");
output.shouldNotMatch("TestNull::testArg .* unloaded signature classes");
output.shouldNotMatch("TestNull::testRet .* unloaded signature classes");
output.shouldNotMatch("TestNull::test .* unloaded signature classes");
});
}
}