# HG changeset patch # User dpochepk # Date 1464703108 0 # Node ID 58ef2d9356d287e17ef6cdaf2b8ccdb19e8c4b34 # Parent 6927906da88069af6a2e7d418363e01925d8564e# Parent 8ffd59d7bc529721bd86cb05c0a393e3f1c30e62 Merge diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/Makefile --- a/hotspot/test/testlibrary/jittester/Makefile Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/Makefile Tue May 31 13:58:28 2016 +0000 @@ -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) diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/conf/default.properties --- a/hotspot/test/testlibrary/jittester/conf/default.properties Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/conf/default.properties Tue May 31 13:58:28 2016 +0000 @@ -9,3 +9,5 @@ print-complexity=true print-hierarchy=true disable-static=true +generatorsFactories=jdk.test.lib.jittester.TestGeneratorsFactory +generators=JavaCode,ByteCode diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java --- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java Tue May 31 13:58:28 2016 +0000 @@ -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 generateIRTree(String name) { SymbolTable.removeAll(); @@ -120,123 +89,48 @@ } } + private static List getTestGenerators() { + List result = new ArrayList<>(); + Class factoryClass; + Function> factory; + String[] factoryClassNames = ProductionParams.generatorsFactories.value().split(","); + String[] generatorNames = ProductionParams.generators.value().split(","); + for (String factoryClassName : factoryClassNames) { + try { + factoryClass = Class.forName(factoryClassName); + factory = (Function>) 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 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 generators = getTestGenerators(); + do { + double start = System.currentTimeMillis(); + System.out.print("[" + LocalTime.now() + "] |"); + String name = "Test_" + counter; + Pair 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()); } } diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java --- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java Tue May 31 13:58:28 2016 +0000 @@ -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 { - 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 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(); diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java --- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java Tue May 31 13:58:28 2016 +0000 @@ -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 { - 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 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"}; } } diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java --- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java Tue May 31 13:58:28 2016 +0000 @@ -68,8 +68,6 @@ public static Option disableNestedBlocks = null; public static Option disableArrays = null; public static Option enableFinalizers = null; - public static Option disableBytecodeGeneration = null; - public static Option disableJavacodeGeneration = null; // workaraound: to reduce chance throwing ArrayIndexOutOfBoundsException public static Option chanceExpressionIndex = null; public static Option testbaseDir = null; @@ -78,6 +76,8 @@ public static Option specificSeed = null; public static Option classesFile = null; public static Option excludeMethodsFile = null; + public static Option generators = null; + public static Option 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"); } } diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TestGeneratorsFactory.java --- /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 13:58:28 2016 +0000 @@ -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> { + + @Override + public List apply(String[] input) { + List 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; + } +} diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TestsGenerator.java --- /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 13:58:28 2016 +0000 @@ -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 { + 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 preRunActions; + protected final String jtDriverOptions; + + protected TestsGenerator(String suffix) { + this(suffix, s -> new String[0], ""); + } + + protected TestsGenerator(String suffix, Function 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 ""; + } +} diff -r 6927906da880 -r 58ef2d9356d2 hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java --- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java Tue May 31 15:10:10 2016 +0300 +++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java Tue May 31 13:58:28 2016 +0000 @@ -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); }