10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
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.
24 */
25
26 package java.lang.invoke;
27
28 import static java.lang.invoke.MethodHandleStatics.*;
29 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
30 import java.lang.reflect.Field;
31 import sun.misc.Cleaner;
32
33 /**
34 * A {@code CallSite} is a holder for a variable {@link MethodHandle},
35 * which is called its {@code target}.
36 * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
37 * all calls to the site's current target.
38 * A {@code CallSite} may be associated with several {@code invokedynamic}
39 * instructions, or it may be "free floating", associated with none.
40 * In any case, it may be invoked through an associated method handle
41 * called its {@linkplain #dynamicInvoker dynamic invoker}.
42 * <p>
43 * {@code CallSite} is an abstract class which does not allow
44 * direct subclassing by users. It has three immediate,
45 * concrete subclasses that may be either instantiated or subclassed.
46 * <ul>
47 * <li>If a mutable target is not required, an {@code invokedynamic} instruction
48 * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
49 * <li>If a mutable target is required which has volatile variable semantics,
50 * because updates to the target must be immediately and reliably witnessed by other threads,
121 * Make a call site object equipped with an initial target method handle.
122 * @param targetType the desired type of the call site
123 * @param createTargetHook a hook which will bind the call site to the target method handle
124 * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
125 * or if the target returned by the hook is not of the given {@code targetType}
126 * @throws NullPointerException if the hook returns a null value
127 * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
128 * @throws Throwable anything else thrown by the hook function
129 */
130 /*package-private*/
131 CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
132 this(targetType);
133 ConstantCallSite selfCCS = (ConstantCallSite) this;
134 MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
135 checkTargetChange(this.target, boundTarget);
136 this.target = boundTarget;
137 }
138
139 /**
140 * {@code CallSite} dependency context.
141 * VM uses context class to store nmethod dependencies on the call site target.
142 * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
143 * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
144 * it to store dependencies. As a corollary, "null" context means there are no dependencies
145 * registered yet. {@code Cleaner} is used in 2 roles:
146 * (a) context class access for VM;
147 * (b) stale context class cleanup.
148 * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
149 * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
150 * from {@code Reference.referent} field.
151 */
152 private volatile Cleaner context = null;
153
154 /**
155 * Default context.
156 * VM uses it to initialize non-linked CallSite context.
157 */
158 private static class DefaultContext {}
159 private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
160
161 private static Cleaner makeContext(Class<?> referent, final CallSite holder) {
162 return Cleaner.create(referent,
163 new Runnable() {
164 @Override public void run() {
165 MethodHandleNatives.invalidateDependentNMethods(holder);
166 }
167 });
168 }
169
170 /** Initialize context class used for nmethod dependency tracking */
171 /*package-private*/
172 void initContext(Class<?> newContext) {
173 // If there are concurrent actions, exactly one succeeds.
174 if (context == null) {
175 UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
176 // No need to care about failed CAS attempt.
177 // Since initContext is called from indy call site linkage in newContext class, there's no risk
178 // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
179 // action in the wrong context).
180 }
181 }
182
183 /**
184 * Returns the type of this call site's target.
185 * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
186 * The {@code setTarget} method enforces this invariant by refusing any new target that does
187 * not have the previous target's type.
188 * @return the type of the current target, which is also the type of any future target
189 */
190 public MethodType type() {
191 // warning: do not call getTarget here, because CCS.getTarget can throw IllegalStateException
192 return target.type();
193 }
194
195 /**
196 * Returns the target method of the call site, according to the
197 * behavior defined by this call site's specific class.
198 * The immediate subclasses of {@code CallSite} document the
199 * class-specific behaviors of this method.
|
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
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.
24 */
25
26 package java.lang.invoke;
27
28 import static java.lang.invoke.MethodHandleStatics.*;
29 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
30 import sun.misc.Cleaner;
31
32 /**
33 * A {@code CallSite} is a holder for a variable {@link MethodHandle},
34 * which is called its {@code target}.
35 * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
36 * all calls to the site's current target.
37 * A {@code CallSite} may be associated with several {@code invokedynamic}
38 * instructions, or it may be "free floating", associated with none.
39 * In any case, it may be invoked through an associated method handle
40 * called its {@linkplain #dynamicInvoker dynamic invoker}.
41 * <p>
42 * {@code CallSite} is an abstract class which does not allow
43 * direct subclassing by users. It has three immediate,
44 * concrete subclasses that may be either instantiated or subclassed.
45 * <ul>
46 * <li>If a mutable target is not required, an {@code invokedynamic} instruction
47 * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
48 * <li>If a mutable target is required which has volatile variable semantics,
49 * because updates to the target must be immediately and reliably witnessed by other threads,
120 * Make a call site object equipped with an initial target method handle.
121 * @param targetType the desired type of the call site
122 * @param createTargetHook a hook which will bind the call site to the target method handle
123 * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
124 * or if the target returned by the hook is not of the given {@code targetType}
125 * @throws NullPointerException if the hook returns a null value
126 * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
127 * @throws Throwable anything else thrown by the hook function
128 */
129 /*package-private*/
130 CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
131 this(targetType);
132 ConstantCallSite selfCCS = (ConstantCallSite) this;
133 MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
134 checkTargetChange(this.target, boundTarget);
135 this.target = boundTarget;
136 }
137
138 /**
139 * {@code CallSite} dependency context.
140 * JVM uses CallSite.context to store nmethod dependencies on the call site target.
141 */
142 private final Context context = Context.make(this);
143
144 static class Context implements Runnable {
145 static {
146 sun.reflect.Reflection.registerFieldsToFilter(Context.class, "dependencies");
147 }
148
149 private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket*
150
151 static Context make(CallSite cs) {
152 final Context newContext = new Context();
153 // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context.
154 // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is
155 // referenced from Cleaner class) until cleanup is performed.
156 Cleaner.create(cs, newContext);
157 return newContext;
158 }
159
160 @Override
161 public void run() {
162 MethodHandleNatives.clearCallSiteContext(this);
163 }
164 }
165
166 /**
167 * Returns the type of this call site's target.
168 * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
169 * The {@code setTarget} method enforces this invariant by refusing any new target that does
170 * not have the previous target's type.
171 * @return the type of the current target, which is also the type of any future target
172 */
173 public MethodType type() {
174 // warning: do not call getTarget here, because CCS.getTarget can throw IllegalStateException
175 return target.type();
176 }
177
178 /**
179 * Returns the target method of the call site, according to the
180 * behavior defined by this call site's specific class.
181 * The immediate subclasses of {@code CallSite} document the
182 * class-specific behaviors of this method.
|