82 */ |
82 */ |
83 |
83 |
84 package jdk.internal.dynalink; |
84 package jdk.internal.dynalink; |
85 |
85 |
86 import java.lang.invoke.MutableCallSite; |
86 import java.lang.invoke.MutableCallSite; |
|
87 import java.security.AccessController; |
|
88 import java.security.PrivilegedAction; |
87 import java.util.ArrayList; |
89 import java.util.ArrayList; |
88 import java.util.Arrays; |
90 import java.util.Arrays; |
89 import java.util.Collections; |
91 import java.util.Collections; |
90 import java.util.HashSet; |
92 import java.util.HashSet; |
91 import java.util.LinkedList; |
93 import java.util.LinkedList; |
115 /** |
117 /** |
116 * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. |
118 * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. |
117 */ |
119 */ |
118 public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8; |
120 public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8; |
119 |
121 |
120 private ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
122 private boolean classLoaderExplicitlySet = false; |
|
123 private ClassLoader classLoader; |
|
124 |
121 private List<? extends GuardingDynamicLinker> prioritizedLinkers; |
125 private List<? extends GuardingDynamicLinker> prioritizedLinkers; |
122 private List<? extends GuardingDynamicLinker> fallbackLinkers; |
126 private List<? extends GuardingDynamicLinker> fallbackLinkers; |
123 private int runtimeContextArgCount = 0; |
127 private int runtimeContextArgCount = 0; |
124 private boolean syncOnRelink = false; |
128 private boolean syncOnRelink = false; |
125 private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; |
129 private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; |
126 |
130 |
127 /** |
131 /** |
128 * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread |
132 * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread |
129 * context class loader at the time of the constructor invocation will be used. |
133 * context class loader at the time of {@link #createLinker()} invocation will be used. |
130 * |
134 * |
131 * @param classLoader the class loader used for the autodiscovery of available linkers. |
135 * @param classLoader the class loader used for the autodiscovery of available linkers. |
132 */ |
136 */ |
133 public void setClassLoader(ClassLoader classLoader) { |
137 public void setClassLoader(ClassLoader classLoader) { |
134 this.classLoader = classLoader; |
138 this.classLoader = classLoader; |
|
139 classLoaderExplicitlySet = true; |
135 } |
140 } |
136 |
141 |
137 /** |
142 /** |
138 * Sets the prioritized linkers. Language runtimes using this framework will usually precreate at least the linker |
143 * Sets the prioritized linkers. Language runtimes using this framework will usually precreate at least the linker |
139 * for their own language. These linkers will be consulted first in the resulting dynamic linker, before any |
144 * for their own language. These linkers will be consulted first in the resulting dynamic linker, before any |
258 final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses = |
263 final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses = |
259 new HashSet<>(); |
264 new HashSet<>(); |
260 addClasses(knownLinkerClasses, prioritizedLinkers); |
265 addClasses(knownLinkerClasses, prioritizedLinkers); |
261 addClasses(knownLinkerClasses, fallbackLinkers); |
266 addClasses(knownLinkerClasses, fallbackLinkers); |
262 |
267 |
263 final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(classLoader); |
268 final ClassLoader effectiveClassLoader = classLoaderExplicitlySet ? classLoader : getThreadContextClassLoader(); |
|
269 final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(effectiveClassLoader); |
264 // Now, concatenate ... |
270 // Now, concatenate ... |
265 final List<GuardingDynamicLinker> linkers = |
271 final List<GuardingDynamicLinker> linkers = |
266 new ArrayList<>(prioritizedLinkers.size() + discovered.size() |
272 new ArrayList<>(prioritizedLinkers.size() + discovered.size() |
267 + fallbackLinkers.size()); |
273 + fallbackLinkers.size()); |
268 // ... prioritized linkers, ... |
274 // ... prioritized linkers, ... |
301 |
307 |
302 return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite), |
308 return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite), |
303 runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); |
309 runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); |
304 } |
310 } |
305 |
311 |
|
312 private static ClassLoader getThreadContextClassLoader() { |
|
313 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
|
314 @Override |
|
315 public ClassLoader run() { |
|
316 return Thread.currentThread().getContextClassLoader(); |
|
317 } |
|
318 }); |
|
319 } |
|
320 |
306 private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses, |
321 private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses, |
307 List<? extends GuardingDynamicLinker> linkers) { |
322 List<? extends GuardingDynamicLinker> linkers) { |
308 for(GuardingDynamicLinker linker: linkers) { |
323 for(GuardingDynamicLinker linker: linkers) { |
309 knownLinkerClasses.add(linker.getClass()); |
324 knownLinkerClasses.add(linker.getClass()); |
310 } |
325 } |