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/referringObjects002.
28  * VM Testbase keywords: [quick, jpda, jdi, feature_jdk6_jpda, vm6]
29  * VM Testbase readme:
30  * DESCRIPTION
31  *         Test check behaviour of ObjectReference.referringObjects, ObjectReference.disableCollection and
32  *         ObjectReference.enableCollection for ClassObjectReference
33  *      The test scenario is following:
34  *       - Debugger VM
35  *                 - initiate in target VM loading of test class:
36  *                 - Debugee VM
37  *                 - create several instances of loaded class
38  *                 - create references of all possible types to loaded class
39  *       - Debugger VM
40  *                 - check test class have correct number of referrers
41  *                 (class object referrers should include class instances and references with supported types: Strong, PhantomReference, SoftReference, WeakReference)
42  *       - Debugger VM
43  *                 - initiate in debuggee removing of class instances and class object references
44  *                 - check test class have correct number of referrers
45  *       - Debugger VM
46  *                 - prevent collection of class object using ObjectReference.disableCollection
47  *                 - initiate test class unloading in debugee VM
48  *                 - check class object was not collected
49  *                 - enable collection of class object using ObjectReference.enableCollection
50  *                 - check class object was collected
51  *
52  * @requires vm.opt.final.ClassUnloading
53  * @library /vmTestbase
54  *          /test/lib
55  * @run driver jdk.test.lib.FileInstaller . .
56  * @build nsk.jdi.ObjectReference.referringObjects.referringObjects002.referringObjects002
57  *        nsk.jdi.ObjectReference.referringObjects.referringObjects002.referringObjects002a
58  *        nsk.share.jdi.TestClass1
59  * @run main/othervm/native PropertyResolvingWrapper
60  *      nsk.jdi.ObjectReference.referringObjects.referringObjects002.referringObjects002
61  *      -verbose
62  *      -arch=${os.family}-${os.simpleArch}
63  *      -waittime=5
64  *      -debugee.vmkind=java
65  *      -transport.address=dynamic
66  *      "-debugee.vmkeys=-Xmx256M ${test.vm.opts} ${test.java.opts}"
67  *      -testClassPath ${test.class.path}
68  */
69 
70 package nsk.jdi.ObjectReference.referringObjects.referringObjects002;
71 
72 import java.io.PrintStream;
73 import com.sun.jdi.*;
74 import nsk.share.Consts;
75 import nsk.share.TestBug;
76 import nsk.share.jdi.HeapwalkingDebuggee;
77 import nsk.share.jdi.HeapwalkingDebugger;
78 
79 public class referringObjects002 extends HeapwalkingDebugger {
80 
main(String argv[])81     public static void main(String argv[]) {
82         System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
83     }
84 
run(String argv[], PrintStream out)85     public static int run(String argv[], PrintStream out) {
86         return new referringObjects002().runIt(argv, out);
87     }
88 
debuggeeClassName()89     protected String debuggeeClassName() {
90         if (classpath == null) {
91             throw new TestBug("Debugger requires 'testClassPath' parameter");
92         }
93 
94         return nsk.jdi.ObjectReference.referringObjects.referringObjects002.referringObjects002a.class.getName() +
95             " -testClassPath " + classpath;
96     }
97 
checkClassObjectReferrersCount(ClassObjectReference classObjectReference, int expectedCount)98     public void checkClassObjectReferrersCount(ClassObjectReference classObjectReference, int expectedCount) {
99         int referrersCount = classObjectReference.referringObjects(0).size();
100 
101         if (referrersCount != expectedCount) {
102             setSuccess(false);
103             log.complain("Unexpected size of ClassLoaderReference.referringObjects: " + referrersCount + ", expected: " + expectedCount);
104         }
105     }
106 
doTest()107     protected void doTest() {
108         String className = "nsk.share.jdi.TestClass1";
109 
110         int createInstances = 10;
111 
112         pipe.println(HeapwalkingDebuggee.COMMAND_LOAD_CLASS + ":" + className + ":" + createInstances);
113 
114         if (!isDebuggeeReady())
115             return;
116 
117         // each class instances has reference to class object +
118         // + 'includedIntoReferrersCountTypes.size()' referrers was additionally created
119         // +1 referrer is classloader
120         // +1 referrer is debugee class unloader
121         // +1 self-reference from this_class index
122         int expectedReferrersCount = createInstances + HeapwalkingDebuggee.includedIntoReferrersCountTypes.size() + 3;
123 
124         ClassObjectReference classObjectReference = debuggee.classByName(className).classObject();
125 
126         checkClassObjectReferrersCount(classObjectReference, expectedReferrersCount);
127 
128         pipe.println(referringObjects002a.COMMAND_DELETE_CLASS_OBJECT_REFERRERS);
129 
130         if (!isDebuggeeReady())
131             return;
132 
133         // Only this referrers should left:
134         // 1 referrer is classloader
135         // 1 referrer is debugee class unloader
136         // 1 self-reference from this_class index
137         expectedReferrersCount = 3;
138 
139         checkClassObjectReferrersCount(classObjectReference, expectedReferrersCount);
140 
141         // disable collection and try unload class object
142         classObjectReference.disableCollection();
143 
144         pipe.println(HeapwalkingDebuggee.COMMAND_UNLOAD_CLASS + ":" + className + ":" + HeapwalkingDebuggee.UNLOAD_RESULT_FALSE);
145 
146         if (!isDebuggeeReady())
147             return;
148 
149         try {
150             classObjectReference.referringObjects(0);
151         } catch (ObjectCollectedException e) {
152             setSuccess(false);
153             log.complain("Class object was collected after disableCollection");
154             return;
155         }
156 
157         // enable collection and try unload class object
158         classObjectReference.enableCollection();
159 
160         pipe.println(HeapwalkingDebuggee.COMMAND_UNLOAD_CLASS + ":" + className);
161 
162         if (!isDebuggeeReady())
163             return;
164 
165         try {
166             classObjectReference.referringObjects(0);
167         } catch (ObjectCollectedException expectedException) {
168             // expected exception
169             return;
170         }
171 
172         setSuccess(false);
173         log.complain("Class object was not collected after enableCollection");
174     }
175 }
176