Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/invoke/DirectHandle.java
12521 views
1
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/
2
/*******************************************************************************
3
* Copyright (c) 2009, 2020 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
22
*******************************************************************************/
23
package java.lang.invoke;
24
25
import java.lang.reflect.Method;
26
import java.lang.reflect.Modifier;
27
28
/* DirectHandle is a MethodHandle subclass used to call methods that have already
29
* been resolved down to an exact method address.
30
* <p>
31
* The exact method address is known in the following cases:
32
* <ul>
33
* <li> MethodHandles.lookup().findStatic </li>
34
* <li> MethodHandles.lookup().findSpecial </li>
35
* </ul>
36
* <p>
37
* The vmSlot will hold a J9Method address.
38
*/
39
class DirectHandle extends PrimitiveHandle {
40
final boolean isStatic;
41
final boolean originIsFindVirtual;
42
43
DirectHandle(Class<?> referenceClass, String methodName, MethodType type, byte kind, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
44
this(referenceClass, methodName, type, kind, specialCaller, false);
45
}
46
47
DirectHandle(Class<?> referenceClass, String methodName, MethodType type, byte kind, Class<?> specialCaller, boolean originIsFindVirtual) throws NoSuchMethodException, IllegalAccessException {
48
super(directMethodType(type, kind, specialCaller), referenceClass, methodName, kind, null);
49
assert (kind != KIND_SPECIAL) || (specialCaller != null);
50
this.specialCaller = specialCaller;
51
addHandleToClassCache();
52
this.defc = finishMethodInitialization(specialCaller, type);
53
/* Kind should have been changed from KIND_VIRTUAL in finishMethodInitialization */
54
assert (this.kind != KIND_VIRTUAL);
55
isStatic = Modifier.isStatic(rawModifiers);
56
this.originIsFindVirtual = originIsFindVirtual;
57
}
58
59
public DirectHandle(Method method, byte kind, Class<?> specialCaller) throws IllegalAccessException {
60
this(method, kind, specialCaller, false);
61
}
62
63
public DirectHandle(Method method, byte kind, Class<?> specialCaller, boolean originIsFindVirtual) throws IllegalAccessException {
64
super(directMethodType(MethodType.methodType(method.getReturnType(), method.getParameterTypes()), kind, specialCaller), method.getDeclaringClass(), method.getName(), kind, method.getModifiers(), null);
65
assert (kind != KIND_SPECIAL) || (specialCaller != null);
66
this.specialCaller = specialCaller;
67
addHandleToClassCache();
68
boolean succeed = setVMSlotAndRawModifiersFromMethod(this, referenceClass, method, this.kind, specialCaller);
69
if (!succeed) {
70
throw new IllegalAccessException();
71
}
72
isStatic = Modifier.isStatic(rawModifiers);
73
this.originIsFindVirtual = originIsFindVirtual;
74
}
75
76
/*
77
* Create a new DirectHandle from another DirectHandle.
78
* This is used by ReceiverBoundHandle
79
*/
80
DirectHandle(PrimitiveHandle other, byte kind) {
81
super(ReceiverBoundHandle.receiverBoundMethodType(other.type), other.referenceClass, other.name, kind, other.rawModifiers, null);
82
if (!(other instanceof DirectHandle)) {
83
throw new IllegalArgumentException();
84
}
85
this.specialCaller = other.specialCaller;
86
addHandleToClassCache();
87
this.vmSlot = other.vmSlot;
88
this.defc = other.defc;
89
isStatic = Modifier.isStatic(other.rawModifiers);
90
this.originIsFindVirtual = other.directHandleOriginatedInFindVirtual();
91
}
92
93
DirectHandle(DirectHandle originalHandle, MethodType newType) {
94
super(originalHandle, newType);
95
isStatic = originalHandle.isStatic;
96
this.originIsFindVirtual = originalHandle.originIsFindVirtual;
97
addHandleToClassCache();
98
// Reassigning the vmSlot because an HCR may have occurred since it was assigned in super()
99
this.vmSlot = originalHandle.vmSlot;
100
}
101
102
/*
103
* Determine the correct MethodType for the DirectHandle
104
* KIND_STATIC - unmodified
105
* KIND_SPECIAL - insert specialCaller as first parameter
106
*/
107
private static final MethodType directMethodType(MethodType existingType, byte kind, Class<?> specialCaller) {
108
if (kind == KIND_STATIC) {
109
return existingType;
110
}
111
return existingType.insertParameterTypes(0, specialCaller);
112
}
113
114
private void addHandleToClassCache() {
115
MethodHandleCache cache = MethodHandleCache.getCache(defc);
116
cache.addDirectHandle(this);
117
}
118
119
final void nullCheckIfRequired(Object receiver) throws NullPointerException {
120
if (!isStatic) {
121
receiver.getClass(); // Deliberate NPE
122
}
123
}
124
125
@Override
126
boolean canRevealDirect() {
127
return true;
128
}
129
130
@Override
131
boolean directHandleOriginatedInFindVirtual() {
132
return originIsFindVirtual;
133
}
134
135
// {{{ JIT support
136
private static final ThunkTable _thunkTable = new ThunkTable();
137
protected ThunkTable thunkTable(){ return _thunkTable; }
138
139
// ILGen macros
140
protected static native boolean isAlreadyCompiled(long j9method);
141
protected static native long compiledEntryPoint(long j9method);
142
143
protected static native void directCall_V(int argPlaceholder);
144
protected static native int directCall_I(int argPlaceholder);
145
protected static native long directCall_J(int argPlaceholder);
146
protected static native float directCall_F(int argPlaceholder);
147
protected static native double directCall_D(int argPlaceholder);
148
protected static native Object directCall_L(int argPlaceholder);
149
150
protected static native void directCall_V(Object receiver, int argPlaceholder);
151
protected static native int directCall_I(Object receiver, int argPlaceholder);
152
protected static native long directCall_J(Object receiver, int argPlaceholder);
153
protected static native float directCall_F(Object receiver, int argPlaceholder);
154
protected static native double directCall_D(Object receiver, int argPlaceholder);
155
protected static native Object directCall_L(Object receiver, int argPlaceholder);
156
157
@FrameIteratorSkip
158
private final void invokeExact_thunkArchetype_V(int argPlaceholder) {
159
initializeClassIfRequired();
160
if (ILGenMacros.isCustomThunk()) {
161
directCall_V(argPlaceholder);
162
} else if (isAlreadyCompiled(vmSlot)) {
163
ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), argPlaceholder);
164
} else {
165
ComputedCalls.dispatchJ9Method_V(vmSlot, argPlaceholder);
166
}
167
}
168
169
@FrameIteratorSkip
170
private final void invokeExact_thunkArchetype_V(Object receiver, int argPlaceholder) {
171
nullCheckIfRequired(receiver);
172
initializeClassIfRequired();
173
if (ILGenMacros.isCustomThunk()) {
174
directCall_V(receiver, argPlaceholder);
175
} else if (isAlreadyCompiled(vmSlot)) {
176
ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
177
} else {
178
ComputedCalls.dispatchJ9Method_V(vmSlot, receiver, argPlaceholder);
179
}
180
}
181
182
@FrameIteratorSkip
183
private final int invokeExact_thunkArchetype_I(int argPlaceholder) {
184
initializeClassIfRequired();
185
if (ILGenMacros.isCustomThunk()) {
186
return directCall_I(argPlaceholder);
187
} else if (isAlreadyCompiled(vmSlot)) {
188
return ComputedCalls.dispatchDirect_I(compiledEntryPoint(vmSlot), argPlaceholder);
189
} else {
190
return ComputedCalls.dispatchJ9Method_I(vmSlot, argPlaceholder);
191
}
192
}
193
194
@FrameIteratorSkip
195
private final int invokeExact_thunkArchetype_I(Object receiver, int argPlaceholder) {
196
nullCheckIfRequired(receiver);
197
initializeClassIfRequired();
198
if (ILGenMacros.isCustomThunk()) {
199
return directCall_I(receiver, argPlaceholder);
200
} else if (isAlreadyCompiled(vmSlot)) {
201
return ComputedCalls.dispatchDirect_I(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
202
} else {
203
return ComputedCalls.dispatchJ9Method_I(vmSlot, receiver, argPlaceholder);
204
}
205
}
206
207
@FrameIteratorSkip
208
private final long invokeExact_thunkArchetype_J(int argPlaceholder) {
209
initializeClassIfRequired();
210
if (ILGenMacros.isCustomThunk()) {
211
return directCall_J(argPlaceholder);
212
} else if (isAlreadyCompiled(vmSlot)) {
213
return ComputedCalls.dispatchDirect_J(compiledEntryPoint(vmSlot), argPlaceholder);
214
} else {
215
return ComputedCalls.dispatchJ9Method_J(vmSlot, argPlaceholder);
216
}
217
}
218
219
@FrameIteratorSkip
220
private final long invokeExact_thunkArchetype_J(Object receiver, int argPlaceholder) {
221
nullCheckIfRequired(receiver);
222
initializeClassIfRequired();
223
if (ILGenMacros.isCustomThunk()) {
224
return directCall_J(receiver, argPlaceholder);
225
} else if (isAlreadyCompiled(vmSlot)) {
226
return ComputedCalls.dispatchDirect_J(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
227
} else {
228
return ComputedCalls.dispatchJ9Method_J(vmSlot, receiver, argPlaceholder);
229
}
230
}
231
232
@FrameIteratorSkip
233
private final float invokeExact_thunkArchetype_F(int argPlaceholder) {
234
initializeClassIfRequired();
235
if (ILGenMacros.isCustomThunk()) {
236
return directCall_F(argPlaceholder);
237
} else if (isAlreadyCompiled(vmSlot)) {
238
return ComputedCalls.dispatchDirect_F(compiledEntryPoint(vmSlot), argPlaceholder);
239
} else {
240
return ComputedCalls.dispatchJ9Method_F(vmSlot, argPlaceholder);
241
}
242
}
243
244
@FrameIteratorSkip
245
private final float invokeExact_thunkArchetype_F(Object receiver, int argPlaceholder) {
246
nullCheckIfRequired(receiver);
247
initializeClassIfRequired();
248
if (ILGenMacros.isCustomThunk()) {
249
return directCall_F(receiver, argPlaceholder);
250
} else if (isAlreadyCompiled(vmSlot)) {
251
return ComputedCalls.dispatchDirect_F(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
252
} else {
253
return ComputedCalls.dispatchJ9Method_F(vmSlot, receiver, argPlaceholder);
254
}
255
}
256
257
@FrameIteratorSkip
258
private final double invokeExact_thunkArchetype_D(int argPlaceholder) {
259
initializeClassIfRequired();
260
if (ILGenMacros.isCustomThunk()) {
261
return directCall_D(argPlaceholder);
262
} else if (isAlreadyCompiled(vmSlot)) {
263
return ComputedCalls.dispatchDirect_D(compiledEntryPoint(vmSlot), argPlaceholder);
264
} else {
265
return ComputedCalls.dispatchJ9Method_D(vmSlot, argPlaceholder);
266
}
267
}
268
269
@FrameIteratorSkip
270
private final double invokeExact_thunkArchetype_D(Object receiver, int argPlaceholder) {
271
nullCheckIfRequired(receiver);
272
initializeClassIfRequired();
273
if (ILGenMacros.isCustomThunk()) {
274
return directCall_D(receiver, argPlaceholder);
275
} else if (isAlreadyCompiled(vmSlot)) {
276
return ComputedCalls.dispatchDirect_D(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
277
} else {
278
return ComputedCalls.dispatchJ9Method_D(vmSlot, receiver, argPlaceholder);
279
}
280
}
281
282
@FrameIteratorSkip
283
private final Object invokeExact_thunkArchetype_L(int argPlaceholder) {
284
initializeClassIfRequired();
285
if (ILGenMacros.isCustomThunk()) {
286
return directCall_L(argPlaceholder);
287
} else if (isAlreadyCompiled(vmSlot)) {
288
return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), argPlaceholder);
289
} else {
290
return ComputedCalls.dispatchJ9Method_L(vmSlot, argPlaceholder);
291
}
292
}
293
294
@FrameIteratorSkip
295
private final Object invokeExact_thunkArchetype_L(Object receiver, int argPlaceholder) {
296
nullCheckIfRequired(receiver);
297
initializeClassIfRequired();
298
if (ILGenMacros.isCustomThunk()) {
299
return directCall_L(receiver, argPlaceholder);
300
} else if (isAlreadyCompiled(vmSlot)) {
301
return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), receiver, argPlaceholder);
302
} else {
303
return ComputedCalls.dispatchJ9Method_L(vmSlot, receiver, argPlaceholder);
304
}
305
}
306
307
// }}} JIT support
308
309
@Override
310
MethodHandle cloneWithNewType(MethodType newType) {
311
return new DirectHandle(this, newType);
312
}
313
314
// Not final because it's overridden in ReceiverBoundHandle
315
void compareWith(MethodHandle right, Comparator c) {
316
if (right instanceof DirectHandle) {
317
((DirectHandle)right).compareWithDirect(this, c);
318
} else {
319
c.fail();
320
}
321
}
322
323
void compareWithDirect(DirectHandle left, Comparator c) {
324
c.compareStructuralParameter(left.vmSlot, this.vmSlot);
325
}
326
327
//Used by ConstructorHandle
328
//Making sure the DirectHandle class is loaded before ConstructorHandle is loaded. Therefore, to secure a correct thunk.
329
public static void load() {}
330
}
331
332
333