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/IndirectHandle.java
12558 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
24
package java.lang.invoke;
25
26
import java.lang.reflect.Method;
27
import java.lang.reflect.Modifier;
28
29
import static java.lang.invoke.MethodHandleResolver.UNSAFE;
30
import static java.lang.invoke.MethodHandleResolver.getJ9ClassFromClass;
31
32
abstract class IndirectHandle extends PrimitiveHandle {
33
IndirectHandle(MethodType type, Class<?> referenceClass, String name, byte kind, int modifiers) {
34
super(type, referenceClass, name, kind, modifiers, null);
35
}
36
37
IndirectHandle(MethodType type, Class<?> referenceClass, String name, byte kind) {
38
super(type, referenceClass, name, kind, null);
39
}
40
41
IndirectHandle(IndirectHandle originalHandle, MethodType newType) {
42
super(originalHandle, newType);
43
}
44
45
// {{{ JIT support
46
protected abstract long vtableOffset(Object receiver);
47
protected final long vtableIndexArgument(Object receiver){ return - vtableOffset(receiver); }
48
49
protected final long jittedMethodAddress(Object receiver) {
50
long receiverClass = getJ9ClassFromClass(receiver.getClass());
51
long result;
52
if (VTABLE_ENTRY_SIZE == 4) {
53
result = UNSAFE.getInt(receiverClass - vtableOffset(receiver));
54
} else {
55
result = UNSAFE.getLong(receiverClass - vtableOffset(receiver));
56
}
57
return result;
58
}
59
60
@Override
61
boolean canRevealDirect() {
62
return true;
63
}
64
65
// }}} JIT support
66
67
protected static final MethodType indirectMethodType(Method method) {
68
MethodType originalType = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
69
return indirectMethodType(originalType, method.getDeclaringClass());
70
}
71
72
/* Indirect MethodHandles have the receiver type inserted as
73
* first argument of the MH's type.
74
*/
75
protected static final MethodType indirectMethodType(MethodType type, Class<?> referenceClazz) {
76
return type.insertParameterTypes(0, referenceClazz);
77
}
78
79
@Override
80
public MethodHandle bindTo(Object value) throws IllegalArgumentException, ClassCastException {
81
if (null == value) {
82
return super.bindTo(value);
83
}
84
85
/*
86
* Check whether the first parameter has a reference type assignable from value. Note that MethodType.parameterType(0) will
87
* throw an IllegalArgumentException if type has no parameters.
88
*/
89
Class<?> firstParameterType = type().parameterType(0);
90
if (firstParameterType.isPrimitive()) {
91
throw new IllegalArgumentException();
92
}
93
94
/*
95
* Ensure type compatibility.
96
*/
97
value = firstParameterType.cast(value);
98
99
/*
100
* Devirtualize virtual/interface handles.
101
*/
102
try {
103
MethodHandle result = MethodHandles.Lookup.internalPrivilegedLookup.bind(value, name, type().dropFirstParameterType());
104
105
/*
106
* An interface method must devirtualize to a public method. If the devirtualized method is not public,
107
* an IllegalAccessError will be thrown when the MethodHandle is invoked. In order to enforce this behaviour,
108
* we must preserve the original MethodHandle, i.e. not optimize to a ReceiverBoundHandle.
109
*/
110
if (this instanceof InterfaceHandle) {
111
if ((result.getModifiers() & Modifier.PUBLIC) == 0) {
112
throw new IllegalAccessException();
113
}
114
}
115
116
return result;
117
} catch (IllegalAccessException e) {
118
/*
119
* Create a receiver bound MethodHandle by inserting the receiver object as an argument. This is done to
120
* ensure that invocation is done using the original MethodHandle, which will result in an IllegalAccessError.
121
*/
122
return MethodHandles.insertArguments(this, 0, value);
123
} catch (NoSuchMethodException e) {
124
throw new Error(e);
125
}
126
}
127
128
final void compareWithIndirect(IndirectHandle left, Comparator c) {
129
c.compareStructuralParameter(left.referenceClass, this.referenceClass);
130
c.compareStructuralParameter(left.vmSlot, this.vmSlot);
131
}
132
}
133
134
135