1 /*
2  * Copyright (c) 2004, 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 package nsk.jvmti.scenarios.allocation.AP04;
25 
26 import java.io.*;
27 import java.lang.reflect.*;
28 
29 import nsk.share.*;
30 import nsk.share.jvmti.*;
31 
32 public class ap04t001 extends DebugeeClass {
33 
main(String[] argv)34     public static void main(String[] argv) {
35         argv = nsk.share.jvmti.JVMTITest.commonInit(argv);
36 
37         // produce JCK-like exit status
38         System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
39     }
40 
run(String argv[], PrintStream out)41     public static int run(String argv[], PrintStream out) {
42         return new ap04t001().runThis(argv, out);
43     }
44 
45     private static int OBJ_MAX_COUNT = 100000;
46     private static ap04t001[] root;
47     public static volatile boolean iterationCompleted = true;
48     public static volatile int cleanedCount = 0;
49     private static Wicket secondaryLock = null;
50 
setTag(Object target, long tag)51     private static native void setTag(Object target, long tag);
52 
runIterateOverHeap()53     public static native void runIterateOverHeap();
runIterateOverInstancesOfClass()54     public static native void runIterateOverInstancesOfClass();
runIterateOverReachableObjects()55     public static native void runIterateOverReachableObjects();
runIterateOverObjectsReachableFromObject()56     public static native void runIterateOverObjectsReachableFromObject();
57 
forceGC()58     public static native void forceGC();
59 
60     /* scaffold objects */
61     static ArgumentHandler argHandler = null;
62     static Log log = null;
63     static long timeout = 0;
64     int status = Consts.TEST_PASSED;
65 
runThis(String argv[], PrintStream out)66     private int runThis(String argv[], PrintStream out) {
67         argHandler = new ArgumentHandler(argv);
68         log = new Log(out, argHandler);
69         timeout = argHandler.getWaitTime() * 60 * 1000; // milliseconds
70 
71         status = checkStatus(status);
72 
73         try {
74             runCase("1", "thread1", new ap04t001HeapIterator(), false);
75             runCase("2", "thread2", new ap04t001AllReachachableObjectsIterator(), false);
76             runCase("3", "thread3", new ap04t001SomeReachachableObjectsIterator(), true);
77             runCase("4", "thread4", new ap04t001ClassIterator(), false);
78 
79         } catch (OutOfMemoryError e) {
80             log.display("Warning: OutOfMemoryError was thrown. Test exited");
81             System.exit(Consts.TEST_PASSED + Consts.JCK_STATUS_BASE);
82         }
83 
84         status = checkStatus(status);
85         return status;
86     }
87 
unlockSecondary()88     private static void unlockSecondary() {
89         if (secondaryLock != null)
90             secondaryLock.unlock();
91     }
92 
runCase( String caseName, String threadName, ap04t001Iterator iterator, boolean useSecondaryLock)93     private static void runCase ( String caseName,
94                            String threadName,
95                            ap04t001Iterator iterator,
96                            boolean useSecondaryLock) {
97 
98         log.display("CASE #" + caseName + ":");
99         log.display("Allocating objects...");
100         root = new ap04t001[OBJ_MAX_COUNT];
101         for (int i = 0; i < OBJ_MAX_COUNT; i++) {
102             root[i] = new ap04t001();
103             setTag(root[i], i + 1 );
104         }
105 
106         log.display("Start thread and making garbage collection");
107 
108         if (useSecondaryLock) secondaryLock = new Wicket();
109         ap04t001Thread thread = startThread( threadName, iterator);
110         if (useSecondaryLock) secondaryLock.waitFor();
111 
112         root = null;
113         forceGC();
114         log.display("All objects collected");
115 
116         log.display("Wait for thread to finish");
117         joinThread(thread);
118 
119         log.display("CASE #" + caseName + " finished.\n");
120     }
121 
122 
startThread(String name, ap04t001Iterator iterator)123     private static ap04t001Thread startThread(String name, ap04t001Iterator iterator) {
124         ap04t001Thread thread = new ap04t001Thread(name, new Wicket(), iterator);
125         thread.start();
126         thread.getStartLock().waitFor();
127         return thread;
128     }
129 
joinThread(Thread thread)130     private static void joinThread(Thread thread) {
131         if (thread.isAlive()) {
132             try {
133                 thread.join(timeout);
134             } catch (InterruptedException e) {
135                 throw new Failure(e);
136             }
137         }
138     }
139 }
140 
141 /**************************************************************************/
142 interface ap04t001Iterator {
runIteration()143     public void runIteration();
144 }
145 
146 class ap04t001HeapIterator implements ap04t001Iterator {
runIteration()147     public void runIteration() {
148         ap04t001.runIterateOverHeap();
149         ap04t001.iterationCompleted = true;
150     }
151 }
152 
153 class ap04t001ClassIterator implements ap04t001Iterator {
runIteration()154     public void runIteration() {
155         ap04t001.runIterateOverInstancesOfClass();
156         ap04t001.iterationCompleted = true;
157     }
158 }
159 
160 class ap04t001AllReachachableObjectsIterator implements ap04t001Iterator {
runIteration()161     public void runIteration() {
162         ap04t001.runIterateOverReachableObjects();
163         ap04t001.iterationCompleted = true;
164     }
165 }
166 
167 class ap04t001SomeReachachableObjectsIterator implements ap04t001Iterator {
runIteration()168     public void runIteration() {
169         ap04t001.runIterateOverObjectsReachableFromObject();
170         ap04t001.iterationCompleted = true;
171     }
172 }
173 
174 /**************************************************************************/
175 class ap04t001Thread extends Thread {
176     String name;
177     ap04t001Iterator iterator;
178     Wicket startLock;
179     Wicket endLock;
180 
ap04t001Thread( String name, Wicket startLock, ap04t001Iterator iterator )181     public ap04t001Thread( String name,
182                            Wicket startLock,
183                            ap04t001Iterator iterator ) {
184 
185         if (name == null || name.length() == 0) {
186             throw new Failure("Empty thread name.");
187         }
188         if (startLock == null) {
189             throw new Failure("startLock is null.");
190         }
191         if (iterator == null) {
192             throw new Failure("iterator is null.");
193         }
194 
195         this.name       = name;
196         this.startLock  = startLock;
197         this.iterator   = iterator;
198     }
199 
getStartLock()200     public Wicket getStartLock() {
201         return startLock;
202     }
203 
run()204     public void run() {
205         ap04t001.log.display(name + " started.");
206         ap04t001.iterationCompleted = false;
207         startLock.unlock();
208 
209         iterator.runIteration();
210         ap04t001.log.display(name + " finished.");
211     }
212 }
213