1 /* 2 * Copyright (c) 2007, 2018, 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 * 27 * @summary converted from VM Testbase nsk/jdi/ReferenceType/instances/instances003. 28 * VM Testbase keywords: [jpda, jdi, feature_jdk6_jpda, vm6] 29 * VM Testbase readme: 30 * DESCRIPTION 31 * The test scenario is following: 32 * - Debugger VM 33 * for refererence_type in <Strong, JNI_Local_Ref, JNI_Global_Ref, JNI_Weak_Ref, PhantomReference, SoftReference, WeakReference> 34 * - initiate creation test class instances of type 'refererence_type' in debuggee VM 35 * - prevent some instances from being garbage collected using ObjectReference.disableCollection 36 * - initiate GarbageCollection in Debuggee VM 37 * - check the number of instances is left is correct 38 * - enables Garbage Collection for instances for which it were previously disabled using ObjectReference.enableCollection 39 * - initiate GarbageCollection in Debuggee VM 40 * - check the number of instances is 0 41 * done 42 * Test is executed for following sublcasses of ObjectReference: StringReference, ThreadReference, ClassLoaderReference 43 * 44 * @requires vm.gc != "Z" 45 * @library /vmTestbase 46 * /test/lib 47 * @run driver jdk.test.lib.FileInstaller . . 48 * @build nsk.jdi.ReferenceType.instances.instances003.instances003 49 * @run main/othervm/native PropertyResolvingWrapper 50 * nsk.jdi.ReferenceType.instances.instances003.instances003 51 * -verbose 52 * -arch=${os.family}-${os.simpleArch} 53 * -waittime=5 54 * -debugee.vmkind=java 55 * -transport.address=dynamic 56 * "-debugee.vmkeys=-Xmx128M ${test.vm.opts} ${test.java.opts}" 57 * -testClassNames nsk.jdi.ReferenceType.instances.instances003.instances003$TestClassLoader:java.lang.String:java.lang.Thread 58 */ 59 60 package nsk.jdi.ReferenceType.instances.instances003; 61 62 import java.io.PrintStream; 63 import java.util.*; 64 65 import com.sun.jdi.ObjectReference; 66 import com.sun.jdi.ReferenceType; 67 68 import nsk.share.Consts; 69 import nsk.share.ObjectInstancesManager; 70 import nsk.share.TestBug; 71 import nsk.share.jdi.HeapwalkingDebuggee; 72 import nsk.share.jdi.HeapwalkingDebugger; 73 import nsk.share.jpda.AbstractDebuggeeTest; 74 75 public class instances003 extends HeapwalkingDebugger { 76 // use subclass of java.lang.ClassLoader to be sure that there are no its instances in debuggee VM 77 public static class TestClassLoader extends ClassLoader { 78 79 } 80 81 private String testClasses[]; 82 83 protected String[] doInit(String[] args, PrintStream out) { 84 args = super.doInit(args, out); 85 86 ArrayList<String> standardArgs = new ArrayList<String>(); 87 88 for (int i = 0; i < args.length; i++) { 89 if (args[i].equals("-testClassNames") && (i < args.length - 1)) { 90 testClasses = args[i + 1].split(":"); 91 92 i++; 93 } else 94 standardArgs.add(args[i]); 95 } 96 97 if ((testClasses == null) || (testClasses.length == 0)) 98 throw new TestBug("Test class names was not specified, use test parameter '-testClassNames'"); 99 100 return standardArgs.toArray(new String[] {}); 101 } 102 103 public static void main(String argv[]) { 104 System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); 105 } 106 107 public static int run(String argv[], PrintStream out) { 108 return new instances003().runIt(argv, out); 109 } 110 111 protected String debuggeeClassName() { 112 return nsk.share.jdi.HeapwalkingDebuggee.class.getName(); 113 } 114 115 protected void testClass(String className, String referrerType) { 116 final int createInstanceCount = 50; 117 final int referrerCount = 1; 118 119 List<ObjectReference> objectsToFilter = HeapwalkingDebugger.getObjectReferences(className, vm); 120 121 // create 'createInstanceCount' instances of test class 122 123 // create temporary strong references to prevent the weakly referred instances being GCed 124 // during the time between creating them and disabling collection on them 125 pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount + 126 ":" + referrerCount + ":" + referrerType + 127 (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE) ? "|" + ObjectInstancesManager.STRONG_REFERENCE : "")); 128 129 // Note! This test is broken, in the sense that it incorrectly assumes 130 // that no GC can happen before it walks the heap. In practice, it seems 131 // to only affect this test when using ZGC. However, this test will also 132 // fail when using other GCs if an explicit GC is done here. 133 134 // the instance counts should not be affected by creating multiple references 135 checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter); 136 137 ReferenceType referenceType = debuggee.classByName(className); 138 List<ObjectReference> instances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0)); 139 140 for (ObjectReference or : instances) { 141 or.disableCollection(); 142 } 143 144 // remove the temporary strong references so the weak references can be properly tested 145 if (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE)) { 146 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + referrerCount + ":" + ObjectInstancesManager.STRONG_REFERENCE); 147 if (!isDebuggeeReady()) { 148 return; 149 } 150 } 151 152 // prevent half of instances from GC, delete references and force GC 153 154 int preventGCCount = createInstanceCount / 2; 155 156 for (int i = 0; i < preventGCCount; i++) { 157 instances.get(i).enableCollection(); 158 } 159 160 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + createInstanceCount); 161 162 if (!isDebuggeeReady()) 163 return; 164 165 pipe.println(AbstractDebuggeeTest.COMMAND_FORCE_GC); 166 167 checkDebugeeAnswer_instanceCounts(className, createInstanceCount - preventGCCount, objectsToFilter); 168 169 // enable garbage collection for all instances and force GC 170 171 for (ObjectReference reference : referenceType.instances(0)) { 172 reference.enableCollection(); 173 } 174 175 pipe.println(AbstractDebuggeeTest.COMMAND_FORCE_GC); 176 177 checkDebugeeAnswer_instanceCounts(className, 0, objectsToFilter); 178 } 179 180 protected void doTest() { 181 for (String referenceType : HeapwalkingDebuggee.includedIntoInstancesCountTypes) { 182 for (String className : testClasses) 183 testClass(className, referenceType); 184 } 185 } 186 }