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