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 /** 25 * @test 26 * @bug 5024119 27 * @summary Add ReferenceType.getAllInstances () method to JDI. 28 * @author jjh 29 * 30 * @modules jdk.jdi 31 * @run build TestScaffold VMConnection TargetListener TargetAdapter 32 * @run compile -g InstancesTest.java 33 * @run driver InstancesTest 34 */ 35 36 /* 37 * To run this test do this: 38 * runregress -no InstancesTest <cmd line options> 39 * 40 * where <cmd line options> are the options to be used to 41 * launch the debuggee, with the classname prefixed with @@. 42 * For example, this would run java2d demo as the debuggee: 43 * runregress -no InstancesTest -classpath 44 * $jdkDir/demo/jfc/Java2D/Java2Demo.jar \ 45 * -client @@java2d.Java2Demo 46 * 47 * In this mode, the specified debuggee is launched in debug mode, 48 * the debugger waits 20 secs, and then connects to the debuggee, suspends 49 * it, and 'debugs' it. 50 * 51 * If <cmd line options> is not specified, then the InstancesTarg class below 52 * is run as the debuggee. 53 */ 54 import com.sun.jdi.*; 55 import com.sun.jdi.event.*; 56 import com.sun.jdi.request.*; 57 58 import java.util.*; 59 60 class InstancesFiller { 61 // This many instances of this are created. 62 static int FILLER_COUNT = 200000; 63 static InstancesFiller[] lotsAndLots = new InstancesFiller[ 64 InstancesFiller.FILLER_COUNT]; 65 int xx; 66 InstancesFiller(int p1) { 67 xx = p1; 68 } 69 } 70 71 class InstancesTarg { 72 // This many instances + 1 of this class are created. 73 static int TARG_COUNT = 1000; 74 static InstancesTarg theInstancesTarg; 75 static InstancesTarg[] allInstancesTargs; 76 77 // Each instance will point to the theInstancesTarg 78 InstancesTarg oneInstancesTarg; 79 80 public static void bkpt() { 81 } 82 83 public static void main(String[] args) { 84 System.out.println("Howdy!"); 85 for (int ii = 0; ii < InstancesFiller.lotsAndLots.length; ii++) { 86 InstancesFiller.lotsAndLots[ii] = new InstancesFiller(ii); 87 } 88 89 theInstancesTarg = new InstancesTarg(); 90 allInstancesTargs = new InstancesTarg[InstancesTarg.TARG_COUNT]; 91 for (int ii = 0; ii < InstancesTarg.TARG_COUNT; ii++) { 92 allInstancesTargs[ii] = new InstancesTarg(); 93 allInstancesTargs[ii].oneInstancesTarg = theInstancesTarg; 94 } 95 bkpt(); 96 97 System.out.println("Goodbye from InstancesTarg!"); 98 } 99 } 100 101 /********** test program **********/ 102 103 public class InstancesTest extends TestScaffold { 104 static String targetName = "InstancesTarg"; 105 ReferenceType targetClass; 106 ThreadReference mainThread; 107 108 InstancesTest(String args[]) { 109 super(args); 110 } 111 112 public static void main(String[] args) throws Exception { 113 /* 114 * If args contains @@xxxx, then that is the 115 * name of the class we are to run. 116 */ 117 for (int ii = 0; ii < args.length; ii ++) { 118 if (args[ii].startsWith("@@")) { 119 targetName = args[ii] = args[ii].substring(2); 120 break; 121 } 122 } 123 new InstancesTest(args).startTests(); 124 } 125 126 /* 127 * Used to sort a list of ReferenceTypes by 128 * instance count. 129 */ 130 class ToSort implements Comparable<ToSort> { 131 long count; 132 ReferenceType rt; 133 134 public ToSort(long count, ReferenceType rt) { 135 this.count = count; 136 this.rt = rt; 137 } 138 139 public int compareTo(ToSort obj) { 140 if (count < obj.count) return -1; 141 if (count == obj.count) return 0; 142 return 1; 143 } 144 } 145 146 protected void runTests() throws Exception { 147 /* 148 * Get to the top of main() 149 * to determine targetClass and mainThread 150 */ 151 int CUT_OFF = 1000; 152 BreakpointEvent bpe; 153 bpe = startToMain(targetName); 154 targetClass = bpe.location().declaringType(); 155 mainThread = bpe.thread(); 156 157 if (targetName.equals("InstancesTarg")) { 158 resumeTo("InstancesTarg", "bkpt", "()V"); 159 } else { 160 // Let debuggee run for awhile to get classes loaded 161 vm().resume(); 162 try { 163 System.err.println("Press <enter> to continue"); 164 System.in.read(); 165 System.err.println("running..."); 166 167 } catch(Exception e) { 168 } 169 vm().suspend(); 170 } 171 172 // Get all classes. 173 long start = System.currentTimeMillis(); 174 List<ReferenceType> allClasses = vm().allClasses(); 175 long end = System.currentTimeMillis(); 176 System.out.println( allClasses.size() + 177 " classes from vm.allClasses() took " + 178 (end - start) + " ms"); 179 180 long[] counts; 181 182 // Test for NPE 183 { 184 boolean pass = false; 185 try { 186 counts = vm().instanceCounts(null); 187 } catch (NullPointerException ee) { 188 pass = true; 189 } 190 if (!pass) { 191 failure("failure: NullPointerException not thrown on instanceCounts(null)"); 192 } 193 } 194 195 // Test for 0 length array 196 { 197 List<ReferenceType>someClasses = new ArrayList(2); 198 counts = vm().instanceCounts(someClasses); 199 if (counts.length != 0) { 200 failure("failure: instanceCounts with a zero length array fails: " + 201 counts.length); 202 } 203 } 204 205 // Test various values of maxInstances 206 if (targetClass.name().equals("InstancesTarg")) { 207 List<ObjectReference> noInstances = targetClass.instances(0); 208 if (noInstances.size() != InstancesTarg.TARG_COUNT + 1) { 209 failure("failure: instances(0): " + noInstances.size() + ", for " + targetClass); 210 } 211 noInstances = targetClass.instances(1); 212 if (noInstances.size() != 1) { 213 failure("failure: instances(1): " + noInstances.size() + ", for " + targetClass); 214 } 215 boolean pass = false; 216 try { 217 noInstances = targetClass.instances(-1); 218 } catch (IllegalArgumentException ee) { 219 pass = true; 220 } 221 if (!pass) { 222 failure("failure: instances(-1) did not get an exception"); 223 } 224 } 225 226 // Instance counts for all classes 227 start = System.currentTimeMillis(); 228 counts = vm().instanceCounts(allClasses); 229 end = System.currentTimeMillis(); 230 231 if (counts.length == 0) { 232 System.out.println("failure: No instances found"); 233 throw new Exception("InstancesTest: failed"); 234 } 235 236 // Create a list of ReferenceTypes sorted by instance count 237 int size = 0; 238 List<ToSort> sorted = new ArrayList(allClasses.size()); 239 for (int ii = 0; ii < allClasses.size(); ii++) { 240 System.out.println(counts[ii] + " " + allClasses.get(ii)); 241 size += counts[ii]; 242 ToSort tos = new ToSort(counts[ii], allClasses.get(ii)); 243 sorted.add(tos); 244 } 245 246 System.out.println("instance counts for " + counts.length + 247 " classes got " + size + " instances and took " + 248 (end - start) + " ms"); 249 250 251 boolean gotInstancesFiller = false; 252 boolean gotInstancesTarg = false; 253 254 Collections.sort(sorted); 255 for (int ii = sorted.size() - 1; ii >= 0 ; ii--) { 256 ToSort xxx = sorted.get(ii); 257 if (xxx.count <= CUT_OFF) { 258 break; 259 } 260 if (xxx.rt.name().equals("InstancesFiller") && 261 xxx.count == InstancesFiller.FILLER_COUNT) { 262 gotInstancesFiller = true; 263 } 264 if (xxx.rt.name().equals("InstancesTarg") && 265 xxx.count == InstancesTarg.TARG_COUNT + 1) { 266 gotInstancesTarg = true; 267 } 268 } 269 if (!gotInstancesFiller) { 270 failure("failure: Expected " + InstancesFiller.FILLER_COUNT + 271 " instances of InstancesFiller"); 272 } 273 if (!gotInstancesTarg) { 274 failure("failure: Expected " + (InstancesTarg.TARG_COUNT + 1) + 275 " instances of InstancesTarg"); 276 } 277 278 // Instances, one class at a time, in sorted order, printing each line 279 if (true) { 280 System.out.println("\nGetting instances for one class " + 281 "at a time (limited) in sorted order"); 282 List<ReferenceType> rtList = new ArrayList(1); 283 rtList.add(null); 284 long start1 = System.currentTimeMillis(); 285 size = 0; 286 long count = 0; 287 for (int ii = sorted.size() - 1; ii >= 0 ; ii--) { 288 ToSort xxx = sorted.get(ii); 289 if (xxx.count <= CUT_OFF) { 290 break; 291 } 292 rtList.set(0, xxx.rt); 293 start = System.currentTimeMillis(); 294 List<ObjectReference> oneInstances = xxx.rt.instances(19999999); 295 end = System.currentTimeMillis(); 296 size += oneInstances.size(); 297 count++; 298 System.out.println("Expected " + xxx.count + " instances, got " + 299 oneInstances.size() + 300 " instances for " + sorted.get(ii).rt + 301 " in " + (end - start) + " ms"); 302 303 if (xxx.rt.name().equals("InstancesFiller") && 304 oneInstances.size() != InstancesFiller.FILLER_COUNT) { 305 failure("failure: Expected " + InstancesFiller.FILLER_COUNT + 306 " instances of InstancesFiller"); 307 } 308 if (xxx.rt.name().equals("InstancesTarg") && 309 oneInstances.size() != InstancesTarg.TARG_COUNT + 1) { 310 failure("failure: Expected " + (InstancesTarg.TARG_COUNT + 1) + 311 " instances of InstancesTarg"); 312 } 313 314 } 315 316 end = System.currentTimeMillis(); 317 318 System.out.println(size + " instances via making one vm.instances" + 319 " call for each of " + count + 320 " classes took " + (end - start1) + " ms"); 321 System.out.println("Per class = " + 322 (end - start) / allClasses.size() + " ms"); 323 } 324 325 /* 326 * deal with results of test 327 * if anything has called failure("foo") testFailed will be true 328 */ 329 if (!testFailed) { 330 println("InstancesTest: passed"); 331 } else { 332 throw new Exception("InstancesTest: failed"); 333 } 334 } 335 }