1 /*
2  * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  *
22  */
23 
24 /* @test TestJNIGlobalRefs
25  * @summary Test JNI Global Refs with Shenandoah
26  * @key gc
27  * @requires vm.gc.Shenandoah & !vm.graal.enabled
28  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xlog:gc -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahVerify TestJNIGlobalRefs
29  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xlog:gc -XX:ShenandoahGCHeuristics=aggressive                       TestJNIGlobalRefs
30  */
31 
32 import java.util.Arrays;
33 import java.util.Random;
34 
35 public class TestJNIGlobalRefs {
36     static {
37         System.loadLibrary("TestJNIGlobalRefs");
38     }
39 
40     private static final int TIME_MSEC = 120000;
41     private static final int ARRAY_SIZE = 10000;
42 
makeGlobalRef(Object o)43     private static native void makeGlobalRef(Object o);
makeWeakGlobalRef(Object o)44     private static native void makeWeakGlobalRef(Object o);
readGlobalRef()45     private static native Object readGlobalRef();
readWeakGlobalRef()46     private static native Object readWeakGlobalRef();
47 
main(String[] args)48     public static void main(String[] args) throws Throwable {
49         seedGlobalRef();
50         seedWeakGlobalRef();
51         long start = System.currentTimeMillis();
52         long current = start;
53         while (current - start < TIME_MSEC) {
54             testGlobal();
55             testWeakGlobal();
56             Thread.sleep(1);
57             current = System.currentTimeMillis();
58         }
59     }
60 
seedGlobalRef()61     private static void seedGlobalRef() {
62         int[] a = new int[ARRAY_SIZE];
63         fillArray(a, 1337);
64         makeGlobalRef(a);
65     }
66 
seedWeakGlobalRef()67     private static void seedWeakGlobalRef() {
68         int[] a = new int[ARRAY_SIZE];
69         fillArray(a, 8080);
70         makeWeakGlobalRef(a);
71     }
72 
testGlobal()73     private static void testGlobal() {
74         int[] a = (int[]) readGlobalRef();
75         checkArray(a, 1337);
76     }
77 
testWeakGlobal()78     private static void testWeakGlobal() {
79         int[] a = (int[]) readWeakGlobalRef();
80         if (a != null) {
81             checkArray(a, 8080);
82         } else {
83             // weak reference is cleaned, recreate:
84             seedWeakGlobalRef();
85         }
86     }
87 
fillArray(int[] array, int seed)88     private static void fillArray(int[] array, int seed) {
89         Random r = new Random(seed);
90         for (int i = 0; i < ARRAY_SIZE; i++) {
91             array[i] = r.nextInt();
92         }
93     }
94 
checkArray(int[] array, int seed)95     private static void checkArray(int[] array, int seed) {
96         Random r = new Random(seed);
97         if (array.length != ARRAY_SIZE) {
98             throw new IllegalStateException("Illegal array length: " + array.length + ", but expected " + ARRAY_SIZE);
99         }
100         for (int i = 0; i < ARRAY_SIZE; i++) {
101             int actual = array[i];
102             int expected = r.nextInt();
103             if (actual != expected) {
104                 throw new IllegalStateException("Incorrect array data: " + actual + ", but expected " + expected);
105             }
106         }
107     }
108 }
109