author | jrose |
Wed, 08 Sep 2010 18:40:23 -0700 | |
changeset 7052 | 963a5baf2ba3 |
parent 7051 | 1c545d70a157 |
child 7555 | a279ebc3b25c |
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 |
|
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
28 |
import sun.dyn.*; |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
29 |
import java.util.Collection; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
30 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
31 |
/** |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
32 |
* A {@code CallSite} is a holder for a variable {@link MethodHandle}, |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
33 |
* which is called its {@code target}. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
34 |
* Every call to a {@code CallSite} is delegated to the site's current target. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
35 |
* <p> |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
36 |
* A call site is initially created in an <em>unlinked</em> state, |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
37 |
* which is distinguished by a null target variable. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
38 |
* Before the call site may be invoked (and before certain other |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
39 |
* operations are attempted), the call site must be linked to |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
40 |
* a non-null target. |
2763 | 41 |
* <p> |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
42 |
* A call site may be <em>relinked</em> by changing its target. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
43 |
* The new target must be non-null and must have the same |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
44 |
* {@linkplain MethodHandle#type() type} |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
45 |
* as the previous target. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
46 |
* Thus, though a call site can be relinked to a series of |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
47 |
* successive targets, it cannot change its type. |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
48 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
49 |
* 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
|
50 |
* 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
|
51 |
* a single {@code invokedynamic} instruction, with multiple {@code CallSite} objects. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
52 |
* 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
|
53 |
* 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
|
54 |
* 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
|
55 |
* state. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
56 |
* <p> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
57 |
* 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
|
58 |
* dynamic call site to print its arguments: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
59 |
<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java --> |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
60 |
@BootstrapMethod(value=PrintArgsDemo.class, name="bootstrapDynamic") |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
61 |
static void test() throws Throwable { |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
62 |
InvokeDynamic.baz("baz arg", 2, 3.14); |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
63 |
} |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
64 |
private static void printArgs(Object... args) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
65 |
System.out.println(java.util.Arrays.deepToString(args)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
66 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
67 |
private static final MethodHandle printArgs; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
68 |
static { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
69 |
MethodHandles.Lookup lookup = MethodHandles.lookup(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
70 |
Class thisClass = lookup.lookupClass(); // (who am I?) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
71 |
printArgs = lookup.findStatic(thisClass, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
72 |
"printArgs", MethodType.methodType(void.class, Object[].class)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
73 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
74 |
private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
75 |
// ignore caller and name, but match the type: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
76 |
return new CallSite(MethodHandles.collectArguments(printArgs, type)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
77 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
78 |
</pre></blockquote> |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
79 |
* @author John Rose, JSR 292 EG |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
80 |
*/ |
4537 | 81 |
public class CallSite |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
82 |
implements MethodHandleProvider |
4537 | 83 |
{ |
84 |
private static final Access IMPL_TOKEN = Access.getToken(); |
|
85 |
||
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
86 |
// 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
|
87 |
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
|
88 |
private int vmindex; // supplied by the JVM (BCI within calling method) |
4537 | 89 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
90 |
// The actual payload of this call site: |
4537 | 91 |
private MethodHandle target; |
92 |
||
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
93 |
// Remove this field for PFD and delete deprecated methods: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
94 |
private MemberName calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
95 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
96 |
/** |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
97 |
* Make a blank call site object. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
98 |
* 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
|
99 |
* must be provided with |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
100 |
* 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
|
101 |
* 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
|
102 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
103 |
public CallSite() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
104 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
105 |
|
2763 | 106 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
107 |
* 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
|
108 |
* 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
|
109 |
* 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
|
110 |
* or by a subclass override of {@link CallSite#initialTarget}. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
111 |
* @param target the method handle which will be the initial target of the call site, or null if there is none yet |
2763 | 112 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
113 |
public CallSite(MethodHandle target) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
114 |
this.target = target; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
115 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
116 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
117 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
118 |
public CallSite(Class<?> caller, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
119 |
this.calleeNameRemoveForPFD = new MemberName(caller, name, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
120 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
121 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
122 |
public Class<?> callerClass() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
123 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
124 |
return callee == null ? null : callee.getDeclaringClass(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
125 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
126 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
127 |
public String name() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
128 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
129 |
return callee == null ? null : callee.getName(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
130 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
131 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
132 |
public MethodType type() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
133 |
MemberName callee = this.calleeNameRemoveForPFD; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
134 |
return callee == null ? (target == null ? null : target.type()) : callee.getMethodType(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
135 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
136 |
/** @deprecated transitional form defined in EDR but removed in PFD */ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
137 |
protected MethodHandle initialTarget() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
138 |
return initialTarget(callerClass(), name(), type()); |
4537 | 139 |
} |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
140 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
141 |
/** 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
|
142 |
* Once it is linked, it is never unlinked. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
143 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
144 |
private boolean isLinked() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
145 |
return vmmethod != null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
146 |
} |
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 |
/** 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
|
149 |
* The parameters are JVM-specific. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
150 |
*/ |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
151 |
void initializeFromJVM(String name, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
152 |
MethodType type, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
153 |
MemberName callerMethod, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
154 |
int callerBCI) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
155 |
if (this.isLinked()) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
156 |
throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction"); |
4537 | 157 |
} |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
158 |
MethodHandle target = this.target; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
159 |
if (target == null) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
160 |
this.target = target = this.initialTarget(callerMethod.getDeclaringClass(), name, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
161 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
162 |
if (!target.type().equals(type)) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
163 |
throw wrongTargetType(target, type); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
164 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
165 |
this.vmindex = callerBCI; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
166 |
this.vmmethod = callerMethod; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
167 |
assert(this.isLinked()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
168 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
169 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
170 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
171 |
* 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
|
172 |
* 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
|
173 |
* 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
|
174 |
* 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
|
175 |
* <p> |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
176 |
* 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
|
177 |
* 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
|
178 |
* create a "blank" {@code CallSite} object of an appropriate subclass. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
179 |
* <p> |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
180 |
* 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
|
181 |
* this method must be overridden, because it just raises an |
2763 | 182 |
* {@code InvokeDynamicBootstrapError}, which in turn causes the |
183 |
* linkage of the {@code invokedynamic} instruction to terminate |
|
184 |
* abnormally. |
|
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
185 |
* @deprecated transitional form defined in EDR but removed in PFD |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
186 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
187 |
protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
188 |
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
|
189 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
190 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
191 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
192 |
* Report the current linkage state of the call site. (This is mutable.) |
4537 | 193 |
* The value may not be null after the {@code CallSite} object is returned |
194 |
* from the bootstrap method of the {@code invokedynamic} instruction. |
|
195 |
* When an {@code invokedynamic} instruction is executed, the target method |
|
196 |
* of its associated {@code call site} object is invoked directly, |
|
197 |
* as if via {@link MethodHandle}{@code .invoke}. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
198 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
199 |
* 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
|
200 |
* 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
|
201 |
* non-volatile, non-final field. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
202 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
203 |
* 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
|
204 |
* 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
|
205 |
* a recent update to the target by another thread. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
206 |
* @return the current linkage state of the call site |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
207 |
* @see #setTarget |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
208 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
209 |
public MethodHandle getTarget() { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
210 |
return target; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
211 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
212 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
213 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
214 |
* Set the target method of this call site. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
215 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
216 |
* 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
|
217 |
* 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
|
218 |
* non-volatile, non-final field. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
219 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
220 |
* 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
|
221 |
* until they perform a read from memory. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
222 |
* Stronger guarantees can be created by putting appropriate operations |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
223 |
* 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
|
224 |
* at any given call site. |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
225 |
* @param newTarget the new target |
2763 | 226 |
* @throws NullPointerException if the proposed new target is null |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
227 |
* @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
|
228 |
* 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
|
229 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
230 |
public void setTarget(MethodHandle newTarget) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
231 |
MethodType newType = newTarget.type(); // null check! |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
232 |
MethodHandle oldTarget = this.target; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
233 |
if (oldTarget == null) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
234 |
// CallSite is not yet linked. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
235 |
assert(!isLinked()); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
236 |
this.target = newTarget; // might be null! |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
237 |
return; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
238 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
239 |
MethodType oldType = oldTarget.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
240 |
if (!newTarget.type().equals(oldType)) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
241 |
throw wrongTargetType(newTarget, oldType); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
242 |
if (oldTarget != newTarget) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
243 |
CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
244 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
245 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
246 |
private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
247 |
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
|
248 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
249 |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
250 |
/** 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
|
251 |
* that may be useful to the human reader. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
252 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
253 |
@Override |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
254 |
public String toString() { |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
255 |
return "CallSite"+(target == null ? "" : target.type()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
256 |
} |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
257 |
|
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
258 |
/** |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
259 |
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
260 |
* Produce a method handle equivalent to an invokedynamic instruction |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
261 |
* which has been linked to this call site. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
262 |
* <p>If this call site is a {@link ConstantCallSite}, this method |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
263 |
* simply returns the call site's target, since that will not change. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
264 |
* <p>Otherwise, this method is equivalent to the following code: |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
265 |
* <p><blockquote><pre> |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
266 |
* MethodHandle getTarget, invoker, result; |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
267 |
* getTarget = MethodHandles.lookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class)); |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
268 |
* invoker = MethodHandles.exactInvoker(this.type()); |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
269 |
* result = MethodHandles.foldArguments(invoker, getTarget) |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
270 |
* </pre></blockquote> |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
271 |
* @return a method handle which always invokes this call site's current target |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
272 |
*/ |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
273 |
public final MethodHandle dynamicInvoker() { |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
274 |
if (this instanceof ConstantCallSite) |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
275 |
return getTarget(); // will not change dynamically |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
276 |
MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this); |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
277 |
MethodHandle invoker = MethodHandles.exactInvoker(this.type()); |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
278 |
return MethodHandles.foldArguments(invoker, getTarget); |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
279 |
} |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
280 |
private static final MethodHandle GET_TARGET; |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
281 |
static { |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
282 |
try { |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
283 |
GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP. |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
284 |
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class)); |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
285 |
} catch (NoAccessException ignore) { |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
286 |
throw new InternalError(); |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
287 |
} |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
7051
diff
changeset
|
288 |
} |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
289 |
|
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
290 |
/** Implementation of {@link MethodHandleProvider} which returns {@code this.dynamicInvoker()}. */ |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
291 |
public final MethodHandle asMethodHandle() { return dynamicInvoker(); } |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
292 |
|
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
293 |
/** Implementation of {@link MethodHandleProvider}, which returns {@code this.dynamicInvoker().asType(type)}. */ |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
5725
diff
changeset
|
294 |
public final MethodHandle asMethodHandle(MethodType type) { return dynamicInvoker().asType(type); } |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
295 |
} |