author | lana |
Thu, 26 Dec 2013 12:04:16 -0800 | |
changeset 23010 | 6dadb192ad81 |
parent 20535 | cc85c8626435 |
permissions | -rw-r--r-- |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
1 |
/* |
23010
6dadb192ad81
8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents:
20535
diff
changeset
|
2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
4 |
* |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. Oracle designates this |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
10 |
* |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
15 |
* accompanied this code). |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
16 |
* |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
20 |
* |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
22 |
* or visit www.oracle.com if you need additional information or have any |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
23 |
* questions. |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
24 |
*/ |
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
25 |
|
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8346
diff
changeset
|
26 |
package java.lang.invoke; |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
27 |
|
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
28 |
/** |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
29 |
* <p> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
30 |
* A {@code SwitchPoint} is an object which can publish state transitions to other threads. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
31 |
* A switch point is initially in the <em>valid</em> state, but may at any time be |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
32 |
* changed to the <em>invalid</em> state. Invalidation cannot be reversed. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
33 |
* A switch point can combine a <em>guarded pair</em> of method handles into a |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
34 |
* <em>guarded delegator</em>. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
35 |
* The guarded delegator is a method handle which delegates to one of the old method handles. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
36 |
* The state of the switch point determines which of the two gets the delegation. |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
37 |
* <p> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
38 |
* A single switch point may be used to control any number of method handles. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
39 |
* (Indirectly, therefore, it can control any number of call sites.) |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
40 |
* This is done by using the single switch point as a factory for combining |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
41 |
* any number of guarded method handle pairs into guarded delegators. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
42 |
* <p> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
43 |
* When a guarded delegator is created from a guarded pair, the pair |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
44 |
* is wrapped in a new method handle {@code M}, |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
45 |
* which is permanently associated with the switch point that created it. |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
46 |
* Each pair consists of a target {@code T} and a fallback {@code F}. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
47 |
* While the switch point is valid, invocations to {@code M} are delegated to {@code T}. |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
48 |
* After it is invalidated, invocations are delegated to {@code F}. |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
49 |
* <p> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
50 |
* Invalidation is global and immediate, as if the switch point contained a |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
51 |
* volatile boolean variable consulted on every call to {@code M}. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
52 |
* The invalidation is also permanent, which means the switch point |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
53 |
* can change state only once. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
54 |
* The switch point will always delegate to {@code F} after being invalidated. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
55 |
* At that point {@code guardWithTest} may ignore {@code T} and return {@code F}. |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
56 |
* <p> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
57 |
* Here is an example of a switch point in action: |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
9859
diff
changeset
|
58 |
* <blockquote><pre>{@code |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
59 |
MethodHandle MH_strcat = MethodHandles.lookup() |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
60 |
.findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class)); |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
61 |
SwitchPoint spt = new SwitchPoint(); |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
62 |
assert(!spt.hasBeenInvalidated()); |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
63 |
// the following steps may be repeated to re-use the same switch point: |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
64 |
MethodHandle worker1 = MH_strcat; |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
65 |
MethodHandle worker2 = MethodHandles.permuteArguments(MH_strcat, MH_strcat.type(), 1, 0); |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
66 |
MethodHandle worker = spt.guardWithTest(worker1, worker2); |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
67 |
assertEquals("method", (String) worker.invokeExact("met", "hod")); |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
68 |
SwitchPoint.invalidateAll(new SwitchPoint[]{ spt }); |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
69 |
assert(spt.hasBeenInvalidated()); |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
70 |
assertEquals("hodmet", (String) worker.invokeExact("met", "hod")); |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
9859
diff
changeset
|
71 |
* }</pre></blockquote> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
72 |
* <p style="font-size:smaller;"> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
73 |
* <em>Discussion:</em> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
74 |
* Switch points are useful without subclassing. They may also be subclassed. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
75 |
* This may be useful in order to associate application-specific invalidation logic |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
76 |
* with the switch point. |
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8346
diff
changeset
|
77 |
* Notice that there is no permanent association between a switch point and |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8346
diff
changeset
|
78 |
* the method handles it produces and consumes. |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8346
diff
changeset
|
79 |
* The garbage collector may collect method handles produced or consumed |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8346
diff
changeset
|
80 |
* by a switch point independently of the lifetime of the switch point itself. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
81 |
* <p style="font-size:smaller;"> |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
82 |
* <em>Implementation Note:</em> |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
83 |
* A switch point behaves as if implemented on top of {@link MutableCallSite}, |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
84 |
* approximately as follows: |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
9859
diff
changeset
|
85 |
* <blockquote><pre>{@code |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
86 |
public class SwitchPoint { |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
87 |
private static final MethodHandle |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
88 |
K_true = MethodHandles.constant(boolean.class, true), |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
89 |
K_false = MethodHandles.constant(boolean.class, false); |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
90 |
private final MutableCallSite mcs; |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
91 |
private final MethodHandle mcsInvoker; |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
92 |
public SwitchPoint() { |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
93 |
this.mcs = new MutableCallSite(K_true); |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
94 |
this.mcsInvoker = mcs.dynamicInvoker(); |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
95 |
} |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
96 |
public MethodHandle guardWithTest( |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
97 |
MethodHandle target, MethodHandle fallback) { |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
98 |
// Note: mcsInvoker is of type ()boolean. |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
99 |
// Target and fallback may take any arguments, but must have the same type. |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
100 |
return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback); |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
101 |
} |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
102 |
public static void invalidateAll(SwitchPoint[] spts) { |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
103 |
List<MutableCallSite> mcss = new ArrayList<>(); |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
104 |
for (SwitchPoint spt : spts) mcss.add(spt.mcs); |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
105 |
for (MutableCallSite mcs : mcss) mcs.setTarget(K_false); |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
106 |
MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0])); |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
107 |
} |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
108 |
} |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
9859
diff
changeset
|
109 |
* }</pre></blockquote> |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
110 |
* @author Remi Forax, JSR 292 EG |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
111 |
*/ |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
112 |
public class SwitchPoint { |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
113 |
private static final MethodHandle |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
114 |
K_true = MethodHandles.constant(boolean.class, true), |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
115 |
K_false = MethodHandles.constant(boolean.class, false); |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
116 |
|
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
117 |
private final MutableCallSite mcs; |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
118 |
private final MethodHandle mcsInvoker; |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
119 |
|
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
120 |
/** |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
121 |
* Creates a new switch point. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
122 |
*/ |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
123 |
public SwitchPoint() { |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
124 |
this.mcs = new MutableCallSite(K_true); |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
125 |
this.mcsInvoker = mcs.dynamicInvoker(); |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
126 |
} |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
127 |
|
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
128 |
/** |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
129 |
* Determines if this switch point has been invalidated yet. |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
130 |
* |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
131 |
* <p style="font-size:smaller;"> |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
132 |
* <em>Discussion:</em> |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
133 |
* Because of the one-way nature of invalidation, once a switch point begins |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
134 |
* to return true for {@code hasBeenInvalidated}, |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
135 |
* it will always do so in the future. |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
136 |
* On the other hand, a valid switch point visible to other threads may |
9859
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9782
diff
changeset
|
137 |
* be invalidated at any moment, due to a request by another thread. |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
138 |
* <p style="font-size:smaller;"> |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
139 |
* Since invalidation is a global and immediate operation, |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
140 |
* the execution of this query, on a valid switchpoint, |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
141 |
* must be internally sequenced with any |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
142 |
* other threads that could cause invalidation. |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
143 |
* This query may therefore be expensive. |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
144 |
* The recommended way to build a boolean-valued method handle |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
145 |
* which queries the invalidation state of a switch point {@code s} is |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
146 |
* to call {@code s.guardWithTest} on |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
147 |
* {@link MethodHandles#constant constant} true and false method handles. |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
148 |
* |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
149 |
* @return true if this switch point has been invalidated |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
150 |
*/ |
9782
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
151 |
public boolean hasBeenInvalidated() { |
973c21557e1a
7051206: JSR 292 method name SwitchPoint.isValid is misleading to unwary users; should be hasBeenInvalidated
jrose
parents:
9752
diff
changeset
|
152 |
return (mcs.getTarget() != K_true); |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
153 |
} |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
154 |
|
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
155 |
/** |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
156 |
* Returns a method handle which always delegates either to the target or the fallback. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
157 |
* The method handle will delegate to the target exactly as long as the switch point is valid. |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
158 |
* After that, it will permanently delegate to the fallback. |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
159 |
* <p> |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
160 |
* The target and fallback must be of exactly the same method type, |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
161 |
* and the resulting combined method handle will also be of this type. |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
162 |
* |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
163 |
* @param target the method handle selected by the switch point as long as it is valid |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
164 |
* @param fallback the method handle selected by the switch point after it is invalidated |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
165 |
* @return a combined method handle which always calls either the target or fallback |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
166 |
* @throws NullPointerException if either argument is null |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
167 |
* @throws IllegalArgumentException if the two method types do not match |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
168 |
* @see MethodHandles#guardWithTest |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
169 |
*/ |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
170 |
public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) { |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
171 |
if (mcs.getTarget() == K_false) |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
172 |
return fallback; // already invalid |
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
173 |
return MethodHandles.guardWithTest(mcsInvoker, target, fallback); |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
174 |
} |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
175 |
|
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
176 |
/** |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
177 |
* Sets all of the given switch points into the invalid state. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
178 |
* After this call executes, no thread will observe any of the |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
179 |
* switch points to be in a valid state. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
180 |
* <p> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
181 |
* This operation is likely to be expensive and should be used sparingly. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
182 |
* If possible, it should be buffered for batch processing on sets of switch points. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
183 |
* <p> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
184 |
* If {@code switchPoints} contains a null element, |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
185 |
* a {@code NullPointerException} will be raised. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
186 |
* In this case, some non-null elements in the array may be |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
187 |
* processed before the method returns abnormally. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
188 |
* Which elements these are (if any) is implementation-dependent. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
189 |
* |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
190 |
* <p style="font-size:smaller;"> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
191 |
* <em>Discussion:</em> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
192 |
* For performance reasons, {@code invalidateAll} is not a virtual method |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
193 |
* on a single switch point, but rather applies to a set of switch points. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
194 |
* Some implementations may incur a large fixed overhead cost |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
195 |
* for processing one or more invalidation operations, |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
196 |
* but a small incremental cost for each additional invalidation. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
197 |
* In any case, this operation is likely to be costly, since |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
198 |
* other threads may have to be somehow interrupted |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
199 |
* in order to make them notice the updated switch point state. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
200 |
* However, it may be observed that a single call to invalidate |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
201 |
* several switch points has the same formal effect as many calls, |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
202 |
* each on just one of the switch points. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
203 |
* |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
204 |
* <p style="font-size:smaller;"> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
205 |
* <em>Implementation Note:</em> |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
206 |
* Simple implementations of {@code SwitchPoint} may use |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
207 |
* a private {@link MutableCallSite} to publish the state of a switch point. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
208 |
* In such an implementation, the {@code invalidateAll} method can |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
209 |
* simply change the call site's target, and issue one call to |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
210 |
* {@linkplain MutableCallSite#syncAll synchronize} all the |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
211 |
* private call sites. |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
212 |
* |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
213 |
* @param switchPoints an array of call sites to be synchronized |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
214 |
* @throws NullPointerException if the {@code switchPoints} array reference is null |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
215 |
* or the array contains a null |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
216 |
*/ |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
217 |
public static void invalidateAll(SwitchPoint[] switchPoints) { |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
218 |
if (switchPoints.length == 0) return; |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
219 |
MutableCallSite[] sites = new MutableCallSite[switchPoints.length]; |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
220 |
for (int i = 0; i < switchPoints.length; i++) { |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
221 |
SwitchPoint spt = switchPoints[i]; |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
222 |
if (spt == null) break; // MSC.syncAll will trigger a NPE |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
223 |
sites[i] = spt.mcs; |
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
224 |
spt.mcs.setTarget(K_false); |
7562
a0ad195efe2c
7001424: implement JSR 292 EG adjustments, November 2010
jrose
parents:
7555
diff
changeset
|
225 |
} |
8346
3b891698c4ec
7012650: implement JSR 292 EG adjustments through January 2010
jrose
parents:
7562
diff
changeset
|
226 |
MutableCallSite.syncAll(sites); |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7051
diff
changeset
|
227 |
} |
7051
1c545d70a157
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
diff
changeset
|
228 |
} |