1 /* 2 * Copyright (c) 1998, 2020, 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 jit.graph; 25 26 import jdk.test.lib.Utils; 27 import jtreg.SkippedException; 28 import nsk.share.TestFailure; 29 import nsk.share.test.StressOptions; 30 31 import java.lang.reflect.InvocationTargetException; 32 import java.util.Vector; 33 34 public class CGT { 35 private static StressOptions stressOptions = new StressOptions(); 36 private static String ClistPath = ""; 37 private static long finishTime; 38 39 private final Vector summation = new Vector(100000); 40 private final Vector idList = new Vector(100000); 41 CGT(String[] args)42 public CGT(String[] args) { 43 parse(args); 44 Globals.initialize(ClistPath); 45 outputStats(args); 46 } 47 main(String[] args)48 public static void main(String[] args) { 49 stressOptions.parseCommandLine(args); 50 new CGT(args).run(); 51 } 52 outputStats(String[] args)53 public void outputStats(String[] args) { 54 System.out.println("CGT command line options:"); 55 for (String arg : args) { 56 System.out.println("# " + arg); 57 } 58 59 System.out.println(); 60 61 System.out.println("CGT parameters"); 62 System.out.println("Seed: " + Utils.SEED); 63 System.out.println("Number of Random Loop iterations: " + Globals.RANDOM_LOOP); 64 System.out.println("Number of Static Loop iterations: " + Globals.STATIC_LOOP); 65 System.out.println("Max number of Methods in the Graph: " + Globals.NUM_TEST_CLASSES); 66 System.out.println("Verbose function calls: " + Globals.VERBOSE); 67 68 System.out.println(); 69 } 70 run()71 public void run() { 72 finishTime = System.currentTimeMillis() + stressOptions.getTime() * 1000; 73 Long numFcalls = Globals.RANDOM_LOOP - 1; 74 Integer staticFcalls = Globals.STATIC_LOOP; 75 MethodData methodCallStr = Globals.nextRandomMethod(); 76 Globals.addFunctionIDToVector(methodCallStr.id, idList); 77 Throwable invocationExcept; 78 79 try { 80 methodCallStr.nextMethod.invoke(methodCallStr.instance, summation, idList, numFcalls, staticFcalls); 81 } catch (IllegalAccessException e) { 82 throw new TestFailure("Illegal Access Exception", e); 83 } catch (InvocationTargetException e) { 84 System.out.println("Invocation Target Exception"); 85 invocationExcept = e.getTargetException(); 86 System.out.println(invocationExcept); 87 if (invocationExcept.getClass() == e.getClass()) { 88 System.out.println("Processing Exception Invocation Target Exception"); 89 while (invocationExcept.getClass() == e.getClass()) { 90 invocationExcept = ((InvocationTargetException) invocationExcept).getTargetException(); 91 } 92 System.out.println(invocationExcept); 93 } 94 if (invocationExcept instanceof StackOverflowError) { 95 throw new SkippedException("stack overflow: skipping verification.", invocationExcept); 96 } else if (invocationExcept instanceof OutOfMemoryError) { 97 throw new SkippedException("test devoured heap ;), skipping verification.", invocationExcept); 98 } else { 99 throw new TestFailure(invocationExcept); 100 } 101 } 102 103 verify(); 104 } 105 verify()106 private void verify() { 107 long oldsum = 0; 108 long newsum; 109 System.out.println("begin call stack validation"); 110 if (summation.size() != idList.size()) { 111 throw new TestFailure("Vector Length's Do Not Match, VERIFY ERROR : Summation Element Count = " + summation.size() + " ID Element Count = " + idList.size()); 112 } 113 long vectorSize = summation.size(); 114 115 while (!summation.isEmpty()) { 116 if (CGT.shouldFinish()) { 117 throw new SkippedException("skipping verification due to timeout"); 118 } 119 120 newsum = (Long) summation.firstElement(); 121 summation.removeElementAt(0); 122 123 int functionID = (Integer) idList.firstElement(); 124 idList.removeElementAt(0); 125 126 if ((newsum - oldsum) != (functionID)) { 127 throw new TestFailure("Function Call structure invalid, VERIFY ERROR. Expected = " + (newsum - oldsum) + " Actual = " + functionID); 128 } 129 oldsum = newsum; 130 } 131 132 System.out.println("function call structure validated successfully (" + vectorSize + " calls validated)"); 133 } 134 shouldFinish()135 public static boolean shouldFinish() { 136 return System.currentTimeMillis() >= finishTime; 137 } 138 parse(String args[])139 public void parse(String args[]) { 140 for (int i = 0; i < args.length; i++) { 141 String arg = args[i].toLowerCase(); 142 switch (arg) { 143 case "-help": 144 case "-h": 145 case "-?": { 146 usage(); 147 System.exit(1); 148 break; 149 } 150 case "-staticloop": { 151 int argIndex = i + 1; 152 if (argIndex < args.length) { 153 try { 154 Globals.STATIC_LOOP = Math.abs(Integer.parseInt(args[argIndex])) * stressOptions.getIterationsFactor(); 155 } catch (NumberFormatException e) { 156 usage(); 157 throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e); 158 } 159 i++; 160 } else { 161 usage(); 162 throw new Error("TESTBUG: Improper Argument: " + args[i]); 163 } 164 break; 165 } 166 case "-randomloop": { 167 int argIndex = i + 1; 168 if (argIndex < args.length) { 169 try { 170 Globals.RANDOM_LOOP = Math.abs(Long.parseLong(args[argIndex])) * stressOptions.getIterationsFactor(); 171 } catch (NumberFormatException e) { 172 usage(); 173 throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e); 174 } 175 i++; 176 } else { 177 usage(); 178 throw new Error("TESTBUG: Improper Argument: " + args[i]); 179 180 } 181 break; 182 } 183 case "-numtestclass": { 184 int argIndex = i + 1; 185 if (argIndex < args.length) { 186 try { 187 Globals.NUM_TEST_CLASSES = Math.abs(Integer.parseInt(args[argIndex])); 188 } catch (NumberFormatException e) { 189 usage(); 190 throw new Error("TESTBUG: Improper Argument: " + args[i] + " " + args[argIndex], e); 191 } 192 i++; 193 } else { 194 usage(); 195 throw new Error("TESTBUG: Improper Argument: " + args[i]); 196 } 197 break; 198 } 199 case "-verbose": 200 case "-v": { 201 Globals.VERBOSE = true; 202 break; 203 } 204 case "-path": { 205 int argIndex = i + 1; 206 if (argIndex < args.length) { 207 ClistPath = args[argIndex]; 208 i++; 209 } else { 210 usage(); 211 throw new Error("TESTBUG: Improper Argument: " + args[i]); 212 } 213 break; 214 } 215 default: { 216 if (!arg.startsWith("-stress")) { 217 usage(); 218 throw new Error("TESTBUG: Invalid Argument: " + args[i]); 219 } 220 } 221 } 222 } 223 224 if ("".equals(ClistPath)) { 225 usage(); 226 throw new Error("TESTBUG: class list path not defined"); 227 } 228 } 229 usage()230 public void usage() { 231 System.out.println("usage: java CGT [options]"); 232 System.out.println(" -help prints out this message"); 233 System.out.println(" -numTestClass # limits the number of \"Test Methods\" to #"); 234 System.out.println(" -randomcLoop # # of random function calls"); 235 System.out.println(" -staticLoop # # of non-random static function calls"); 236 System.out.println(" -v -verbose turn on verbose mode"); 237 System.out.println(" -path <path to classlist> required, argument so program can find classes"); 238 } 239 } 240