8158065: [Jittester]: tests generation has tests generators hardcoded, blocking alternative tests generation
Reviewed-by: iignatyev
--- a/hotspot/test/testlibrary/jittester/Makefile Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/Makefile Tue May 31 15:48:47 2016 +0300
@@ -44,6 +44,10 @@
APPLICATION_ARGS += --seed $(SEED)
endif
+ifneq "x$(EXTRA_SRC_DIR)" "x"
+ EXTRA_SRC_FILES := $(shell find $(EXTRA_SRC_DIR) -name '*.java')
+endif
+
JAVA = $(JDK_HOME)/bin/java
JAVAC = $(JDK_HOME)/bin/javac
JAR = $(JDK_HOME)/bin/jar
@@ -99,6 +103,7 @@
filelist: $(SRC_FILES)
@rm -f $@
@echo $(SRC_FILES) > $@
+ @echo $(EXTRA_SRC_FILES) >> $@
INIT: $(DIST_DIR)
$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
--- a/hotspot/test/testlibrary/jittester/conf/default.properties Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/conf/default.properties Tue May 31 15:48:47 2016 +0300
@@ -9,3 +9,5 @@
print-complexity=true
print-hierarchy=true
disable-static=true
+generatorsFactories=jdk.test.lib.jittester.TestGeneratorsFactory
+generators=JavaCode,ByteCode
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java Tue May 31 15:48:47 2016 +0300
@@ -25,50 +25,19 @@
import jdk.test.lib.Pair;
import jdk.test.lib.jittester.factories.IRNodeBuilder;
-import jdk.test.lib.jittester.jtreg.Printer;
import jdk.test.lib.jittester.types.TypeKlass;
import jdk.test.lib.jittester.utils.FixedTrees;
import jdk.test.lib.jittester.utils.OptionResolver;
import jdk.test.lib.jittester.utils.OptionResolver.Option;
import jdk.test.lib.jittester.utils.PseudoRandom;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
+import java.util.function.Function;
public class Automatic {
- private static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
-
- static String getJtregHeader(String mainClass, boolean addCompile) {
- String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
- + ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
- StringBuilder header = new StringBuilder();
- header.append("/*\n * @test\n * @summary ")
- .append(synopsis)
- .append(" \n* @library / ../\n");
- if (addCompile) {
- header.append("\n * @compile ")
- .append(mainClass)
- .append(".java\n");
- }
- header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
- + "jdk.test.lib.jittester.jtreg.Printer\n")
- .append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
- .append(mainClass)
- .append("\n */\n\n");
- if (ProductionParams.printHierarchy.value()) {
- header.append("/*\n")
- .append(Automatic.printHierarchy())
- .append("*/\n");
- }
- return header.toString();
- }
+ public static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
private static Pair<IRNode, IRNode> generateIRTree(String name) {
SymbolTable.removeAll();
@@ -120,123 +89,48 @@
}
}
+ private static List<TestsGenerator> getTestGenerators() {
+ List<TestsGenerator> result = new ArrayList<>();
+ Class<?> factoryClass;
+ Function<String[], List<TestsGenerator>> factory;
+ String[] factoryClassNames = ProductionParams.generatorsFactories.value().split(",");
+ String[] generatorNames = ProductionParams.generators.value().split(",");
+ for (String factoryClassName : factoryClassNames) {
+ try {
+ factoryClass = Class.forName(factoryClassName);
+ factory = (Function<String[], List<TestsGenerator>>) factoryClass.newInstance();
+ } catch (ReflectiveOperationException roe) {
+ throw new Error("Can't instantiate generators factory", roe);
+ }
+ result.addAll(factory.apply(generatorNames));
+ }
+ return result;
+ }
+
public static void main(String[] args) {
initializeTestGenerator(args);
int counter = 0;
- try {
- Path testbaseDir = Paths.get(ProductionParams.testbaseDir.value());
- System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
- "running");
- System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---","---");
- String path = getJavaPath();
- String javacPath = Paths.get(path, "javac").toString();
- String javaPath = Paths.get(path, "java").toString();
-
- // compile Printer class first. A common one for all tests
- ensureExisting(testbaseDir);
- ProcessBuilder pbPrinter = new ProcessBuilder(javacPath,
- Paths.get(testbaseDir.toString(), "jdk", "test", "lib", "jittester",
- "jtreg", "Printer.java").toString());
- runProcess(pbPrinter, testbaseDir.resolve("Printer").toString());
- do {
- double start = System.currentTimeMillis();
- System.out.print("[" + LocalTime.now() + "] |");
- String name = "Test_" + counter;
- Pair<IRNode, IRNode> irTree = generateIRTree(name);
- System.out.printf(" %8d |", counter);
- double generationTime = System.currentTimeMillis() - start;
- System.out.printf(" %8.0f |", generationTime);
- if (!ProductionParams.disableJavacodeGeneration.value()) {
- JavaCodeGenerator generator = new JavaCodeGenerator();
- String javaFile = generator.apply(irTree.first, irTree.second);
- ProcessBuilder pb = new ProcessBuilder(javacPath, "-cp", testbaseDir.toString()
- + ":" + generator.getTestbase().toString(), javaFile);
- runProcess(pb, generator.getTestbase().resolve(name).toString());
- start = System.currentTimeMillis();
-
- // Run compiled class files
- pb = new ProcessBuilder(javaPath, "-Xint", "-cp", testbaseDir.toString()
- + ":" + generator.getTestbase().toString(), name);
- String goldFile = name + ".gold";
- runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
- }
-
- if (!ProductionParams.disableBytecodeGeneration.value()) {
- ByteCodeGenerator generator = new ByteCodeGenerator();
- generator.apply(irTree.first, irTree.second);
- generator.writeJtregBytecodeRunner(name);
- // Run generated bytecode
- ProcessBuilder pb = new ProcessBuilder(javaPath, "-Xint", "-Xverify", "-cp",
- testbaseDir.toString() + ":" + generator.getTestbase().toString(),
- name);
- String goldFile = name + ".gold";
- start = System.currentTimeMillis();
- runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
- }
-
- double runningTime = System.currentTimeMillis() - start;
- System.out.printf(" %8.0f |%n", runningTime);
- if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
- ++counter;
- }
- } while (counter < ProductionParams.numberOfTests.value());
- } catch (IOException | InterruptedException ex) {
- ex.printStackTrace();
- }
- }
-
- private static String getJavaPath() {
- String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
- for (String name : env) {
- String path = System.getenv(name);
- if (path != null) {
- return path + "/bin/";
+ System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
+ "running");
+ System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---", "---");
+ List<TestsGenerator> generators = getTestGenerators();
+ do {
+ double start = System.currentTimeMillis();
+ System.out.print("[" + LocalTime.now() + "] |");
+ String name = "Test_" + counter;
+ Pair<IRNode, IRNode> irTree = generateIRTree(name);
+ System.out.printf(" %8d |", counter);
+ double generationTime = System.currentTimeMillis() - start;
+ System.out.printf(" %8.0f |", generationTime);
+ start = System.currentTimeMillis();
+ for (TestsGenerator generator : generators) {
+ generator.accept(irTree.first, irTree.second);
}
- }
- return "";
- }
-
- private static int runProcess(ProcessBuilder pb, String name)
- throws IOException, InterruptedException {
- pb.redirectError(new File(name + ".err"));
- pb.redirectOutput(new File(name + ".out"));
- Process process = pb.start();
- if (process.waitFor(MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
- try (FileWriter file = new FileWriter(name + ".exit")) {
- file.write(Integer.toString(process.exitValue()));
+ double runningTime = System.currentTimeMillis() - start;
+ System.out.printf(" %8.0f |%n", runningTime);
+ if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
+ ++counter;
}
- return process.exitValue();
- } else {
- process.destroyForcibly();
- return -1;
- }
- }
-
- private static String printHierarchy() {
- return TypeList.getAll().stream()
- .filter(t -> t instanceof TypeKlass)
- .map(t -> typeDescription((TypeKlass) t))
- .collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
- }
-
- private static String typeDescription(TypeKlass type) {
- StringBuilder result = new StringBuilder();
- String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
- result.append(type.isAbstract() ? "abstract " : "")
- .append(type.isFinal() ? "final " : "")
- .append(type.isInterface() ? "interface " : "class ")
- .append(type.getName())
- .append(parents.isEmpty() ? "" : ": " + parents);
- return result.toString();
- }
-
- static void ensureExisting(Path path) {
- if (Files.notExists(path)) {
- try {
- Files.createDirectories(path);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
+ } while (counter < ProductionParams.numberOfTests.value());
}
}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java Tue May 31 15:48:47 2016 +0300
@@ -23,54 +23,60 @@
package jdk.test.lib.jittester;
-import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
-
import java.io.FileOutputStream;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.util.function.BiFunction;
+import java.util.function.Function;
+import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
/**
- * Generates class files from bytecode
+ * Generates class files from IRTree
*/
-class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
- private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(),
- "bytecode_tests");
+class ByteCodeGenerator extends TestsGenerator {
+ private static final String DEFAULT_SUFFIX = "bytecode_tests";
- public void writeJtregBytecodeRunner(String name) {
- try (FileWriter file = new FileWriter(testbase.resolve(name + ".java").toFile())) {
- file.write(Automatic.getJtregHeader(name, false));
- } catch (IOException e) {
- e.printStackTrace();
- }
+ ByteCodeGenerator() {
+ super(DEFAULT_SUFFIX);
+ }
+
+ ByteCodeGenerator(String suffix, Function<String, String[]> preRunActions, String jtDriverOptions) {
+ super(suffix, preRunActions, jtDriverOptions);
}
- public String apply(IRNode mainClass, IRNode privateClasses) {
- Automatic.ensureExisting(testbase);
+ @Override
+ public void accept(IRNode mainClass, IRNode privateClasses) {
+ generateClassFiles(mainClass, privateClasses);
+ generateSeparateJtregHeader(mainClass);
+ compilePrinter();
+ generateGoldenOut(mainClass.getName());
+ }
+
+ private void generateSeparateJtregHeader(IRNode mainClass) {
+ String mainClassName = mainClass.getName();
+ writeFile(generatorDir, mainClassName + ".java", getJtregHeader(mainClassName));
+ }
+
+ private void generateClassFiles(IRNode mainClass, IRNode privateClasses) {
+ String mainClassName = mainClass.getName();
+ ensureExisting(generatorDir);
try {
ByteCodeVisitor vis = new ByteCodeVisitor();
if (privateClasses != null) {
privateClasses.accept(vis);
}
mainClass.accept(vis);
-
- Path mainClassPath = testbase.resolve(mainClass.getName() + ".class");
- writeToClassFile(mainClassPath, vis.getByteCode(mainClass.getName()));
+ writeFile(mainClassName + ".class", vis.getByteCode(mainClassName));
if (privateClasses != null) {
privateClasses.getChildren().forEach(c -> {
String name = c.getName();
- Path classPath = testbase.resolve(name + ".class");
- writeToClassFile(classPath, vis.getByteCode(name));
+ writeFile(name + ".class", vis.getByteCode(name));
});
}
- return mainClassPath.toString();
} catch (Throwable t) {
- Path errFile = testbase.resolve(mainClass.getName() + ".err");
+ Path errFile = generatorDir.resolve(mainClassName + ".err");
try (PrintWriter pw = new PrintWriter(Files.newOutputStream(errFile,
StandardOpenOption.CREATE_NEW))) {
t.printStackTrace(pw);
@@ -78,16 +84,11 @@
t.printStackTrace();
throw new Error("can't write error to error file " + errFile, e);
}
- return null;
}
}
- public Path getTestbase() {
- return testbase;
- }
-
- private void writeToClassFile(Path path, byte[] bytecode) {
- try (FileOutputStream file = new FileOutputStream(path.toString())) {
+ private void writeFile(String fileName, byte[] bytecode) {
+ try (FileOutputStream file = new FileOutputStream(generatorDir.resolve(fileName).toFile())) {
file.write(bytecode);
} catch (IOException ex) {
ex.printStackTrace();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java Tue May 31 15:48:47 2016 +0300
@@ -23,48 +23,59 @@
package jdk.test.lib.jittester;
-import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
-
-import java.io.FileWriter;
+import java.io.File;
import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.function.BiFunction;
+import java.util.function.Function;
+import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
/**
- * Generates class files from java source code
+ * Generates java source code from IRTree
*/
-class JavaCodeGenerator implements BiFunction<IRNode, IRNode, String> {
- private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(), "java_tests");
+public class JavaCodeGenerator extends TestsGenerator {
+ private static final String DEFAULT_SUFFIX = "java_tests";
+
+ JavaCodeGenerator() {
+ this(DEFAULT_SUFFIX, JavaCodeGenerator::generatePrerunAction, "");
+ }
+
+ JavaCodeGenerator(String prefix, Function<String, String[]> preRunActions, String jtDriverOptions) {
+ super(prefix, preRunActions, jtDriverOptions);
+ }
- private String generateJavaCode(IRNode mainClass, IRNode privateClasses) {
+ @Override
+ public void accept(IRNode mainClass, IRNode privateClasses) {
+ String mainClassName = mainClass.getName();
+ generateSources(mainClass, privateClasses);
+ compilePrinter();
+ compileJavaFile(mainClassName);
+ generateGoldenOut(mainClassName);
+ }
+
+ private void generateSources(IRNode mainClass, IRNode privateClasses) {
+ String mainClassName = mainClass.getName();
StringBuilder code = new StringBuilder();
JavaCodeVisitor vis = new JavaCodeVisitor();
-
- code.append(Automatic.getJtregHeader(mainClass.getName(), true));
+ code.append(getJtregHeader(mainClassName));
if (privateClasses != null) {
code.append(privateClasses.accept(vis));
}
code.append(mainClass.accept(vis));
-
- return code.toString();
- }
-
- public Path getTestbase() {
- return testbase;
+ ensureExisting(generatorDir);
+ writeFile(generatorDir, mainClassName + ".java", code.toString());
}
- @Override
- public String apply(IRNode mainClass, IRNode privateClasses) {
- String code = generateJavaCode(mainClass, privateClasses);
- Automatic.ensureExisting(testbase);
- Path fileName = testbase.resolve(mainClass.getName() + ".java");
- try (FileWriter file = new FileWriter(fileName.toFile())) {
- file.write(code);
- return fileName.toString();
- } catch (IOException ex) {
- ex.printStackTrace();
+ private void compileJavaFile(String mainClassName) {
+ String classPath = getRoot() + File.pathSeparator + generatorDir;
+ ProcessBuilder pb = new ProcessBuilder(JAVAC, "-cp", classPath,
+ generatorDir.resolve(mainClassName + ".java").toString());
+ try {
+ runProcess(pb, generatorDir.resolve(mainClassName).toString());
+ } catch (IOException | InterruptedException e) {
+ throw new Error("Can't compile sources ", e);
}
- return "";
+ }
+
+ private static String[] generatePrerunAction(String mainClassName) {
+ return new String[] {"@compile " + mainClassName + ".java"};
}
}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java Tue May 31 15:48:47 2016 +0300
@@ -68,8 +68,6 @@
public static Option<Boolean> disableNestedBlocks = null;
public static Option<Boolean> disableArrays = null;
public static Option<Boolean> enableFinalizers = null;
- public static Option<Boolean> disableBytecodeGeneration = null;
- public static Option<Boolean> disableJavacodeGeneration = null;
// workaraound: to reduce chance throwing ArrayIndexOutOfBoundsException
public static Option<Integer> chanceExpressionIndex = null;
public static Option<String> testbaseDir = null;
@@ -78,6 +76,8 @@
public static Option<Long> specificSeed = null;
public static Option<String> classesFile = null;
public static Option<String> excludeMethodsFile = null;
+ public static Option<String> generators = null;
+ public static Option<String> generatorsFactories = null;
public static void register(OptionResolver optionResolver) {
productionLimit = optionResolver.addIntegerOption('l', "production-limit", 100, "Limit on steps in the production of an expression");
@@ -120,8 +120,6 @@
disableNestedBlocks = optionResolver.addBooleanOption("disable-nested-blocks", "Disable generation of nested blocks");
disableArrays = optionResolver.addBooleanOption("disable-arrays", "Disable generation of arrays");
enableFinalizers = optionResolver.addBooleanOption("enable-finalizers", "Enable finalizers (for stress testing)");
- disableBytecodeGeneration = optionResolver.addBooleanOption("disable-bytecode-generation", "Disable generation of bytecode output");
- disableJavacodeGeneration = optionResolver.addBooleanOption("disable-javacode-generation", "Disable generation of java source code output");
chanceExpressionIndex = optionResolver.addIntegerOption("chance-expression-index", 0, "A non negative decimal integer used to restrict chane of generating expression in array index while creating or accessing by index");
testbaseDir = optionResolver.addStringOption("testbase-dir", ".", "Testbase dir");
numberOfTests = optionResolver.addIntegerOption('n', "number-of-tests", 0, "Number of test classes to generate");
@@ -129,5 +127,7 @@
specificSeed = optionResolver.addLongOption('z', "specificSeed", 0L, "A seed to be set for specific test generation(regular seed still needed for initialization)");
classesFile = optionResolver.addStringOption('f', "classes-file", "conf/classes.lst", "File to read classes from");
excludeMethodsFile = optionResolver.addStringOption('r', "exclude-methods-file", "conf/exclude.methods.lst", "File to read excluded methods from");
+ generators = optionResolver.addStringOption("generators", "", "Comma-separated list of generator names");
+ generatorsFactories = optionResolver.addStringOption("generatorsFactories", "", "Comma-separated list of generators factories class names");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TestGeneratorsFactory.java Tue May 31 15:48:47 2016 +0300
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, 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 jdk.test.lib.jittester;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public class TestGeneratorsFactory implements Function<String[], List<TestsGenerator>> {
+
+ @Override
+ public List<TestsGenerator> apply(String[] input) {
+ List<TestsGenerator> result = new ArrayList<>();
+ for (String generatorName : input) {
+ switch (generatorName) {
+ case "JavaCode":
+ result.add(new JavaCodeGenerator());
+ break;
+ case "ByteCode":
+ result.add(new ByteCodeGenerator());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown generator: " + generatorName);
+ }
+ }
+ return result;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TestsGenerator.java Tue May 31 15:48:47 2016 +0300
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016, 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 jdk.test.lib.jittester;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+public abstract class TestsGenerator implements BiConsumer<IRNode, IRNode> {
+ protected static final String JAVA_BIN = getJavaPath();
+ protected static final String JAVAC = Paths.get(JAVA_BIN, "javac").toString();
+ protected static final String JAVA = Paths.get(JAVA_BIN, "java").toString();
+ protected final Path generatorDir;
+ protected final Function<String, String[]> preRunActions;
+ protected final String jtDriverOptions;
+
+ protected TestsGenerator(String suffix) {
+ this(suffix, s -> new String[0], "");
+ }
+
+ protected TestsGenerator(String suffix, Function<String, String[]> preRunActions,
+ String jtDriverOptions) {
+ generatorDir = getRoot().resolve(suffix);
+ this.preRunActions = preRunActions;
+ this.jtDriverOptions = jtDriverOptions;
+ }
+
+ protected void generateGoldenOut(String mainClassName) {
+ String classPath = getRoot() + File.pathSeparator + generatorDir;
+ ProcessBuilder pb = new ProcessBuilder(JAVA, "-Xint", "-Xverify", "-cp", classPath,
+ mainClassName);
+ String goldFile = mainClassName + ".gold";
+ try {
+ runProcess(pb, generatorDir.resolve(goldFile).toString());
+ } catch (IOException | InterruptedException e) {
+ throw new Error("Can't run generated test ", e);
+ }
+ }
+
+ protected static int runProcess(ProcessBuilder pb, String name)
+ throws IOException, InterruptedException {
+ pb.redirectError(new File(name + ".err"));
+ pb.redirectOutput(new File(name + ".out"));
+ Process process = pb.start();
+ if (process.waitFor(Automatic.MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
+ try (FileWriter file = new FileWriter(name + ".exit")) {
+ file.write(Integer.toString(process.exitValue()));
+ }
+ return process.exitValue();
+ } else {
+ process.destroyForcibly();
+ return -1;
+ }
+ }
+
+ protected static void compilePrinter() {
+ Path root = getRoot();
+ ProcessBuilder pbPrinter = new ProcessBuilder(JAVAC,
+ root.resolve("jdk")
+ .resolve("test")
+ .resolve("lib")
+ .resolve("jittester")
+ .resolve("jtreg")
+ .resolve("Printer.java")
+ .toString());
+ try {
+ int exitCode = runProcess(pbPrinter, root.resolve("Printer").toString());
+ if (exitCode != 0) {
+ throw new Error("Printer compilation returned exit code " + exitCode);
+ }
+ } catch (IOException | InterruptedException e) {
+ throw new Error("Can't compile printer", e);
+ }
+ }
+
+ protected static void ensureExisting(Path path) {
+ if (Files.notExists(path)) {
+ try {
+ Files.createDirectories(path);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ protected String getJtregHeader(String mainClassName) {
+ String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
+ + ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
+ StringBuilder header = new StringBuilder();
+ header.append("/*\n * @test\n * @summary ")
+ .append(synopsis)
+ .append(" \n * @library / ../\n");
+ header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
+ + "jdk.test.lib.jittester.jtreg.Printer\n");
+ for (String action : preRunActions.apply(mainClassName)) {
+ header.append(" * ")
+ .append(action)
+ .append("\n");
+ }
+ header.append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
+ .append(jtDriverOptions)
+ .append(" ")
+ .append(mainClassName)
+ .append("\n */\n\n");
+ if (ProductionParams.printHierarchy.value()) {
+ header.append("/*\n")
+ .append(printHierarchy())
+ .append("*/\n");
+ }
+ return header.toString();
+ }
+
+ protected static Path getRoot() {
+ return Paths.get(ProductionParams.testbaseDir.value());
+ }
+
+ protected static void writeFile(Path targetDir, String fileName, String content) {
+ try (FileWriter file = new FileWriter(targetDir.resolve(fileName).toFile())) {
+ file.write(content);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static String printHierarchy() {
+ return TypeList.getAll()
+ .stream()
+ .filter(t -> t instanceof TypeKlass)
+ .map(t -> typeDescription((TypeKlass) t))
+ .collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
+ }
+
+ private static String typeDescription(TypeKlass type) {
+ StringBuilder result = new StringBuilder();
+ String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
+ result.append(type.isAbstract() ? "abstract " : "")
+ .append(type.isFinal() ? "final " : "")
+ .append(type.isInterface() ? "interface " : "class ")
+ .append(type.getName())
+ .append(parents.isEmpty() ? "" : ": " + parents);
+ return result.toString();
+ }
+
+ private static String getJavaPath() {
+ String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
+ for (String name : env) {
+ String path = System.getenv(name);
+ if (path != null) {
+ return path + "/bin/";
+ }
+ }
+ return "";
+ }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java Mon May 30 23:33:00 2016 +0300
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java Tue May 31 15:48:47 2016 +0300
@@ -40,30 +40,31 @@
public class JitTesterDriver {
public static void main(String[] args) {
- if (args.length != 1) {
+ if (args.length < 1) {
throw new IllegalArgumentException(
"[TESTBUG]: wrong number of argument : " + args.length
- + ". Expected 1 argument -- jit-tester test name.");
+ + ". Expected at least 1 argument -- jit-tester test name.");
}
OutputAnalyzer oa;
try {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args[0]);
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args);
oa = new OutputAnalyzer(pb.start());
} catch (Exception e) {
throw new Error("Unexpected exception on test jvm start :" + e, e);
}
+ String name = args[args.length - 1];
Pattern splitOut = Pattern.compile("\\n"); // tests use \n only in stdout
Pattern splitErr = Pattern.compile("\\r?\\n"); // can handle both \r\n and \n
Path testDir = Paths.get(Utils.TEST_SRC);
- String goldOut = formatOutput(streamGoldFile(testDir, args[0], "out"));
+ String goldOut = formatOutput(streamGoldFile(testDir, name, "out"));
String anlzOut = formatOutput(Arrays.stream(splitOut.split(oa.getStdout())));
Asserts.assertEQ(anlzOut, goldOut, "Actual stdout isn't equal to golden one");
- String goldErr = formatOutput(streamGoldFile(testDir, args[0], "err"));
+ String goldErr = formatOutput(streamGoldFile(testDir, name, "err"));
String anlzErr = formatOutput(Arrays.stream(splitErr.split(oa.getStderr())));
Asserts.assertEQ(anlzErr, goldErr, "Actual stderr isn't equal to golden one");
- int exitValue = Integer.parseInt(streamGoldFile(testDir, args[0], "exit").findFirst().get());
+ int exitValue = Integer.parseInt(streamGoldFile(testDir, name, "exit").findFirst().get());
oa.shouldHaveExitValue(exitValue);
}