author | jrose |
Fri, 18 Jun 2010 15:23:57 -0700 | |
changeset 5725 | 16c1792b2ee6 |
parent 5506 | 202f599c92aa |
parent 5722 | 4ada807383c8 |
child 7051 | 1c545d70a157 |
permissions | -rw-r--r-- |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1 |
/* |
5725 | 2 |
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
4 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
10 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
15 |
* accompanied this code). |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
16 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
20 |
* |
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
24 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
25 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
26 |
package java.dyn; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
27 |
|
4537 | 28 |
import sun.dyn.Access; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
29 |
import sun.dyn.MemberName; |
4537 | 30 |
import sun.dyn.CallSiteImpl; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
31 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
32 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
33 |
* A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
34 |
* and controls its linkage. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
35 |
* Every linked {@code CallSite} object corresponds to a distinct instance |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
36 |
* of the {@code invokedynamic} instruction, and vice versa. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
37 |
* <p> |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
38 |
* Every linked {@code CallSite} object has one state variable, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
39 |
* a {@link MethodHandle} reference called the {@code target}. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
40 |
* This reference is never null. Though it can change its value |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
41 |
* successive values must always have exactly the {@link MethodType method type} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
42 |
* called for by the bytecodes of the associated {@code invokedynamic} instruction |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
43 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
44 |
* It is the responsibility of each class's |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
45 |
* {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
46 |
* to produce call sites which have been pre-linked to an initial target method. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
47 |
* The required {@link MethodType type} for the target method is a parameter |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
48 |
* to each bootstrap method call. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
49 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
50 |
* The bootstrap method may elect to produce call sites of a |
2763 | 51 |
* language-specific subclass of {@code CallSite}. In such a case, |
52 |
* the subclass may claim responsibility for initializing its target to |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
53 |
* a non-null value, by overriding {@link #initialTarget}. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
54 |
* <p> |
2763 | 55 |
* An {@code invokedynamic} instruction which has not yet been executed |
56 |
* is said to be <em>unlinked</em>. When an unlinked call site is executed, |
|
57 |
* the containing class's bootstrap method is called to manufacture a call site, |
|
58 |
* for the instruction. If the bootstrap method does not assign a non-null |
|
59 |
* value to the new call site's target variable, the method {@link #initialTarget} |
|
60 |
* is called to produce the new call site's first target method. |
|
61 |
* <p> |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
62 |
* A freshly-created {@code CallSite} object is not yet in a linked state. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
63 |
* An unlinked {@code CallSite} object reports null for its {@code callerClass}. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
64 |
* When the JVM receives a {@code CallSite} object from a bootstrap method, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
65 |
* it first ensures that its target is non-null and of the correct type. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
66 |
* The JVM then links the {@code CallSite} object to the call site instruction, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
67 |
* enabling the {@code callerClass} to return the class in which the instruction occurs. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
68 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
69 |
* Next, the JVM links the instruction to the {@code CallSite}, at which point |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
70 |
* any further execution of the {@code invokedynamic} instruction implicitly |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
71 |
* invokes the current target of the {@code CallSite} object. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
72 |
* After this two-way linkage, both the instruction and the {@code CallSite} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
73 |
* object are said to be linked. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
74 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
75 |
* This state of linkage continues until the method containing the |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
76 |
* dynamic call site is garbage collected, or the dynamic call site |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
77 |
* is invalidated by an explicit request. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
78 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
79 |
* Linkage happens once in the lifetime of any given {@code CallSite} object. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
80 |
* Because of call site invalidation, this linkage can be repeated for |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
81 |
* a single {@code invokedynamic} instruction, with multiple {@code CallSite} objects. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
82 |
* When a {@code CallSite} is unlinked from an {@code invokedynamic} instruction, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
83 |
* the instruction is reset so that it is no longer associated with |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
84 |
* the {@code CallSite} object, but the {@code CallSite} does not change |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
85 |
* state. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
86 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
87 |
* Here is a sample use of call sites and bootstrap methods which links every |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
88 |
* dynamic call site to print its arguments: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
89 |
<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java --> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
90 |
private static void printArgs(Object... args) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
91 |
System.out.println(java.util.Arrays.deepToString(args)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
92 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
93 |
private static final MethodHandle printArgs; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
94 |
static { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
95 |
MethodHandles.Lookup lookup = MethodHandles.lookup(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
96 |
Class thisClass = lookup.lookupClass(); // (who am I?) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
97 |
printArgs = lookup.findStatic(thisClass, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
98 |
"printArgs", MethodType.methodType(void.class, Object[].class)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
99 |
Linkage.registerBootstrapMethod("bootstrapDynamic"); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
100 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
101 |
private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
102 |
// ignore caller and name, but match the type: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
103 |
return new CallSite(MethodHandles.collectArguments(printArgs, type)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
104 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
105 |
</pre></blockquote> |
2763 | 106 |
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle) |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
107 |
* @author John Rose, JSR 292 EG |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
108 |
*/ |
4537 | 109 |
public class CallSite |
110 |
{ |
|
111 |
private static final Access IMPL_TOKEN = Access.getToken(); |
|
112 |
||
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
113 |
// Fields used only by the JVM. Do not use or change. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
114 |
private MemberName vmmethod; // supplied by the JVM (ref. to calling method) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
115 |
private int vmindex; // supplied by the JVM (BCI within calling method) |
4537 | 116 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
117 |
// The actual payload of this call site: |
4537 | 118 |
private MethodHandle target; |
119 |
||
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
120 |
// Remove this field for PFD and delete deprecated methods: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
121 |
private MemberName calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
122 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
123 |
/** |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
124 |
* Make a blank call site object. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
125 |
* Before it is returned from a bootstrap method, this {@code CallSite} object |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
126 |
* must be provided with |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
127 |
* a target method via a call to {@link CallSite#setTarget(MethodHandle) setTarget}, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
128 |
* or by a subclass override of {@link CallSite#initialTarget(Class,String,MethodType) initialTarget}. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
129 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
130 |
public CallSite() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
131 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
132 |
|
2763 | 133 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
134 |
* Make a blank call site object, possibly equipped with an initial target method handle. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
135 |
* The initial target reference may be null, in which case the {@code CallSite} object |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
136 |
* must be provided with a target method via a call to {@link CallSite#setTarget}, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
137 |
* or by a subclass override of {@link CallSite#initialTarget}. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
138 |
* @param target the method handle which will be the initial target of the call site, or null if there is none yet |
2763 | 139 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
140 |
public CallSite(MethodHandle target) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
141 |
this.target = target; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
142 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
143 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
144 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
145 |
public CallSite(Class<?> caller, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
146 |
this.calleeNameRemoveForPFD = new MemberName(caller, name, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
147 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
148 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
149 |
public Class<?> callerClass() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
150 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
151 |
return callee == null ? null : callee.getDeclaringClass(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
152 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
153 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
154 |
public String name() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
155 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
156 |
return callee == null ? null : callee.getName(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
157 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
158 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
159 |
public MethodType type() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
160 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
161 |
return callee == null ? (target == null ? null : target.type()) : callee.getMethodType(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
162 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
163 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
164 |
protected MethodHandle initialTarget() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
165 |
return initialTarget(callerClass(), name(), type()); |
4537 | 166 |
} |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
167 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
168 |
/** Report if the JVM has linked this {@code CallSite} object to a dynamic call site instruction. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
169 |
* Once it is linked, it is never unlinked. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
170 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
171 |
private boolean isLinked() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
172 |
return vmmethod != null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
173 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
174 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
175 |
/** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
176 |
* The parameters are JVM-specific. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
177 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
178 |
void initializeFromJVM(String name, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
179 |
MethodType type, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
180 |
MemberName callerMethod, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
181 |
int callerBCI) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
182 |
if (this.isLinked()) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
183 |
throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction"); |
4537 | 184 |
} |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
185 |
MethodHandle target = this.target; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
186 |
if (target == null) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
187 |
this.target = target = this.initialTarget(callerMethod.getDeclaringClass(), name, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
188 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
189 |
if (!target.type().equals(type)) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
190 |
throw wrongTargetType(target, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
191 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
192 |
this.vmindex = callerBCI; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
193 |
this.vmmethod = callerMethod; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
194 |
assert(this.isLinked()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
195 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
196 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
197 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
198 |
* Just after a call site is created by a bootstrap method handle, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
199 |
* if the target has not been initialized by the factory method itself, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
200 |
* the method {@code initialTarget} is called to produce an initial |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
201 |
* non-null target. (Live call sites must never have null targets.) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
202 |
* <p> |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
203 |
* The arguments are the same as those passed to the bootstrap method. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
204 |
* Thus, a bootstrap method is free to ignore the arguments and simply |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
205 |
* create a "blank" {@code CallSite} object of an appropriate subclass. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
206 |
* <p> |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
207 |
* If the bootstrap method itself does not initialize the call site, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
208 |
* this method must be overridden, because it just raises an |
2763 | 209 |
* {@code InvokeDynamicBootstrapError}, which in turn causes the |
210 |
* linkage of the {@code invokedynamic} instruction to terminate |
|
211 |
* abnormally. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
212 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
213 |
protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
214 |
throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
215 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
216 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
217 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
218 |
* Report the current linkage state of the call site. (This is mutable.) |
4537 | 219 |
* The value may not be null after the {@code CallSite} object is returned |
220 |
* from the bootstrap method of the {@code invokedynamic} instruction. |
|
221 |
* When an {@code invokedynamic} instruction is executed, the target method |
|
222 |
* of its associated {@code call site} object is invoked directly, |
|
223 |
* as if via {@link MethodHandle}{@code .invoke}. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
224 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
225 |
* The interactions of {@code getTarget} with memory are the same |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
226 |
* as of a read from an ordinary variable, such as an array element or a |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
227 |
* non-volatile, non-final field. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
228 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
229 |
* In particular, the current thread may choose to reuse the result |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
230 |
* of a previous read of the target from memory, and may fail to see |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
231 |
* a recent update to the target by another thread. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
232 |
* @return the current linkage state of the call site |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
233 |
* @see #setTarget |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
234 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
235 |
public MethodHandle getTarget() { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
236 |
return target; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
237 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
238 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
239 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
240 |
* Set the target method of this call site. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
241 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
242 |
* The interactions of {@code setTarget} with memory are the same |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
243 |
* as of a write to an ordinary variable, such as an array element or a |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
244 |
* non-volatile, non-final field. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
245 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
246 |
* In particular, unrelated threads may fail to see the updated target |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
247 |
* until they perform a read from memory. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
248 |
* Stronger guarantees can be created by putting appropriate operations |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
249 |
* into the bootstrap method and/or the target methods used |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
250 |
* at any given call site. |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
251 |
* @param newTarget the new target |
2763 | 252 |
* @throws NullPointerException if the proposed new target is null |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
253 |
* @throws WrongMethodTypeException if the call site is linked and the proposed new target |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
254 |
* has a method type that differs from the previous target |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
255 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
256 |
public void setTarget(MethodHandle newTarget) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
257 |
MethodType newType = newTarget.type(); // null check! |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
258 |
MethodHandle oldTarget = this.target; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
259 |
if (oldTarget == null) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
260 |
// CallSite is not yet linked. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
261 |
assert(!isLinked()); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
262 |
this.target = newTarget; // might be null! |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
263 |
return; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
264 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
265 |
MethodType oldType = oldTarget.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
266 |
if (!newTarget.type().equals(oldType)) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
267 |
throw wrongTargetType(newTarget, oldType); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
268 |
if (oldTarget != newTarget) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
269 |
CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
270 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
271 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
272 |
private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
273 |
return new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
274 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
275 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
276 |
/** Produce a printed representation that displays information about this call site |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
277 |
* that may be useful to the human reader. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
278 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
279 |
@Override |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
280 |
public String toString() { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
281 |
StringBuilder buf = new StringBuilder("CallSite#"); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
282 |
buf.append(hashCode()); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
283 |
if (!isLinked()) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
284 |
buf.append("[unlinked]"); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
285 |
else |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
286 |
buf.append("[") |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
287 |
.append("from ").append(vmmethod.getDeclaringClass().getName()) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
288 |
.append(" : ").append(getTarget().type()) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
289 |
.append(" => ").append(getTarget()) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
290 |
.append("]"); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
291 |
return buf.toString(); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
292 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
293 |
} |