Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/ThrowExceptionsTest.java
47209 views
1
/*
2
* Copyright (c) 2011, 2013, 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
/* @test
25
* @summary unit tests for method handles which permute their arguments
26
* @run testng test.java.lang.invoke.ThrowExceptionsTest
27
*/
28
29
package test.java.lang.invoke;
30
31
import org.testng.*;
32
import org.testng.annotations.*;
33
34
import java.util.*;
35
import java.lang.reflect.*;
36
37
import java.lang.invoke.*;
38
import static java.lang.invoke.MethodHandles.*;
39
import static java.lang.invoke.MethodType.*;
40
41
public class ThrowExceptionsTest {
42
private static final Class<?> CLASS = ThrowExceptionsTest.class;
43
private static final Lookup LOOKUP = lookup();
44
45
public static void main(String argv[]) throws Throwable {
46
new ThrowExceptionsTest().testAll((argv.length == 0 ? null : Arrays.asList(argv).toString()));
47
}
48
49
@Test
50
public void testWMT() throws Throwable {
51
// mostly call testWMTCallee, but sometimes call its void-returning variant
52
MethodHandle mh = testWMTCallee();
53
MethodHandle mh1 = mh.asType(mh.type().changeReturnType(void.class));
54
assert(mh1 != mh);
55
testWMT(mh, mh1, 1000);
56
}
57
58
@Test
59
public void testBoundWMT() throws Throwable {
60
// mostly call exactInvoker.bindTo(testWMTCallee), but sometimes call its void-returning variant
61
MethodHandle callee = testWMTCallee();
62
MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));
63
MethodHandle invoker = exactInvoker(callee.type());
64
MethodHandle mh = invoker.bindTo(callee);
65
MethodHandle mh1 = invoker.bindTo(callee1);
66
testWMT(mh, mh1, 1000);
67
}
68
69
@Test
70
public void testFoldWMT() throws Throwable {
71
// mostly call exactInvoker.fold(constant(testWMTCallee)), but sometimes call its void-returning variant
72
MethodHandle callee = testWMTCallee();
73
MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));
74
MethodHandle invoker = exactInvoker(callee.type());
75
MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));
76
MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
77
testWMT(mh, mh1, 1000);
78
}
79
80
@Test
81
public void testFoldCCE() throws Throwable {
82
MethodHandle callee = testWMTCallee();
83
MethodHandle callee1 = callee.asType(callee.type().changeParameterType(1, Number.class)).asType(callee.type());
84
MethodHandle invoker = exactInvoker(callee.type());
85
MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));
86
MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
87
testWMT(mh, mh1, 1000);
88
}
89
90
@Test
91
public void testStackOverflow() throws Throwable {
92
MethodHandle callee = testWMTCallee();
93
MethodHandle callee1 = makeStackOverflow().asType(callee.type());
94
MethodHandle invoker = exactInvoker(callee.type());
95
MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));
96
MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
97
for (int i = 0; i < REPEAT; i++) {
98
try {
99
testWMT(mh, mh1, 1000);
100
} catch (StackOverflowError ex) {
101
// OK, try again
102
}
103
}
104
}
105
106
private static MethodHandle makeStackOverflow() {
107
MethodType cellType = methodType(void.class);
108
MethodHandle[] cell = { null }; // recursion point
109
MethodHandle getCell = insertArguments(arrayElementGetter(cell.getClass()), 0, cell, 0);
110
MethodHandle invokeCell = foldArguments(exactInvoker(cellType), getCell);
111
assert(invokeCell.type() == cellType);
112
cell[0] = invokeCell;
113
// make it conformable to any type:
114
invokeCell = dropArguments(invokeCell, 0, Object[].class).asVarargsCollector(Object[].class);
115
return invokeCell;
116
}
117
118
static int testCases;
119
120
private void testAll(String match) throws Throwable {
121
testCases = 0;
122
Lookup lookup = lookup();
123
for (Method m : CLASS.getDeclaredMethods()) {
124
String name = m.getName();
125
if (name.startsWith("test") &&
126
(match == null || match.contains(name.substring("test".length()))) &&
127
m.getParameterTypes().length == 0 &&
128
Modifier.isPublic(m.getModifiers()) &&
129
!Modifier.isStatic(m.getModifiers())) {
130
System.out.println("["+name+"]");
131
int tc = testCases;
132
try {
133
m.invoke(this);
134
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
135
System.out.println("*** "+ex);
136
ex.printStackTrace(System.out);
137
}
138
if (testCases == tc) testCases++;
139
}
140
}
141
if (testCases == 0) throw new RuntimeException("no test cases found");
142
System.out.println("ran a total of "+testCases+" test cases");
143
}
144
145
private static MethodHandle findStatic(String name) {
146
return findMethod(name, true);
147
}
148
private static MethodHandle findVirtual(String name) {
149
return findMethod(name, false);
150
}
151
private static MethodHandle findMethod(String name, boolean isStatic) {
152
MethodHandle mh = null;
153
for (Method m : CLASS.getDeclaredMethods()) {
154
if (m.getName().equals(name) &&
155
Modifier.isStatic(m.getModifiers()) == isStatic) {
156
if (mh != null)
157
throw new RuntimeException("duplicate methods: "+name);
158
try {
159
mh = LOOKUP.unreflect(m);
160
} catch (ReflectiveOperationException ex) {
161
throw new RuntimeException(ex);
162
}
163
}
164
}
165
if (mh == null)
166
throw new RuntimeException("no method: "+name);
167
return mh;
168
}
169
170
int testWMTCallee;
171
private int testWMTCallee(String x) {
172
return testWMTCallee++;
173
}
174
private static MethodHandle testWMTCallee() {
175
MethodHandle callee = findVirtual("testWMTCallee");
176
// FIXME: should not have to retype callee
177
callee = callee.asType(callee.type().changeParameterType(0, Object.class));
178
return callee;
179
}
180
181
private Exception testWMT(MethodHandle[] mhs, int reps) throws Throwable {
182
testCases += 1;
183
testWMTCallee = 0;
184
int catches = 0;
185
Exception savedEx = null;
186
for (int i = 0; i < reps; i++) {
187
MethodHandle mh = mhs[i % mhs.length];
188
int n;
189
try {
190
// FIXME: should not have to retype this
191
n = (int) mh.invokeExact((Object)this, "x");
192
assertEquals(n, i - catches);
193
// Using the exact type for this causes endless deopt due to
194
// 'non_cached_result' in SystemDictionary::find_method_handle_invoke.
195
// The problem is that the compiler thread needs to access a cached
196
// invoke method, but invoke methods are not cached if one of the
197
// component types is not on the BCP.
198
} catch (Exception ex) {
199
savedEx = ex;
200
catches++;
201
}
202
}
203
//VERBOSE: System.out.println("reps="+reps+" catches="+catches);
204
return savedEx;
205
}
206
207
private static final int REPEAT = Integer.getInteger(CLASS.getSimpleName()+".REPEAT", 10);
208
209
private Exception testWMT(MethodHandle mh, MethodHandle mh1, int reps) throws Throwable {
210
//VERBOSE: System.out.println("mh="+mh+" mh1="+mh1);
211
MethodHandle[] mhs = new MethodHandle[100];
212
Arrays.fill(mhs, mh);
213
int patch = mhs.length-1;
214
Exception savedEx = null;
215
for (int i = 0; i < REPEAT; i++) {
216
mhs[patch] = mh;
217
testWMT(mhs, 10000);
218
mhs[patch] = mh1;
219
savedEx = testWMT(mhs, reps);
220
}
221
return savedEx;
222
}
223
224
private static void assertEquals(Object x, Object y) {
225
if (x == y || x != null && x.equals(y)) return;
226
throw new RuntimeException(x+" != "+y);
227
}
228
}
229
230