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/7087570/Test7087570.java
47311 views
1
/*
2
* Copyright (c) 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
25
/* @test
26
* @bug 7087570
27
* @summary REF_invokeSpecial DMHs (which are unusual) get marked explicitly; tweak the MHI to use this bit
28
*
29
* @run main Test7087570
30
*/
31
32
import java.lang.invoke.*;
33
import java.lang.reflect.*;
34
import java.util.*;
35
36
import static java.lang.invoke.MethodHandles.*;
37
import static java.lang.invoke.MethodType.*;
38
import static java.lang.invoke.MethodHandleInfo.*;
39
40
public class Test7087570 {
41
42
private static final TestMethodData[] TESTS = new TestMethodData[] {
43
// field accessors
44
data(DummyFieldHolder.class, "instanceField", getterMethodType(String.class), DummyFieldHolder.class, REF_getField),
45
data(DummyFieldHolder.class, "instanceField", setterMethodType(String.class), DummyFieldHolder.class, REF_putField),
46
data(DummyFieldHolder.class, "staticField", getterMethodType(Integer.class), DummyFieldHolder.class, REF_getStatic),
47
data(DummyFieldHolder.class, "staticField", setterMethodType(Integer.class), DummyFieldHolder.class, REF_putStatic),
48
data(DummyFieldHolder.class, "instanceByteField", getterMethodType(byte.class), DummyFieldHolder.class, REF_getField),
49
data(DummyFieldHolder.class, "instanceByteField", setterMethodType(byte.class), DummyFieldHolder.class, REF_putField),
50
51
// REF_invokeVirtual
52
data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeVirtual),
53
54
// REF_invokeVirtual strength-reduced to REF_invokeSpecial,
55
// test if it normalizes back to REF_invokeVirtual in MethodHandleInfo as expected
56
data(String.class, "hashCode", methodType(int.class), String.class, REF_invokeVirtual),
57
58
// REF_invokeStatic
59
data(Collections.class, "sort", methodType(void.class, List.class), Collections.class, REF_invokeStatic),
60
data(Arrays.class, "asList", methodType(List.class, Object[].class), Arrays.class, REF_invokeStatic), // varargs case
61
62
// REF_invokeSpecial
63
data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeSpecial),
64
65
// REF_newInvokeSpecial
66
data(String.class, "<init>", methodType(void.class, char[].class), String.class, REF_newInvokeSpecial),
67
data(DummyFieldHolder.class, "<init>", methodType(void.class, byte.class, Long[].class), DummyFieldHolder.class, REF_newInvokeSpecial), // varargs case
68
69
// REF_invokeInterface
70
data(List.class, "size", methodType(int.class), List.class, REF_invokeInterface)
71
};
72
73
public static void main(String... args) throws Throwable {
74
testWithLookup();
75
testWithUnreflect();
76
}
77
78
private static void doTest(MethodHandle mh, TestMethodData testMethod) {
79
MethodHandleInfo mhi = LOOKUP.revealDirect(mh);
80
81
System.out.printf("%s.%s: %s, nominal refKind: %s, actual refKind: %s\n",
82
testMethod.clazz.getName(), testMethod.name, testMethod.methodType,
83
referenceKindToString(testMethod.referenceKind),
84
referenceKindToString(mhi.getReferenceKind()));
85
assertEquals(testMethod.name, mhi.getName());
86
assertEquals(testMethod.methodType, mhi.getMethodType());
87
assertEquals(testMethod.declaringClass, mhi.getDeclaringClass());
88
assertEquals(testMethod.referenceKind == REF_invokeSpecial, isInvokeSpecial(mh));
89
assertRefKindEquals(testMethod.referenceKind, mhi.getReferenceKind());
90
}
91
92
private static void testWithLookup() throws Throwable {
93
for (TestMethodData testMethod : TESTS) {
94
MethodHandle mh = lookupFrom(testMethod);
95
doTest(mh, testMethod);
96
}
97
}
98
99
private static void testWithUnreflect() throws Throwable {
100
for (TestMethodData testMethod : TESTS) {
101
MethodHandle mh = unreflectFrom(testMethod);
102
doTest(mh, testMethod);
103
}
104
}
105
106
private static MethodType getterMethodType(Class<?> clazz) {
107
return methodType(clazz);
108
}
109
110
private static MethodType setterMethodType(Class<?> clazz) {
111
return methodType(void.class, clazz);
112
}
113
114
private static final Lookup LOOKUP = lookup();
115
116
private static class TestMethodData {
117
final Class<?> clazz;
118
final String name;
119
final MethodType methodType;
120
final Class<?> declaringClass;
121
final int referenceKind; // the nominal refKind
122
123
public TestMethodData(Class<?> clazz, String name,
124
MethodType methodType, Class<?> declaringClass,
125
int referenceKind) {
126
this.clazz = clazz;
127
this.name = name;
128
this.methodType = methodType;
129
this.declaringClass = declaringClass;
130
this.referenceKind = referenceKind;
131
}
132
}
133
134
private static TestMethodData data(Class<?> clazz, String name,
135
MethodType methodType, Class<?> declaringClass,
136
int referenceKind) {
137
return new TestMethodData(clazz, name, methodType, declaringClass, referenceKind);
138
}
139
140
private static MethodHandle lookupFrom(TestMethodData testMethod)
141
throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
142
switch (testMethod.referenceKind) {
143
case REF_getField:
144
return LOOKUP.findGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
145
case REF_putField:
146
return LOOKUP.findSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
147
case REF_getStatic:
148
return LOOKUP.findStaticGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
149
case REF_putStatic:
150
return LOOKUP.findStaticSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
151
case REF_invokeVirtual:
152
case REF_invokeInterface:
153
return LOOKUP.findVirtual(testMethod.clazz, testMethod.name, testMethod.methodType);
154
case REF_invokeStatic:
155
return LOOKUP.findStatic(testMethod.clazz, testMethod.name, testMethod.methodType);
156
case REF_invokeSpecial:
157
Class<?> thisClass = LOOKUP.lookupClass();
158
MethodHandle smh = LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass);
159
noteInvokeSpecial(smh);
160
return smh;
161
case REF_newInvokeSpecial:
162
return LOOKUP.findConstructor(testMethod.clazz, testMethod.methodType);
163
default:
164
throw new Error("ERROR: unexpected referenceKind in test data");
165
}
166
}
167
168
private static MethodHandle unreflectFrom(TestMethodData testMethod)
169
throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
170
switch (testMethod.referenceKind) {
171
case REF_getField:
172
case REF_getStatic: {
173
Field f = testMethod.clazz.getDeclaredField(testMethod.name);
174
return LOOKUP.unreflectGetter(f);
175
}
176
case REF_putField:
177
case REF_putStatic: {
178
Field f = testMethod.clazz.getDeclaredField(testMethod.name);
179
return LOOKUP.unreflectSetter(f);
180
}
181
case REF_invokeVirtual:
182
case REF_invokeStatic:
183
case REF_invokeInterface: {
184
Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
185
return LOOKUP.unreflect(m);
186
}
187
case REF_invokeSpecial: {
188
Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
189
Class<?> thisClass = LOOKUP.lookupClass();
190
MethodHandle smh = LOOKUP.unreflectSpecial(m, thisClass);
191
noteInvokeSpecial(smh);
192
return smh;
193
}
194
case REF_newInvokeSpecial: {
195
Constructor c = testMethod.clazz.getDeclaredConstructor(testMethod.methodType.parameterArray());
196
return LOOKUP.unreflectConstructor(c);
197
}
198
default:
199
throw new Error("ERROR: unexpected referenceKind in test data");
200
}
201
}
202
203
private static List<MethodHandle> specialMethodHandles = new ArrayList<>();
204
private static void noteInvokeSpecial(MethodHandle mh) {
205
specialMethodHandles.add(mh);
206
assert(isInvokeSpecial(mh));
207
}
208
private static boolean isInvokeSpecial(MethodHandle mh) {
209
return specialMethodHandles.contains(mh);
210
}
211
212
private static void assertRefKindEquals(int expect, int observed) {
213
if (expect == observed) return;
214
215
String msg = "expected " + referenceKindToString(expect) +
216
" but observed " + referenceKindToString(observed);
217
System.out.println("FAILED: " + msg);
218
throw new AssertionError(msg);
219
}
220
221
private static void assertEquals(Object expect, Object observed) {
222
if (java.util.Objects.equals(expect, observed)) return;
223
224
String msg = "expected " + expect + " but observed " + observed;
225
System.out.println("FAILED: " + msg);
226
throw new AssertionError(msg);
227
}
228
}
229
230
class DummyFieldHolder {
231
public static Integer staticField;
232
public String instanceField;
233
public byte instanceByteField;
234
235
public DummyFieldHolder(byte unused1, Long... unused2) {
236
}
237
}
238
239
240