95 import java.util.Set; |
95 import java.util.Set; |
96 import jdk.internal.dynalink.beans.BeansLinker; |
96 import jdk.internal.dynalink.beans.BeansLinker; |
97 import jdk.internal.dynalink.linker.GuardingDynamicLinker; |
97 import jdk.internal.dynalink.linker.GuardingDynamicLinker; |
98 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; |
98 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; |
99 import jdk.internal.dynalink.linker.LinkRequest; |
99 import jdk.internal.dynalink.linker.LinkRequest; |
|
100 import jdk.internal.dynalink.linker.MethodTypeConversionStrategy; |
100 import jdk.internal.dynalink.support.AutoDiscovery; |
101 import jdk.internal.dynalink.support.AutoDiscovery; |
101 import jdk.internal.dynalink.support.BottomGuardingDynamicLinker; |
102 import jdk.internal.dynalink.support.BottomGuardingDynamicLinker; |
102 import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider; |
103 import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider; |
103 import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker; |
104 import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker; |
104 import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker; |
105 import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker; |
105 import jdk.internal.dynalink.support.DefaultPrelinkFilter; |
106 import jdk.internal.dynalink.support.DefaultPrelinkFilter; |
106 import jdk.internal.dynalink.support.LinkerServicesImpl; |
107 import jdk.internal.dynalink.support.LinkerServicesImpl; |
107 import jdk.internal.dynalink.support.TypeConverterFactory; |
108 import jdk.internal.dynalink.support.TypeConverterFactory; |
|
109 import jdk.internal.dynalink.support.TypeUtilities; |
108 |
110 |
109 /** |
111 /** |
110 * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition |
112 * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition |
111 * of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any |
113 * of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any |
112 * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker} and a |
114 * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker} and a |
113 * {@link DefaultPrelinkFilter}. See {@link DynamicLinker} documentation for tips on how to use this class. |
115 * {@link DefaultPrelinkFilter}. See {@link DynamicLinker} documentation for tips on how to use this class. |
114 * |
116 * |
115 * @author Attila Szegedi |
117 * @author Attila Szegedi |
116 */ |
118 */ |
117 public class DynamicLinkerFactory { |
119 public class DynamicLinkerFactory { |
118 |
|
119 /** |
120 /** |
120 * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. |
121 * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. |
121 */ |
122 */ |
122 public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8; |
123 public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8; |
123 |
124 |
128 private List<? extends GuardingDynamicLinker> fallbackLinkers; |
129 private List<? extends GuardingDynamicLinker> fallbackLinkers; |
129 private int runtimeContextArgCount = 0; |
130 private int runtimeContextArgCount = 0; |
130 private boolean syncOnRelink = false; |
131 private boolean syncOnRelink = false; |
131 private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; |
132 private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; |
132 private GuardedInvocationFilter prelinkFilter; |
133 private GuardedInvocationFilter prelinkFilter; |
|
134 private MethodTypeConversionStrategy autoConversionStrategy; |
133 |
135 |
134 /** |
136 /** |
135 * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread |
137 * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread |
136 * context class loader at the time of {@link #createLinker()} invocation will be used. |
138 * context class loader at the time of {@link #createLinker()} invocation will be used. |
137 * |
139 * |
254 * When not set explicitly, {@link DefaultPrelinkFilter} will be used. |
256 * When not set explicitly, {@link DefaultPrelinkFilter} will be used. |
255 * @param prelinkFilter the pre-link filter for the dynamic linker. |
257 * @param prelinkFilter the pre-link filter for the dynamic linker. |
256 */ |
258 */ |
257 public void setPrelinkFilter(final GuardedInvocationFilter prelinkFilter) { |
259 public void setPrelinkFilter(final GuardedInvocationFilter prelinkFilter) { |
258 this.prelinkFilter = prelinkFilter; |
260 this.prelinkFilter = prelinkFilter; |
|
261 } |
|
262 |
|
263 /** |
|
264 * Sets an object representing the conversion strategy for automatic type conversions. After |
|
265 * {@link TypeConverterFactory#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} has |
|
266 * applied all custom conversions to a method handle, it still needs to effect |
|
267 * {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method invocation conversions} that |
|
268 * can usually be automatically applied as per |
|
269 * {@link java.lang.invoke.MethodHandle#asType(java.lang.invoke.MethodType)}. |
|
270 * However, sometimes language runtimes will want to customize even those conversions for their own call |
|
271 * sites. A typical example is allowing unboxing of null return values, which is by default prohibited by |
|
272 * ordinary {@code MethodHandles.asType}. In this case, a language runtime can install its own custom |
|
273 * automatic conversion strategy, that can deal with null values. Note that when the strategy's |
|
274 * {@link MethodTypeConversionStrategy#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} |
|
275 * is invoked, the custom language conversions will already have been applied to the method handle, so by |
|
276 * design the difference between the handle's current method type and the desired final type will always |
|
277 * only be ones that can be subjected to method invocation conversions. The strategy also doesn't need to |
|
278 * invoke a final {@code MethodHandle.asType()} as the converter factory will do that as the final step. |
|
279 * @param autoConversionStrategy the strategy for applying method invocation conversions for the linker |
|
280 * created by this factory. |
|
281 */ |
|
282 public void setAutoConversionStrategy(final MethodTypeConversionStrategy autoConversionStrategy) { |
|
283 this.autoConversionStrategy = autoConversionStrategy; |
259 } |
284 } |
260 |
285 |
261 /** |
286 /** |
262 * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as |
287 * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as |
263 * the pre-link filter. |
288 * the pre-link filter. |
322 |
347 |
323 if(prelinkFilter == null) { |
348 if(prelinkFilter == null) { |
324 prelinkFilter = new DefaultPrelinkFilter(); |
349 prelinkFilter = new DefaultPrelinkFilter(); |
325 } |
350 } |
326 |
351 |
327 return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite), |
352 return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters, |
328 prelinkFilter, runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); |
353 autoConversionStrategy), composite), prelinkFilter, runtimeContextArgCount, syncOnRelink, |
|
354 unstableRelinkThreshold); |
329 } |
355 } |
330 |
356 |
331 private static ClassLoader getThreadContextClassLoader() { |
357 private static ClassLoader getThreadContextClassLoader() { |
332 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
358 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
333 @Override |
359 @Override |