1 /* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.test.lib.jittester; 25 26 import java.io.File; 27 import java.io.FileWriter; 28 import java.io.IOException; 29 import java.util.HashSet; 30 import java.util.Iterator; 31 import java.util.concurrent.TimeUnit; 32 import java.util.logging.Level; 33 import java.util.logging.Logger; 34 import jdk.test.lib.jittester.IRNode; 35 import jdk.test.lib.jittester.ProductionParams; 36 import jdk.test.lib.jittester.SymbolTable; 37 import jdk.test.lib.jittester.TypeList; 38 import jdk.test.lib.jittester.factories.IRNodeBuilder; 39 import jdk.test.lib.jittester.TypesParser; 40 import jdk.test.lib.jittester.types.TypeKlass; 41 import jdk.test.lib.jittester.visitors.JavaCodeVisitor; 42 import jdk.test.lib.jittester.utils.OptionResolver; 43 import jdk.test.lib.jittester.utils.OptionResolver.Option; 44 import jdk.test.lib.jittester.utils.PseudoRandom; 45 46 public class Automatic { 47 public static final int minutesToWait = 3; 48 49 private static String makeTestCase(String name) { 50 SymbolTable.removeAll(); 51 TypeList.removeAll(); 52 StringBuilder resultVis = new StringBuilder(); 53 StringBuilder headerBuilder = new StringBuilder(); 54 try { 55 IRNodeBuilder builder = new IRNodeBuilder() 56 .setPrefix(name) 57 .setName(name) 58 .setLevel(0); 59 60 JavaCodeVisitor vis = new JavaCodeVisitor(); 61 String synopsis = "seed = '" + ProductionParams.seed.value() + "'"; 62 String pathPrefix = ProductionParams.testbaseDir.value() 63 .replaceAll("([^/]+)", ".."); 64 headerBuilder 65 .append("/*\n") 66 .append(" * @test\n") 67 .append(" * @summary ") 68 .append(synopsis) 69 .append("\n") 70 .append(" * @compile ") 71 .append(name) 72 .append(".java\n") 73 .append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver\n") 74 .append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ") 75 .append(name) 76 .append("\n") 77 .append(" */\n\n"); 78 79 80 if (!ProductionParams.disableClasses.value()) { 81 long comlexityLimit = (long) (ProductionParams.complexityLimit.value() 82 * PseudoRandom.random()); 83 IRNode privateClasses = builder.setComplexityLimit(comlexityLimit) 84 .getClassDefinitionBlockFactory() 85 .produce(); 86 if (privateClasses != null) { 87 resultVis.append(privateClasses.accept(vis)); 88 } 89 } 90 long mainComplexityLimit = (long) (ProductionParams.complexityLimit.value() 91 * PseudoRandom.random()); 92 IRNode mainClass = builder.setComplexityLimit(mainComplexityLimit) 93 .getMainKlassFactory() 94 .produce(); 95 resultVis.append(mainClass.accept(vis)); 96 97 if (ProductionParams.printHierarchy.value()) { 98 headerBuilder 99 .append("/*\n") 100 .append(Automatic.printHierarchy()) 101 .append("*/\n"); 102 } 103 } catch (Exception e) { 104 e.printStackTrace(System.out); 105 } 106 return headerBuilder.append(resultVis).toString(); 107 } 108 109 private static void initializeTestGenerator(String[] params) { 110 OptionResolver parser = new OptionResolver(); 111 Option<String> propertyFileOpt = parser.addStringOption('p', "property-file", "", 112 "File to read properties from"); 113 ProductionParams.register(parser); 114 parser.parse(params, propertyFileOpt); 115 jdk.test.lib.jittester.utils.PseudoRandom.reset(ProductionParams.seed.value()); 116 TypesParser.parseTypesAndMethods(ProductionParams.classesFile.value(), ProductionParams.excludeMethodsFile.value()); 117 } 118 119 public static void main(String[] args) { 120 initializeTestGenerator(args); 121 int counter = 0; 122 try { 123 String testbaseDir = ProductionParams.testbaseDir.value(); 124 do { 125 double start = System.currentTimeMillis(); 126 String name = "Test_" + counter; 127 generateTestFile(name); 128 double generationTime = System.currentTimeMillis() - start; 129 String path = getJavaPath(); 130 ProcessBuilder pb = new ProcessBuilder(path + "javac", testbaseDir + "/" + name + ".java"); 131 runProcess(pb, testbaseDir + "/" + name); 132 133 start = System.currentTimeMillis(); 134 pb = new ProcessBuilder(path + "java", "-Xint", "-cp", testbaseDir, name); 135 name = name + ".gold"; 136 runProcess(pb, testbaseDir + "/" + name); 137 double runningTime = System.currentTimeMillis() - start; 138 System.out.printf("%4d : generation time (ms) : %8.0f running time (ms) : %8.0f\n", 139 counter, generationTime, runningTime); 140 if (runningTime < TimeUnit.MINUTES.toMillis(minutesToWait)) 141 ++counter; 142 } while (counter < ProductionParams.numberOfTests.value()); 143 } catch (IOException | InterruptedException ex) { 144 Logger.getLogger(Automatic.class.getName()).log(Level.SEVERE, null, ex); 145 } 146 } 147 148 private static String getJavaPath() { 149 String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" }; 150 for (String name : env) { 151 String path = System.getenv(name); 152 if (path != null) { 153 return path + "/bin/"; 154 } 155 } 156 return ""; 157 } 158 159 private static void runProcess(ProcessBuilder pb, String name) 160 throws IOException, InterruptedException { 161 pb.redirectError(new File(name + ".err")); 162 pb.redirectOutput(new File(name + ".out")); 163 Process process = pb.start(); 164 if (process.waitFor(minutesToWait, TimeUnit.MINUTES)) { 165 try (FileWriter file = new FileWriter(name + ".exit")) { 166 file.write(Integer.toString(process.exitValue())); 167 } 168 } else { 169 process.destroyForcibly(); 170 } 171 TimeUnit.MILLISECONDS.sleep(300); 172 } 173 174 private static void generateTestFile(String testName) { 175 String code = makeTestCase(testName); 176 String testbaseDir = ProductionParams.testbaseDir.value(); 177 String fileName = testbaseDir + "/" + testName + ".java"; 178 try (FileWriter file = new FileWriter(fileName)) { 179 file.write(code); 180 //file.close(); 181 } catch (IOException ex) { 182 Logger.getLogger(Automatic.class.getName()) 183 .log(Level.SEVERE, " Cannot write to file " + fileName, ex); 184 } 185 } 186 187 private static String printHierarchy() { 188 String r = "CLASS HIERARCHY:\n"; 189 for (Type t : TypeList.getAll()) { 190 if (t instanceof TypeKlass) { 191 TypeKlass k = (TypeKlass) t; 192 if (k.isAbstract()) { 193 r += "abstract "; 194 } 195 if (k.isFinal()) { 196 r += "final "; 197 } 198 if (k.isInterface()) { 199 r += "interface "; 200 } else { 201 r += "class "; 202 } 203 r += k.getName() + ": "; 204 HashSet<String> parents = k.getParentsNames(); 205 if (parents != null) { 206 Iterator<String> n = parents.iterator(); 207 int size = parents.size(); 208 for (int i = 0; n.hasNext() && i < size - 1; i++) { 209 r += n.next() + ", "; 210 } 211 if (n.hasNext()) { 212 r += n.next(); 213 } 214 } 215 r += "\n"; 216 } 217 } 218 return r; 219 } 220 }