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 ap04t003 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 ap04t003().runThis(argv, out);
43     }
44 
45     private static int OBJ_MAX_COUNT = 100000;
46     private static ap04t003[] root;
47     private static int modified;
48     public  static volatile boolean iterationCompleted = true;
49 
setTag(Object target, long tag)50     private static native void setTag(Object target, long tag);
51 
runIterateOverHeap()52     public static native void runIterateOverHeap();
runIterateOverInstancesOfClass()53     public static native void runIterateOverInstancesOfClass();
runIterateOverReachableObjects()54     public static native void runIterateOverReachableObjects();
runIterateOverObjectsReachableFromObject()55     public static native void runIterateOverObjectsReachableFromObject();
56 
57     /* scaffold objects */
58     static ArgumentHandler argHandler = null;
59     static Log log = null;
60     static long timeout = 0;
61     int status = Consts.TEST_PASSED;
62 
runThis(String argv[], PrintStream out)63     private int runThis(String argv[], PrintStream out) {
64         argHandler = new ArgumentHandler(argv);
65         log = new Log(out, argHandler);
66         timeout = argHandler.getWaitTime() * 60 * 1000; // milliseconds
67 
68         status = checkStatus(status);
69 
70         try {
71             runCase("1", "thread1", new ap04t003HeapIterator());
72             runCase("2", "thread2", new ap04t003AllReachachableObjectsIterator());
73             runCase("3", "thread3", new ap04t003SomeReachachableObjectsIterator());
74             runCase("4", "thread4", new ap04t003ClassIterator());
75 
76         } catch (OutOfMemoryError e) {
77             log.display("Warning: OutOfMemoryError was thrown. Test exited");
78             System.exit(Consts.TEST_PASSED + Consts.JCK_STATUS_BASE);
79         }
80 
81         status = checkStatus(status);
82         return status;
83     }
84 
runCase( String caseName, String threadName, ap04t003Iterator iterator )85     private void runCase ( String caseName,
86                            String threadName,
87                            ap04t003Iterator iterator ) {
88 
89         log.display("CASE #" + caseName + ":");
90         log.display("Allocating objects...");
91         root = new ap04t003[OBJ_MAX_COUNT];
92         for (int i = 0; i < OBJ_MAX_COUNT; i++) {
93             root[i] = new ap04t003();
94             setTag(root[i], 1);
95         }
96 
97         log.display("Start heap iteration thread");
98         ap04t003Thread thread = startThread( threadName, iterator);
99 
100         log.display("Wait for thread to finish");
101         joinThread(thread);
102         log.display("Cleaning tags and references to objects...");
103         for (int i = 0; i < OBJ_MAX_COUNT; i++) {
104             if (root[i] != null) {
105                 setTag(root[i], 0);
106             }
107             root[i] = null;
108         }
109         System.gc();
110 
111         log.display("CASE #" + caseName + " finished.\n");
112     }
113 
114 
startThread(String name, ap04t003Iterator iterator)115     private static ap04t003Thread startThread(String name, ap04t003Iterator iterator) {
116         ap04t003Thread thread = new ap04t003Thread(name, new Wicket(), iterator);
117         thread.start();
118         thread.getStartLock().waitFor();
119         return thread;
120     }
121 
joinThread(Thread thread)122     private static void joinThread(Thread thread) {
123         if (thread.isAlive()) {
124             try {
125                 thread.join(timeout);
126             } catch (InterruptedException e) {
127                 throw new Failure(e);
128             }
129         }
130     }
131 }
132 
133 /**************************************************************************/
134 interface ap04t003Iterator {
runIteration()135     public void runIteration();
136 }
137 
138 class ap04t003HeapIterator implements ap04t003Iterator {
runIteration()139     public void runIteration() {
140         ap04t003.runIterateOverHeap();
141         ap04t003.iterationCompleted = true;
142     }
143 }
144 
145 class ap04t003ClassIterator implements ap04t003Iterator {
runIteration()146     public void runIteration() {
147         ap04t003.runIterateOverInstancesOfClass();
148         ap04t003.iterationCompleted = true;
149     }
150 }
151 
152 class ap04t003AllReachachableObjectsIterator implements ap04t003Iterator {
runIteration()153     public void runIteration() {
154         ap04t003.runIterateOverReachableObjects();
155         ap04t003.iterationCompleted = true;
156     }
157 }
158 
159 class ap04t003SomeReachachableObjectsIterator implements ap04t003Iterator {
runIteration()160     public void runIteration() {
161         ap04t003.runIterateOverObjectsReachableFromObject();
162         ap04t003.iterationCompleted = true;
163     }
164 }
165 
166 /**************************************************************************/
167 class ap04t003Thread extends Thread {
168     String name;
169     ap04t003Iterator iterator;
170     Wicket startLock;
171     Wicket endLock;
172 
ap04t003Thread( String name, Wicket startLock, ap04t003Iterator iterator )173     public ap04t003Thread( String name,
174                            Wicket startLock,
175                            ap04t003Iterator iterator ) {
176 
177         if (name == null || name.length() == 0) {
178             throw new Failure("Empty thread name.");
179         }
180         if (startLock == null) {
181             throw new Failure("startLock is null.");
182         }
183         if (iterator == null) {
184             throw new Failure("iterator is null.");
185         }
186 
187         this.name       = name;
188         this.startLock  = startLock;
189         this.iterator   = iterator;
190     }
191 
getStartLock()192     public Wicket getStartLock() {
193         return startLock;
194     }
195 
run()196     public void run() {
197         ap04t003.log.display(name + " started.");
198         ap04t003.iterationCompleted = false;
199         startLock.unlock();
200 
201         iterator.runIteration();
202         ap04t003.log.display(name + " finished.");
203     }
204 }
205