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