71 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
72 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
73 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
74 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
75 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
76 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
77 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
78 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
79 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
80 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
81 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 */
83
84 package jdk.internal.dynalink;
85
86 import java.lang.invoke.MethodHandle;
87 import java.lang.invoke.MethodHandles;
88 import java.lang.invoke.MethodType;
89 import java.lang.invoke.MutableCallSite;
90 import java.util.List;
91 import jdk.internal.dynalink.linker.GuardedInvocation;
92 import jdk.internal.dynalink.linker.GuardingDynamicLinker;
93 import jdk.internal.dynalink.linker.LinkRequest;
94 import jdk.internal.dynalink.linker.LinkerServices;
95 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
96 import jdk.internal.dynalink.support.LinkRequestImpl;
97 import jdk.internal.dynalink.support.Lookup;
98 import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
99
100 /**
101 * The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
102 * create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
103 * methods to set the target of all the call sites in the code they generate. Usual usage would be to create one class
104 * per language runtime to contain one linker instance as:
105 *
106 * <pre>
107 * class MyLanguageRuntime {
108 * private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
109 * private static final DynamicLinker dynamicLinker = createDynamicLinker();
110 *
235 // None found - throw an exception
236 if(guardedInvocation == null) {
237 throw new NoSuchDynamicMethodException(callSiteDescriptor.toString());
238 }
239
240 // If our call sites have a runtime context, and the linker produced a context-stripped invocation, adapt the
241 // produced invocation into contextual invocation (by dropping the context...)
242 if(runtimeContextArgCount > 0) {
243 final MethodType origType = callSiteDescriptor.getMethodType();
244 final MethodHandle invocation = guardedInvocation.getInvocation();
245 if(invocation.type().parameterCount() == origType.parameterCount() - runtimeContextArgCount) {
246 final List<Class<?>> prefix = origType.parameterList().subList(1, runtimeContextArgCount + 1);
247 final MethodHandle guard = guardedInvocation.getGuard();
248 guardedInvocation = guardedInvocation.dropArguments(1, prefix);
249 }
250 }
251
252 // Make sure we filter the invocation before linking it into the call site. This is typically used to match the
253 // return type of the invocation to the call site.
254 guardedInvocation = prelinkFilter.filter(guardedInvocation, linkRequest, linkerServices);
255 guardedInvocation.getClass(); // null pointer check
256
257 int newRelinkCount = relinkCount;
258 // Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until
259 // threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink
260 // has already executed once for the unstable call site; we only want the call site to throw away its current
261 // linkage once, when it transitions to unstable.
262 if(unstableDetectionEnabled && newRelinkCount <= unstableRelinkThreshold && newRelinkCount++ == unstableRelinkThreshold) {
263 callSite.resetAndRelink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
264 } else {
265 callSite.relink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
266 }
267 if(syncOnRelink) {
268 MutableCallSite.syncAll(new MutableCallSite[] { (MutableCallSite)callSite });
269 }
270 return guardedInvocation.getInvocation();
271 }
272
273 /**
274 * Returns a stack trace element describing the location of the call site currently being linked on the current
275 * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
|
71 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
72 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
73 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
74 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
75 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
76 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
77 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
78 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
79 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
80 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
81 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 */
83
84 package jdk.internal.dynalink;
85
86 import java.lang.invoke.MethodHandle;
87 import java.lang.invoke.MethodHandles;
88 import java.lang.invoke.MethodType;
89 import java.lang.invoke.MutableCallSite;
90 import java.util.List;
91 import java.util.Objects;
92 import jdk.internal.dynalink.linker.GuardedInvocation;
93 import jdk.internal.dynalink.linker.GuardingDynamicLinker;
94 import jdk.internal.dynalink.linker.LinkRequest;
95 import jdk.internal.dynalink.linker.LinkerServices;
96 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
97 import jdk.internal.dynalink.support.LinkRequestImpl;
98 import jdk.internal.dynalink.support.Lookup;
99 import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
100
101 /**
102 * The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
103 * create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
104 * methods to set the target of all the call sites in the code they generate. Usual usage would be to create one class
105 * per language runtime to contain one linker instance as:
106 *
107 * <pre>
108 * class MyLanguageRuntime {
109 * private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
110 * private static final DynamicLinker dynamicLinker = createDynamicLinker();
111 *
236 // None found - throw an exception
237 if(guardedInvocation == null) {
238 throw new NoSuchDynamicMethodException(callSiteDescriptor.toString());
239 }
240
241 // If our call sites have a runtime context, and the linker produced a context-stripped invocation, adapt the
242 // produced invocation into contextual invocation (by dropping the context...)
243 if(runtimeContextArgCount > 0) {
244 final MethodType origType = callSiteDescriptor.getMethodType();
245 final MethodHandle invocation = guardedInvocation.getInvocation();
246 if(invocation.type().parameterCount() == origType.parameterCount() - runtimeContextArgCount) {
247 final List<Class<?>> prefix = origType.parameterList().subList(1, runtimeContextArgCount + 1);
248 final MethodHandle guard = guardedInvocation.getGuard();
249 guardedInvocation = guardedInvocation.dropArguments(1, prefix);
250 }
251 }
252
253 // Make sure we filter the invocation before linking it into the call site. This is typically used to match the
254 // return type of the invocation to the call site.
255 guardedInvocation = prelinkFilter.filter(guardedInvocation, linkRequest, linkerServices);
256 Objects.requireNonNull(guardedInvocation);
257
258 int newRelinkCount = relinkCount;
259 // Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until
260 // threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink
261 // has already executed once for the unstable call site; we only want the call site to throw away its current
262 // linkage once, when it transitions to unstable.
263 if(unstableDetectionEnabled && newRelinkCount <= unstableRelinkThreshold && newRelinkCount++ == unstableRelinkThreshold) {
264 callSite.resetAndRelink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
265 } else {
266 callSite.relink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
267 }
268 if(syncOnRelink) {
269 MutableCallSite.syncAll(new MutableCallSite[] { (MutableCallSite)callSite });
270 }
271 return guardedInvocation.getInvocation();
272 }
273
274 /**
275 * Returns a stack trace element describing the location of the call site currently being linked on the current
276 * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
|