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/ObjectReference/referringObjects/referringObjects001. 28 * VM Testbase keywords: [quick, jpda, jdi, feature_jdk6_jpda, vm6] 29 * VM Testbase readme: 30 * DESCRIPTION 31 * Test checks behaviour of ReferenceType.instances, VirtualMachine.instanceCounts, ObjectReference.referringObjects 32 * in cases when object is reacheable via following types of references: 33 * - strong 34 * - soft 35 * - weak 36 * - phantom 37 * - jni local 38 * - jni global 39 * - jni weak 40 * Test is executed for following sublcasses of ObjectReference: StringReference, ThreadReference, ClassLoaderReference, ArrayReference. 41 * The test scenario is following: 42 * - Debugger VM 43 * for refererence_type in <Strong, JNI_Local_Ref, JNI_Global_Ref, JNI_Weak_Ref, PhantomReference, SoftReference, WeakReference> 44 * do 45 * - initiate creation of referring objects of type 'refererence_type' 46 * - check the number of referrers and instances is correct 47 * - initiate deletion of some referreres(making them unreachable) 48 * - check the number of referrers and instances is correct 49 * done 50 * - Debugger VM 51 * create references of all possible types to single object, ObjectReference.referringObjects should return only 52 * referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference) 53 * 54 * @library /vmTestbase 55 * /test/lib 56 * @run driver jdk.test.lib.FileInstaller . . 57 * @build nsk.jdi.ObjectReference.referringObjects.referringObjects001.referringObjects001 58 * nsk.share.jdi.TestClass1 59 * @run main/othervm/native PropertyResolvingWrapper 60 * nsk.jdi.ObjectReference.referringObjects.referringObjects001.referringObjects001 61 * -verbose 62 * -arch=${os.family}-${os.simpleArch} 63 * -waittime=5 64 * -debugee.vmkind=java 65 * -transport.address=dynamic 66 * "-debugee.vmkeys=-Xmx128M ${test.vm.opts} ${test.java.opts}" 67 */ 68 69 package nsk.jdi.ObjectReference.referringObjects.referringObjects001; 70 71 import java.io.PrintStream; 72 import java.util.*; 73 74 import nsk.share.*; 75 import nsk.share.jdi.*; 76 77 78 import com.sun.jdi.*; 79 import nsk.share.jpda.AbstractDebuggeeTest; 80 81 public class referringObjects001 extends HeapwalkingDebugger { 82 83 public static void main(String argv[]) { 84 System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); 85 } 86 87 public static int run(String argv[], PrintStream out) { 88 return new referringObjects001().runIt(argv, out); 89 } 90 91 protected String debuggeeClassName() { 92 return nsk.share.jdi.HeapwalkingDebuggee.class.getName(); 93 } 94 95 // test given class with all references types 96 protected void testClass(String className) { 97 log.display("Test ObjectReference for class: " + className); 98 99 // force GC in debuggee VM to avoid collection of weak references during test execution 100 forceGC(); 101 102 for (String referrerType : ObjectInstancesManager.allReferenceTypes) { 103 testReferrerType(referrerType, className); 104 if (ObjectInstancesManager.isWeak(referrerType)) { 105 resetStatusIfGC(); 106 } 107 } 108 109 int createInstanceCount = 10; 110 List<ObjectReference> objectsToFilter = getObjectReferences(className, vm); 111 112 // create instances reachable via all types of references 113 pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_ALL_TYPE_REFERENCES + ":" + className + ":" + createInstanceCount); 114 115 if (!isDebuggeeReady()) 116 return; 117 118 // ObjectReference.referringObjects should include only supported types of references 119 checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, createInstanceCount, true, 120 HeapwalkingDebuggee.includedIntoReferrersCountTypes.size()); 121 122 for (int i = 0; i < ObjectInstancesManager.allReferenceTypes.size(); i++) { 123 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + 1); 124 125 if (!isDebuggeeReady()) 126 return; 127 } 128 } 129 130 131 protected void testReferrerType(String referrerType, String className) { 132 // can't check number of referrers for objects that was created in debugee VM 133 // before debugger command (for example primitive type arrays), so we should filter such objects 134 List<ObjectReference> objectsToFilter = HeapwalkingDebugger.getObjectReferences(className, vm); 135 136 boolean includedInReferrersCount = HeapwalkingDebuggee.isIncludedIntoReferrersCount(referrerType); 137 boolean includedInInstancesCount = HeapwalkingDebuggee.isIncludedIntoInstancesCount(referrerType); 138 139 int createInstanceCount = 4; 140 int referrerCount = 10; 141 142 // create 'createInstanceCount' instances with 'referrerCount' referrers 143 144 pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount + ":" + referrerCount + ":" 145 + referrerType); 146 147 int expectedInstanceCount; 148 149 if (includedInInstancesCount) 150 expectedInstanceCount = createInstanceCount; 151 else 152 expectedInstanceCount = 0; 153 154 checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter); 155 checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount); 156 157 // delete half of referrers 158 159 int deleteCount = referrerCount / 2; 160 161 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + deleteCount); 162 163 referrerCount -= deleteCount; 164 165 if (includedInInstancesCount) 166 expectedInstanceCount = createInstanceCount; 167 else 168 expectedInstanceCount = 0; 169 170 checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter); 171 checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount); 172 173 // delete half of instances 174 175 deleteCount = createInstanceCount / 2; 176 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + deleteCount); 177 178 createInstanceCount -= deleteCount; 179 180 if (includedInInstancesCount) 181 expectedInstanceCount = createInstanceCount; 182 else 183 expectedInstanceCount = 0; 184 185 checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter); 186 checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount); 187 188 // delete all referrers (make object unreachable) 189 190 deleteCount = referrerCount; 191 192 pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + deleteCount); 193 194 referrerCount = 0; 195 createInstanceCount = 0; 196 197 expectedInstanceCount = 0; 198 199 checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter); 200 checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount); 201 } 202 203 protected void checkDebugeeAnswer_instances_referringObjects(List<ObjectReference> objectsToFilter, String className, int expectedInstances, 204 boolean checkReferrers, int expectedReferrers) { 205 try { 206 ReferenceType referenceType = debuggee.classByName(className); 207 208 if (checkReferrers) { 209 List<ObjectReference> objectReferrences = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0)); 210 211 // used for non-strict check 212 int correctObjectsFound = 0; 213 214 for (ObjectReference objectReference : objectReferrences) { 215 int referrerCount = objectReference.referringObjects(0).size(); 216 217 if (strictCheck(className)) { 218 if (referrerCount != expectedReferrers) { 219 setSuccess(false); 220 log.complain("List with wrong size was returned by ObjectReference.referringObjects: " + referrerCount + ", expected: " 221 + expectedReferrers); 222 } 223 } else { 224 if (referrerCount == expectedReferrers) { 225 correctObjectsFound++; 226 } 227 } 228 } 229 230 if (!strictCheck(className)) { 231 if (correctObjectsFound != expectedInstances) { 232 setSuccess(false); 233 log.complain("List with wrong size was returned by ObjectReference.referringObjects, expected: " + expectedReferrers); 234 } 235 } 236 } 237 } catch (Throwable t) { 238 log.complain("Unexpected exception:"); 239 t.printStackTrace(log.getOutStream()); 240 } 241 } 242 243 protected void doTest() { 244 String[] testClassNames = { "java.lang.String", "nsk.share.jdi.TestClass1", "boolean[]", 245 "float[]" }; 246 247 for (String className : testClassNames) { 248 testClass(className); 249 } 250 } 251 }