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