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  * @library /vmTestbase
  45  *          /test/lib
  46  * @run driver jdk.test.lib.FileInstaller . .
  47  * @build nsk.jdi.ReferenceType.instances.instances003.instances003
  48  * @run main/othervm/native PropertyResolvingWrapper
  49  *      nsk.jdi.ReferenceType.instances.instances003.instances003
  50  *      -verbose
  51  *      -arch=${os.family}-${os.simpleArch}
  52  *      -waittime=5
  53  *      -debugee.vmkind=java
  54  *      -transport.address=dynamic
  55  *      "-debugee.vmkeys=-Xmx128M ${test.vm.opts} ${test.java.opts}"
  56  *      -testClassNames nsk.jdi.ReferenceType.instances.instances003.instances003$TestClassLoader:java.lang.String:java.lang.Thread
  57  */
  58 
  59 package nsk.jdi.ReferenceType.instances.instances003;
  60 
  61 import java.io.PrintStream;
  62 import java.util.*;
  63 
  64 import com.sun.jdi.ObjectReference;
  65 import com.sun.jdi.ReferenceType;
  66 
  67 import nsk.share.Consts;
  68 import nsk.share.ObjectInstancesManager;
  69 import nsk.share.TestBug;
  70 import nsk.share.jdi.HeapwalkingDebuggee;
  71 import nsk.share.jdi.HeapwalkingDebugger;
  72 import nsk.share.jpda.AbstractDebuggeeTest;
  73 
  74 public class instances003 extends HeapwalkingDebugger {
  75     // use subclass of java.lang.ClassLoader to be sure that there are no its instances in debuggee VM
  76     public static class TestClassLoader extends ClassLoader {
  77 
  78     }
  79 
  80     private String testClasses[];
  81 
  82     protected String[] doInit(String[] args, PrintStream out) {
  83         args = super.doInit(args, out);
  84 
  85         ArrayList<String> standardArgs = new ArrayList<String>();
  86 
  87         for (int i = 0; i < args.length; i++) {
  88             if (args[i].equals("-testClassNames") && (i < args.length - 1)) {
  89                 testClasses = args[i + 1].split(":");
  90 
  91                 i++;
  92             } else
  93                 standardArgs.add(args[i]);
  94         }
  95 
  96         if ((testClasses == null) || (testClasses.length == 0))
  97             throw new TestBug("Test class names was not specified, use test parameter '-testClassNames'");
  98 
  99         return standardArgs.toArray(new String[] {});
 100     }
 101 
 102     public static void main(String argv[]) {
 103         System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
 104     }
 105 
 106     public static int run(String argv[], PrintStream out) {
 107         return new instances003().runIt(argv, out);
 108     }
 109 
 110     protected String debuggeeClassName() {
 111         return nsk.share.jdi.HeapwalkingDebuggee.class.getName();
 112     }
 113 
 114     protected void testClass(String className, String referrerType) {
 115         final int createInstanceCount = 50;
 116         final int referrerCount = 1;
 117 
 118         List<ObjectReference> objectsToFilter = HeapwalkingDebugger.getObjectReferences(className, vm);
 119 
 120         // create 'createInstanceCount' instances of test class
 121 
 122         // create temporary strong references to prevent the weakly referred instances being GCed
 123         // during the time between creating them and disabling collection on them
 124         pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount +
 125             ":" + referrerCount + ":" + referrerType +
 126             (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE) ? "|" + ObjectInstancesManager.STRONG_REFERENCE : ""));
 127 
 128         // the instance counts should not be affected by creating multiple references
 129         checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter);
 130 
 131         ReferenceType referenceType = debuggee.classByName(className);
 132         List<ObjectReference> instances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0));
 133 
 134         for (ObjectReference or : instances) {
 135             or.disableCollection();
 136         }
 137 
 138         // remove the temporary strong references so the weak references can be properly tested
 139         if (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE)) {
 140             pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + referrerCount + ":" + ObjectInstancesManager.STRONG_REFERENCE);
 141             if (!isDebuggeeReady()) {
 142                 return;
 143             }
 144         }
 145 
 146         // prevent half of instances from GC, delete references and force GC
 147 
 148         int preventGCCount = createInstanceCount / 2;
 149 
 150         for (int i = 0; i < preventGCCount; i++) {
 151             instances.get(i).enableCollection();
 152         }
 153 
 154         pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + createInstanceCount);
 155 
 156         if (!isDebuggeeReady())
 157             return;
 158 
 159         pipe.println(AbstractDebuggeeTest.COMMAND_FORCE_GC);
 160 
 161         checkDebugeeAnswer_instanceCounts(className, createInstanceCount - preventGCCount, objectsToFilter);
 162 
 163         // enable garbage collection for all instances and force GC
 164 
 165         for (ObjectReference reference : referenceType.instances(0)) {
 166             reference.enableCollection();
 167         }
 168 
 169         pipe.println(AbstractDebuggeeTest.COMMAND_FORCE_GC);
 170 
 171         checkDebugeeAnswer_instanceCounts(className, 0, objectsToFilter);
 172     }
 173 
 174     protected void doTest() {
 175         for (String referenceType : HeapwalkingDebuggee.includedIntoInstancesCountTypes) {
 176             for (String className : testClasses)
 177                 testClass(className, referenceType);
 178         }
 179     }
 180 }