src/jdk/internal/dynalink/DynamicLinkerFactory.java

changeset 1090
99571b7922c0
parent 963
e2497b11a021
child 1205
4112748288bb
child 1239
e1146c9cc758
equal deleted inserted replaced
1089:981feb6ad9cc 1090:99571b7922c0
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

mercurial