diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java b/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java new file mode 100644 index 00000000000..2f14cfb0f04 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 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. + */ + +package compiler.lib.compile_framework; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +/** + * Build a ClassLoader that loads from classpath and {@code classesDir}. + * Helper class that generates a ClassLoader which allows loading classes + * from the classpath (see {@link Utils#getClassPaths()}) and {@code classesDir}. + *
+ * The CompileFramework compiles all its classes to a specific {@code classesDir},
+ * and this generated ClassLoader thus can be used to load those classes.
+ */
+class ClassLoaderBuilder {
+
+ /**
+ * Build a ClassLoader that loads from classpath and {@code classesDir}.
+ */
+ public static ClassLoader build(Path classesDir) {
+ ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
+
+ try {
+ // Classpath for all included classes (e.g. IR Framework).
+ // Get all class paths, convert to URLs.
+ List Please reference the README.md for more details and examples.
+ */
+public class CompileFramework {
+ private final List
+ * Additionally, we must set the classpath for the Test-VM, so that it has access to all compiled
+ * classes (see {@link CompileFramework#getEscapedClassPathOfCompiledClasses}).
+ */
+public class IRFrameworkJavaExample {
+
+ public static void main(String[] args) {
+ testX1();
+ testX2();
+ }
+
+ // Generate a source java file as String
+ public static String generateX1(CompileFramework comp) {
+ return String.format("""
+ import compiler.lib.ir_framework.*;
+
+ public class X1 {
+ public static void main(String args[]) {
+ TestFramework framework = new TestFramework(X1.class);
+ framework.addFlags("-classpath", "%s");
+ framework.start();
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0"},
+ applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"})
+ static float[] test() {
+ float[] a = new float[1024*8];
+ for (int i = 0; i < a.length; i++) {
+ a[i]++;
+ }
+ return a;
+ }
+ }
+ """, comp.getEscapedClassPathOfCompiledClasses());
+ }
+
+ static void testX1() {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ comp.addJavaSourceCode("X1", generateX1(comp));
+
+ // Compile the source file.
+ comp.compile();
+
+ // X1.main();
+ comp.invoke("X1", "main", new Object[] {null});
+ }
+
+ // Generate a source java file as String
+ public static String generateX2(CompileFramework comp) {
+ // Example with conflicting "@IR" rules -> expect a IRViolationException.
+ return String.format("""
+ import compiler.lib.ir_framework.*;
+
+ public class X2 {
+ public static void main(String args[]) {
+ TestFramework framework = new TestFramework(X2.class);
+ framework.addFlags("-classpath", "%s");
+ framework.start();
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD, "> 0"})
+ @IR(failOn = IRNode.LOAD)
+ static void test() {
+ }
+ }
+ """, comp.getEscapedClassPathOfCompiledClasses());
+ }
+
+ static void testX2() {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ comp.addJavaSourceCode("X2", generateX2(comp));
+
+ // Compile the source file.
+ comp.compile();
+
+ // Load the compiled class.
+ Class> c = comp.getClass("X2");
+
+ // Invoke the "X2.main" method from the compiled and loaded class.
+ try {
+ c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
+
+ // Check if IR framework is expected to execute the IR rules.
+ if (Utils.getTestJavaOpts().length == 0 && Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp()) {
+ throw new RuntimeException("IRViolationException expected.");
+ } else {
+ System.out.println("Got no IRViolationException, but was also not expected.");
+ }
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("No such method:", e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Illegal access:", e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t == null) {
+ throw new RuntimeException("IRViolationException expected:", e);
+ }
+ if (!t.getClass().getSimpleName().equals("IRViolationException")) {
+ throw new RuntimeException("IRViolationException expected:", e);
+ }
+ System.out.println("Success, we got a IRViolationException.");
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java
new file mode 100644
index 00000000000..33fe07a5397
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test to use the Compile Framework.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver comile_framework.examples.MultiFileJasmExample
+ */
+
+package comile_framework.examples;
+
+import compiler.lib.compile_framework.*;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+/**
+ * This test shows a compilation of multiple jasm source code files.
+ */
+public class MultiFileJasmExample {
+
+ // Generate a source jasm file as String
+ public static String generate(int i) {
+ StringWriter writer = new StringWriter();
+ PrintWriter out = new PrintWriter(writer);
+ out.println("package p/xyz;");
+ out.println("");
+ out.println("super public class XYZ" + i + " {");
+ out.println(" public static Method test:\"(I)I\"");
+ out.println(" stack 20 locals 20");
+ out.println(" {");
+ out.println(" iload_0;");
+ out.println(" iconst_2;"); // every call multiplies by 2, in total 2^10 = 1024
+ out.println(" imul;");
+ if (i != 0) {
+ out.println(" invokestatic Method p/xyz/XYZ" + (i-1) + ".\"test\":\"(I)I\";");
+ }
+ out.println(" ireturn;");
+ out.println(" }");
+ out.println("}");
+ return writer.toString();
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Generate 10 files.
+ for (int i = 0; i < 10; i++) {
+ comp.addJasmSourceCode("p.xyz.XYZ" + i, generate(i));
+ }
+
+ // Compile the source files.
+ comp.compile();
+
+ // Object ret = XYZ9.test(5);
+ Object ret = comp.invoke("p.xyz.XYZ9", "test", new Object[] { 5 });
+
+ // Extract return value of invocation, verify its value.
+ int i = (int)ret;
+ System.out.println("Result of call: " + i);
+ if (i != 5 * 1024) {
+ throw new RuntimeException("wrong value: " + i);
+ }
+ System.out.println("Success.");
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java
new file mode 100644
index 00000000000..e493ebab4e8
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test to use the Compile Framework.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.examples.MultiFileJavaExample
+ */
+
+package compile_framework.examples;
+
+import compiler.lib.compile_framework.*;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+/**
+ * This test shows a compilation of multiple java source code files.
+ */
+public class MultiFileJavaExample {
+
+ // Generate a source java file as String
+ public static String generate(int i) {
+ StringWriter writer = new StringWriter();
+ PrintWriter out = new PrintWriter(writer);
+ out.println("package p.xyz;");
+ out.println("");
+ out.println("public class XYZ" + i + " {");
+ if (i > 0) {
+ out.println(" public XYZ" + (i - 1) + " xyz = new XYZ" + (i - 1) + "();");
+ }
+ out.println("");
+ out.println(" public static Object test() {");
+ out.println(" return new XYZ" + i + "();");
+ out.println(" }");
+ out.println("}");
+ return writer.toString();
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Generate 10 files.
+ for (int i = 0; i < 10; i++) {
+ comp.addJavaSourceCode("p.xyz.XYZ" + i, generate(i));
+ }
+
+ // Compile the source files.
+ comp.compile();
+
+ // Object ret = XYZ9.test();
+ Object ret = comp.invoke("p.xyz.XYZ9", "test", new Object[] {});
+
+ if (!ret.getClass().getSimpleName().equals("XYZ9")) {
+ throw new RuntimeException("wrong result:" + ret);
+ }
+ System.out.println("Success.");
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java
new file mode 100644
index 00000000000..a67e6e0eb49
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test to use the Compile Framework and run the compiled code with additional flags
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.examples.RunWithFlagsExample
+ */
+
+package compile_framework.examples;
+
+import compiler.lib.compile_framework.*;
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/**
+ * This test shows how the generated code can be compiled and invoked in a new VM. This allows
+ * the execution of the code with additional VM flags and options.
+ *
+ * The new VM must be able to locate the class files of the newly compiled code. For this we
+ * set the class path using {@link CompileFramework#getEscapedClassPathOfCompiledClasses}.
+ */
+public class RunWithFlagsExample {
+
+ private static String generate() {
+ return """
+ package p.xyz;
+
+ public class X {
+ public static void main(String args[]) {
+ System.out.println("Hello world!");
+ System.out.println(System.getProperty("MyMessage", "fail"));
+ System.err.println(args[0]);
+ }
+ }
+ """;
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a Java source file.
+ comp.addJavaSourceCode("p.xyz.X", generate());
+
+ // Compile the source file.
+ comp.compile();
+
+ // Build command line.
+ String[] command = {
+ // Set the classpath to include our newly compiled class.
+ "-classpath",
+ comp.getEscapedClassPathOfCompiledClasses(),
+ // Pass additional flags here.
+ // "-Xbatch" is a harmless VM flag, so this example runs everywhere without issues.
+ "-Xbatch",
+ // We can also pass properties like "MyMessage".
+ "-DMyMessage=hello_world",
+ "p.xyz.X",
+ "hello_arg"
+ };
+
+ // Execute the command, and capture the output.
+ // The JTREG Java and VM options are automatically passed to the test VM.
+ OutputAnalyzer analyzer = ProcessTools.executeTestJava(command);
+
+ // Verify output.
+ analyzer.shouldHaveExitValue(0);
+ analyzer.stdoutContains("Hello world!");
+ analyzer.stdoutContains("hello_world");
+ analyzer.stdoutContains("hello_arg");
+
+ // Print output to stderr.
+ analyzer.reportDiagnosticSummary();
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java
new file mode 100644
index 00000000000..e01b45e7441
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test to use the Compile Framework.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.examples.SimpleJasmExample
+ */
+
+package compile_framework.examples;
+
+import compiler.lib.compile_framework.*;
+
+/**
+ * This test shows a simple compilation of java source code, and its invocation.
+ */
+public class SimpleJasmExample {
+
+ // Generate a source jasm file as String
+ public static String generate() {
+ return """
+ super public class XYZ {
+ public static Method test:"(I)I"
+ stack 20 locals 20
+ {
+ iload_0;
+ iconst_2;
+ imul;
+ ireturn;
+ }
+ }
+ """;
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ String src = generate();
+ comp.addJasmSourceCode("XYZ", src);
+
+ // Compile the source file.
+ comp.compile();
+
+ // Object ret = XYZ.test(5);
+ Object ret = comp.invoke("XYZ", "test", new Object[] {5});
+
+ // Extract return value of invocation, verify its value.
+ int i = (int)ret;
+ System.out.println("Result of call: " + i);
+ if (i != 10) {
+ throw new RuntimeException("wrong value: " + i);
+ }
+ System.out.println("Success.");
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java
new file mode 100644
index 00000000000..5e54a6e8a08
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test to use the Compile Framework.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.examples.SimpleJavaExample
+ */
+
+package compile_framework.examples;
+
+import compiler.lib.compile_framework.*;
+
+/**
+ * This test shows a simple compilation of java source code, and its invocation.
+ */
+public class SimpleJavaExample {
+
+ // Generate a source java file as String
+ public static String generate() {
+ return """
+ public class XYZ {
+ public static int test(int i) {
+ System.out.println("Hello from XYZ.test: " + i);
+ return i * 2;
+ }
+ }
+ """;
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ comp.addJavaSourceCode("XYZ", generate());
+
+ // Compile the source file.
+ comp.compile();
+
+ // Object ret = XYZ.test(5);
+ Object ret = comp.invoke("XYZ", "test", new Object[] {5});
+
+ // Extract return value of invocation, verify its value.
+ int i = (int)ret;
+ System.out.println("Result of call: " + i);
+ if (i != 10) {
+ throw new RuntimeException("wrong value: " + i);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java
new file mode 100644
index 00000000000..b5b6f3e1040
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test with failing jasm compilation.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.tests.TestBadJasmCompilation
+ */
+
+package compile_framework.tests;
+
+import compiler.lib.compile_framework.*;
+
+public class TestBadJasmCompilation {
+
+ // Generate a source jasm file as String
+ public static String generate() {
+ return """
+ super public class XYZ {
+ some bad code
+ }
+ """;
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ comp.addJasmSourceCode("XYZ", generate());
+
+ try {
+ // Compile the source file.
+ comp.compile();
+ throw new RuntimeException("Expected compilation to fail.");
+ } catch (CompileFrameworkException e) {
+ System.out.println("Success, expected compilation to fail.");
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java
new file mode 100644
index 00000000000..1cb1d79afbc
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test with failing java compilation.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.tests.TestBadJavaCompilation
+ */
+
+package compile_framework.tests;
+
+import compiler.lib.compile_framework.*;
+
+public class TestBadJavaCompilation {
+
+ // Generate a source java file as String
+ public static String generate() {
+ return """
+ public class XYZ {
+ some bad code
+ }
+ """;
+ }
+
+ public static void main(String[] args) {
+ // Create a new CompileFramework instance.
+ CompileFramework comp = new CompileFramework();
+
+ // Add a java source file.
+ comp.addJavaSourceCode("XYZ", generate());
+
+ try {
+ // Compile the source file.
+ comp.compile();
+ throw new RuntimeException("Expected compilation to fail.");
+ } catch (CompileFrameworkException e) {
+ System.out.println("Success, expected compilation to fail.");
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java
new file mode 100644
index 00000000000..1cb902d34e4
--- /dev/null
+++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 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
+ * @summary Example test with multi-threaded use of the CompileFramework.
+ * Tests that the source and class directories are set up correctly.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @run driver compile_framework.tests.TestConcurrentCompilation
+ */
+
+package compile_framework.tests;
+
+import compiler.lib.compile_framework.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestConcurrentCompilation {
+
+ // Generate a source java file as String
+ public static String generate(int i) {
+ return String.format("""
+ public class XYZ {
+ public static int test() {
+ return %d;
+ }
+ }
+ """, i);
+ }
+
+ public static void test(int i) {
+ System.out.println("Generate and compile XYZ for " + i);
+ CompileFramework comp = new CompileFramework();
+ comp.addJavaSourceCode("XYZ", generate(i));
+ comp.compile();
+
+ // Now, sleep to give the other threads time to compile and store their class-files.
+ System.out.println("Sleep for " + i);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ System.out.println("Sleep interrupted for " + i);
+ }
+
+ // Now, hopefully all threads have compiled and stored their class-files.
+ // We can check if we get the expected result, i.e. the class-file from the current thread.
+ System.out.println("Run XYZ.test for " + i);
+ int j = (int)comp.invoke("XYZ", "test", new Object[] {});
+ if (i != j) {
+ System.out.println("Wrong value: " + i + " vs " + j);
+ throw new RuntimeException("Wrong value: " + i + " vs " + j);
+ }
+ System.out.println("Success for " + i);
+ }
+
+ public static class MyRunnable implements Runnable {
+ private int i;
+
+ public MyRunnable(int i) {
+ this.i = i;
+ }
+
+ public void run() {
+ TestConcurrentCompilation.test(i);
+ }
+ }
+
+ public static void main(String[] args) {
+ System.out.println("Generating threads:");
+ List