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/CallSite.java
12520 views
1
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/
2
/*******************************************************************************
3
* Copyright (c) 2011, 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 static java.lang.invoke.MethodType.*;
26
27
/**
28
* CallSite is used by the invokedynamic bytecode to hold a reference to the MethodHandle target of the instruction.
29
* <p>
30
* Although CallSite is an abstract class, it cannot be directly sub-classed. Instead, it is necessary to sub-class
31
* one of the three implementation classes:
32
* <ul>
33
* <li>ConstantCallSite - if the target will never change</li>
34
* <li>VolatileCallSite - if the target is expected to frequently change. Changes will be immediately visible in all threads.</li>
35
* <li>MutableCallSite - if the target is expected to rarely change and threads may see previous values of the target for some time.</li>
36
* </ul>
37
*
38
* <p>
39
* CallSites are created with a MethodType and permanently bound to that type. Any changes to the target
40
* MethodHandle must be of the identical MethodType or a WrongMethodTypeException will be thrown.
41
*
42
* @since 1.7
43
*/
44
public abstract class CallSite {
45
private final MethodType type;
46
private static MethodHandle initialTargetHandleCache;
47
48
CallSite(MethodType type){
49
type.getClass(); // Throw NPE if null
50
this.type = type;
51
}
52
53
/**
54
* Report the type of CallSite's target MethodHandle.
55
* A CallSite cannot change its type.
56
* @return The permanent MethodType of this CallSite.
57
*/
58
public MethodType type() {
59
return type;
60
}
61
62
/**
63
* Return the target MethodHandle of the CallSite.
64
*
65
* @return the current target MethodHandle
66
*/
67
public abstract MethodHandle getTarget();
68
69
/**
70
* Set the CallSite's target to be <i>nextTarget</i>.
71
* The <i>nextTarget</i> MethodHandle must have the same type as the CallSite.
72
*
73
* @param nextTarget - the new target value for the CallSite
74
* @throws WrongMethodTypeException - if the type of <i>nextTarget</i> differs from that of the CallSite.
75
* @throws NullPointerException - if <i>nextTarget</i> is null.
76
*/
77
public abstract void setTarget(MethodHandle nextTarget) throws WrongMethodTypeException, NullPointerException;
78
79
/**
80
* Return a MethodHandle equivalent to the invokedynamic instruction on this CallSite.
81
* The MethodHandle is equivalent to getTarget().invokeExact(args).
82
*
83
* @return a MethodHandle that is equivalent to an invokedynamic instruction on this CallSite.
84
*/
85
public abstract MethodHandle dynamicInvoker();
86
87
88
/* Defer the creation of the Exception until called in the IllegalState */
89
static void throwIllegalStateException() throws IllegalStateException {
90
throw new IllegalStateException();
91
}
92
93
/* Return the initial target for the CallSite - it will throw an IllegalStateException. */
94
static MethodHandle initialTarget(MethodType type) {
95
MethodHandle initialTargetHandle = initialTargetHandleCache;
96
if (null == initialTargetHandle) {
97
initialTargetHandle = lookupInitialTarget();
98
}
99
initialTargetHandle = initialTargetHandle.asType(methodType(type.returnType()));
100
/* Adapt the initial target to be compliant with what the caller expects */
101
return MethodHandles.dropArguments(initialTargetHandle, 0, type.ptypes());
102
}
103
104
/* Initialize the cached MethodHandle for initialTarget */
105
private static MethodHandle lookupInitialTarget() {
106
try {
107
initialTargetHandleCache = MethodHandles.Lookup.internalPrivilegedLookup.findStatic(CallSite.class, "throwIllegalStateException", methodType(void.class)); //$NON-NLS-1$
108
} catch (IllegalAccessException | NoSuchMethodException e) {
109
throw new InternalError("Unable to lookup CallSite initial target"); //$NON-NLS-1$
110
}
111
return initialTargetHandleCache;
112
}
113
}
114
115
116