8352020: [CompileFramework] enable compilation for VectorAPI

Reviewed-by: chagedorn, kvn
This commit is contained in:
Emanuel Peter 2025-03-20 06:13:52 +00:00
parent a5d06a1876
commit 3ed010ab7c
3 changed files with 105 additions and 6 deletions

View File

@ -30,6 +30,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.List;
import jdk.test.lib.JDKToolFinder;
@ -47,7 +48,7 @@ class Compile {
* Compile all sources in {@code javaSources}. First write them to the {@code sourceDir},
* then compile them to class-files which are stored in {@code classesDir}.
*/
public static void compileJavaSources(List<SourceCode> javaSources, Path sourceDir, Path classesDir) {
public static void compileJavaSources(List<SourceCode> javaSources, Path sourceDir, Path classesDir, String[] javacFlags) {
if (javaSources.isEmpty()) {
Utils.printlnVerbose("No java sources to compile.");
return;
@ -55,7 +56,7 @@ class Compile {
Utils.printlnVerbose("Compiling Java sources: " + javaSources.size());
List<Path> javaFilePaths = writeSourcesToFiles(javaSources, sourceDir);
compileJavaFiles(javaFilePaths, classesDir);
compileJavaFiles(javaFilePaths, classesDir, javacFlags);
Utils.printlnVerbose("Java sources compiled.");
}
@ -63,10 +64,13 @@ class Compile {
* Compile a list of files (i.e. {@code paths}) using javac and store
* them in {@code classesDir}.
*/
private static void compileJavaFiles(List<Path> paths, Path classesDir) {
private static void compileJavaFiles(List<Path> paths, Path classesDir, String[] javacFlags) {
List<String> command = new ArrayList<>();
command.add(JAVAC_PATH);
if (javacFlags != null) {
command.addAll(Arrays.asList(javacFlags));
}
command.add("-classpath");
// Note: the backslashes from windows paths must be escaped!
command.add(Utils.getEscapedClassPathAndClassesDir(classesDir));
@ -192,8 +196,10 @@ class Compile {
throw new CompileFrameworkException("InterruptedException during compilation", e);
}
if (exitCode != 0 || !output.isEmpty()) {
// Note: the output can be non-empty even if the compilation succeeds, e.g. for warnings.
if (exitCode != 0) {
System.err.println("Compilation failed.");
System.err.println("Command: " + command);
System.err.println("Exit code: " + exitCode);
System.err.println("Output: '" + output + "'");
throw new CompileFrameworkException("Compilation failed.");

View File

@ -71,8 +71,11 @@ public class CompileFramework {
* Compile all sources: store the sources to the {@link sourceDir} directory, compile
* Java and Jasm sources and store the generated class-files in the {@link classesDir}
* directory.
*
* @param javacFlags: optional, list of additional flags for javac, e.g. to make modules
* visible.
*/
public void compile() {
public void compile(String... javacFlags) {
if (classLoader != null) {
throw new CompileFrameworkException("Cannot compile twice!");
}
@ -86,7 +89,7 @@ public class CompileFramework {
System.out.println("Classes directory: " + classesDir);
Compile.compileJasmSources(jasmSources, sourceDir, classesDir);
Compile.compileJavaSources(javaSources, sourceDir, classesDir);
Compile.compileJavaSources(javaSources, sourceDir, classesDir, javacFlags);
classLoader = ClassLoaderBuilder.build(classesDir);
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2025, 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 together with the IR Framework (i.e. TestFramework),
* and the VectorAPI.
* @modules java.base/jdk.internal.misc
* @modules jdk.incubator.vector
* @library /test/lib /
* @compile ../../../compiler/lib/ir_framework/TestFramework.java
* @run driver compile_framework.examples.IRFrameworkWithVectorAPIExample
*/
package compile_framework.examples;
import compiler.lib.compile_framework.*;
import jdk.test.lib.Utils;
import jdk.incubator.vector.IntVector;
import jdk.test.lib.Platform;
import java.lang.reflect.InvocationTargetException;
/**
* This test shows that the IR verification can be done on code compiled by the Compile Framework.
* The "@compile" command for JTREG is required so that the IRFramework is compiled, other javac
* might not compile it because it is not present in the class, only in the dynamically compiled
* code.
* <p>
* 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 IRFrameworkWithVectorAPIExample {
public static void main(String[] args) {
// Create a new CompileFramework instance.
CompileFramework comp = new CompileFramework();
// Add a java source file.
comp.addJavaSourceCode("InnerTest", generateInnerTest(comp));
// Compile the source file. "javac" needs to know that it is ok to compile with the
// VectorAPI module.
comp.compile("--add-modules=jdk.incubator.vector");
// InnerTest.main();
comp.invoke("InnerTest", "main", new Object[] {null});
}
// Generate a source java file as String
public static String generateInnerTest(CompileFramework comp) {
return String.format("""
import compiler.lib.ir_framework.*;
import jdk.incubator.vector.*;
public class InnerTest {
public static void main(String args[]) {
TestFramework framework = new TestFramework(InnerTest.class);
// Also the TestFramework must allow the test VM to see the VectorAPI module.
framework.addFlags("-classpath", "%s", "--add-modules=jdk.incubator.vector");
framework.start();
}
@Test
static Object test() {
return IntVector.broadcast(IntVector.SPECIES_64, 42);
}
}
""", comp.getEscapedClassPathOfCompiledClasses());
}
}