95 import jdk.internal.dynalink.support.Lookup; |
95 import jdk.internal.dynalink.support.Lookup; |
96 import jdk.internal.dynalink.support.SimpleCallSiteDescriptor; |
96 import jdk.internal.dynalink.support.SimpleCallSiteDescriptor; |
97 import jdk.internal.dynalink.support.SimpleLinkRequest; |
97 import jdk.internal.dynalink.support.SimpleLinkRequest; |
98 |
98 |
99 /** |
99 /** |
100 * The linker for {@link RelinkableCallSite} objects. Users of it (scripting |
100 * The linker for {@link RelinkableCallSite} objects. Users of Dynalink have to |
101 * frameworks and language runtimes) have to create a linker using the |
101 * create a linker using the {@link DynamicLinkerFactory} and invoke its |
102 * {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic |
102 * {@link #link(RelinkableCallSite)} method from the invokedynamic bootstrap |
103 * bootstrap methods to set the target of all the call sites in the code they |
103 * methods to let it manage all the call sites they create. Usual usage would be |
104 * generate. Usual usage would be to create one class per language runtime to |
104 * to create one class per language runtime to contain one linker instance as: |
105 * contain one linker instance as: |
|
106 * |
|
107 * <pre> |
105 * <pre> |
|
106 * |
108 * class MyLanguageRuntime { |
107 * class MyLanguageRuntime { |
109 * private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker(); |
108 * private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker(); |
110 * private static final DynamicLinker dynamicLinker = createDynamicLinker(); |
109 * private static final DynamicLinker dynamicLinker = createDynamicLinker(); |
111 * |
110 * |
112 * private static DynamicLinker createDynamicLinker() { |
111 * private static DynamicLinker createDynamicLinker() { |
114 * factory.setPrioritizedLinker(myLanguageLinker); |
113 * factory.setPrioritizedLinker(myLanguageLinker); |
115 * return factory.createLinker(); |
114 * return factory.createLinker(); |
116 * } |
115 * } |
117 * |
116 * |
118 * public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) { |
117 * public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) { |
119 * return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type))); |
118 * return dynamicLinker.link(new MonomorphicCallSite(new SimpleCallSiteDescriptor(lookup, name, type))); |
120 * } |
119 * } |
121 * } |
120 * } |
122 * </pre> |
121 * </pre> |
123 * |
122 * |
124 * Note how there are three components you will need to provide here: |
123 * Note how there are three components you will need to provide here: |
146 * |
145 * |
147 * </ul> |
146 * </ul> |
148 */ |
147 */ |
149 public final class DynamicLinker { |
148 public final class DynamicLinker { |
150 /** |
149 /** |
151 * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is named |
150 * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is |
152 * {@code "dynalink.getCurrentLinkRequest"}. |
151 * named {@code "dynalink.getCurrentLinkRequest"}. |
153 */ |
152 */ |
154 public static final RuntimePermission GET_CURRENT_LINK_REQUEST_PERMISSION = new RuntimePermission("dynalink.getCurrentLinkRequest"); |
153 public static final RuntimePermission GET_CURRENT_LINK_REQUEST_PERMISSION = new RuntimePermission("dynalink.getCurrentLinkRequest"); |
155 |
154 |
156 private static final String CLASS_NAME = DynamicLinker.class.getName(); |
155 private static final String CLASS_NAME = DynamicLinker.class.getName(); |
157 private static final String RELINK_METHOD_NAME = "relink"; |
156 private static final String RELINK_METHOD_NAME = "relink"; |
200 callSite.initialize(createRelinkAndInvokeMethod(callSite, 0)); |
199 callSite.initialize(createRelinkAndInvokeMethod(callSite, 0)); |
201 return callSite; |
200 return callSite; |
202 } |
201 } |
203 |
202 |
204 /** |
203 /** |
205 * Returns the object representing the lower level linker services of this |
204 * Returns the object representing the linker services of this class that |
206 * class that are normally exposed to individual language-specific linkers. |
205 * are normally exposed to individual language-specific linkers. |
207 * While as a user of this class you normally only care about the |
206 * While as a user of this class you normally only care about the |
208 * {@link #link(RelinkableCallSite)} method, in certain circumstances you |
207 * {@link #link(RelinkableCallSite)} method, in certain circumstances you |
209 * might want to use the lower level services directly; either to lookup |
208 * might want to use the lower level services directly; either to lookup |
210 * specific method handles, to access the type converters, and so on. |
209 * specific method handles, to access the type converters, and so on. |
211 * |
210 * |
273 } |
272 } |
274 return guardedInvocation.getInvocation(); |
273 return guardedInvocation.getInvocation(); |
275 } |
274 } |
276 |
275 |
277 /** |
276 /** |
278 * Returns a stack trace element describing the location of the call site |
277 * Returns a stack trace element describing the location of the |
279 * currently being linked on the current thread. The operation internally |
278 * {@code invokedynamic} call site currently being linked on the current |
280 * creates a Throwable object and inspects its stack trace, so it's |
279 * thread. The operation is potentially expensive and is intended for use in |
281 * potentially expensive. The recommended usage for it is in writing |
280 * diagnostics code. For "free-floating" call sites (not associated with an |
282 * diagnostics code. |
281 * {@code invokedynamic} instruction), the result is not well-defined. |
283 * |
282 * |
284 * @return a stack trace element describing the location of the call site |
283 * @return a stack trace element describing the location of the call site |
285 * currently being linked, or null if it is not invoked while a call |
284 * currently being linked, or null if it is not invoked while a call |
286 * site is being linked. |
285 * site is being linked. |
287 */ |
286 */ |
302 } |
301 } |
303 return null; |
302 return null; |
304 } |
303 } |
305 |
304 |
306 /** |
305 /** |
307 * Returns the currently processed link request, or null if the method is invoked outside of the linking process. |
306 * Returns the currently processed link request, or null if the method is |
|
307 * invoked outside of the linking process. |
308 * @return the currently processed link request, or null. |
308 * @return the currently processed link request, or null. |
309 * @throws SecurityException if the calling code doesn't have the {@code "dynalink.getCurrentLinkRequest"} |
309 * @throws SecurityException if the calling code doesn't have the |
310 * runtime permission (available as {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}). |
310 * {@code "dynalink.getCurrentLinkRequest"} runtime permission (available as |
|
311 * {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}). |
311 */ |
312 */ |
312 public static LinkRequest getCurrentLinkRequest() { |
313 public static LinkRequest getCurrentLinkRequest() { |
313 return LinkerServicesImpl.getCurrentLinkRequest(); |
314 return LinkerServicesImpl.getCurrentLinkRequest(); |
314 } |
315 } |
315 |
316 |