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 }