1 /* 2 * Copyright (c) 2005, 2016, 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 jdk.test.lib.util.Pair; 27 import jdk.test.lib.jittester.factories.IRNodeBuilder; 28 import jdk.test.lib.jittester.types.TypeKlass; 29 import jdk.test.lib.jittester.utils.FixedTrees; 30 import jdk.test.lib.jittester.utils.OptionResolver; 31 import jdk.test.lib.jittester.utils.OptionResolver.Option; 32 import jdk.test.lib.jittester.utils.PseudoRandom; 33 import java.time.LocalTime; 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.concurrent.TimeUnit; 37 import java.util.function.Function; 38 39 public class Automatic { 40 public static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3); 41 42 private static Pair<IRNode, IRNode> generateIRTree(String name) { 43 SymbolTable.removeAll(); 44 TypeList.removeAll(); 45 46 IRNodeBuilder builder = new IRNodeBuilder() 47 .setPrefix(name) 48 .setName(name) 49 .setLevel(0); 50 51 Long complexityLimit = ProductionParams.complexityLimit.value(); 52 IRNode privateClasses = null; 53 if (!ProductionParams.disableClasses.value()) { 54 long privateClassComlexity = (long) (complexityLimit * PseudoRandom.random()); 55 try { 56 privateClasses = builder.setComplexityLimit(privateClassComlexity) 57 .getClassDefinitionBlockFactory() 58 .produce(); 59 } catch (ProductionFailedException ex) { 60 ex.printStackTrace(System.out); 61 } 62 } 63 long mainClassComplexity = (long) (complexityLimit * PseudoRandom.random()); 64 IRNode mainClass = null; 65 try { 66 mainClass = builder.setComplexityLimit(mainClassComplexity) 67 .getMainKlassFactory() 68 .produce(); 69 TypeKlass aClass = new TypeKlass(name); 70 mainClass.getChild(1).addChild(FixedTrees.generateMainOrExecuteMethod(aClass, true)); 71 mainClass.getChild(1).addChild(FixedTrees.generateMainOrExecuteMethod(aClass, false)); 72 } catch (ProductionFailedException ex) { 73 ex.printStackTrace(System.out); 74 } 75 return new Pair<>(mainClass, privateClasses); 76 } 77 78 private static void initializeTestGenerator(String[] params) { 79 OptionResolver parser = new OptionResolver(); 80 Option<String> propertyFileOpt = parser.addStringOption('p', "property-file", 81 "conf/default.properties", "File to read properties from"); 82 ProductionParams.register(parser); 83 parser.parse(params, propertyFileOpt); 84 PseudoRandom.reset(ProductionParams.seed.value()); 85 TypesParser.parseTypesAndMethods(ProductionParams.classesFile.value(), 86 ProductionParams.excludeMethodsFile.value()); 87 if (ProductionParams.specificSeed.isSet()) { 88 PseudoRandom.setCurrentSeed(ProductionParams.specificSeed.value()); 89 } 90 } 91 92 private static List<TestsGenerator> getTestGenerators() { 93 List<TestsGenerator> result = new ArrayList<>(); 94 Class<?> factoryClass; 95 Function<String[], List<TestsGenerator>> factory; 96 String[] factoryClassNames = ProductionParams.generatorsFactories.value().split(","); 97 String[] generatorNames = ProductionParams.generators.value().split(","); 98 for (String factoryClassName : factoryClassNames) { 99 try { 100 factoryClass = Class.forName(factoryClassName); 101 factory = (Function<String[], List<TestsGenerator>>) factoryClass.newInstance(); 102 } catch (ReflectiveOperationException roe) { 103 throw new Error("Can't instantiate generators factory", roe); 104 } 105 result.addAll(factory.apply(generatorNames)); 106 } 107 return result; 108 } 109 110 public static void main(String[] args) { 111 initializeTestGenerator(args); 112 int counter = 0; 113 System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat", 114 "running"); 115 System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---", "---"); 116 List<TestsGenerator> generators = getTestGenerators(); 117 do { 118 double start = System.currentTimeMillis(); 119 System.out.print("[" + LocalTime.now() + "] |"); 120 String name = "Test_" + counter; 121 Pair<IRNode, IRNode> irTree = generateIRTree(name); 122 System.out.printf(" %8d |", counter); 123 long maxWaitTime = TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT); 124 double generationTime = System.currentTimeMillis() - start; 125 System.out.printf(" %8.0f |", generationTime); 126 start = System.currentTimeMillis(); 127 Thread generatorThread = new Thread(() -> { 128 for (TestsGenerator generator : generators) { 129 generator.accept(irTree.first, irTree.second); 130 } 131 }); 132 generatorThread.start(); 133 try { 134 generatorThread.join(maxWaitTime); 135 } catch (InterruptedException ie) { 136 throw new Error("Test generation interrupted: " + ie, ie); 137 } 138 if (generatorThread.isAlive()) { 139 // maxTime reached, so, proceed to next test generation 140 generatorThread.interrupt(); 141 } else { 142 double runningTime = System.currentTimeMillis() - start; 143 System.out.printf(" %8.0f |%n", runningTime); 144 if (runningTime < maxWaitTime) { 145 ++counter; 146 } 147 } 148 } while (counter < ProductionParams.numberOfTests.value()); 149 } 150 }