From 21d2a75a1623b7e876e0734d101206663728c3d2 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 7 Dec 2009 12:29:14 +0000 Subject: [PATCH] 6902010: (cl) Delay initialization of ClassLoader.parallelLoaders Reviewed-by: forax, mchung, valeriep --- .../share/classes/java/lang/ClassLoader.java | 75 ++++++++++++------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index 323240b395c..bb4ea98694b 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -175,15 +175,8 @@ import sun.security.util.SecurityConstants; public abstract class ClassLoader { private static native void registerNatives(); - - // Set of classes which are registered as parallel capable class loaders - private static final Set> parallelLoaders - = Collections.newSetFromMap(Collections.synchronizedMap - (new WeakHashMap, Boolean>())); - static { registerNatives(); - parallelLoaders.add(ClassLoader.class); } // The parent class loader for delegation @@ -191,6 +184,52 @@ public abstract class ClassLoader { // must be added *after* it. private final ClassLoader parent; + /** + * Encapsulates the set of parallel capable loader types. + */ + private static class ParallelLoaders { + private ParallelLoaders() {} + + // the set of parallel capable loader types + private static final Set> loaderTypes = + Collections.newSetFromMap( + new WeakHashMap, Boolean>()); + static { + synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); } + } + + /** + * Registers the given class loader type as parallel capabale. + * Returns {@code true} is successfully registered; {@code false} if + * loader's super class is not registered. + */ + static boolean register(Class c) { + synchronized (loaderTypes) { + if (loaderTypes.contains(c.getSuperclass())) { + // register the class loader as parallel capable + // if and only if all of its super classes are. + // Note: given current classloading sequence, if + // the immediate super class is parallel capable, + // all the super classes higher up must be too. + loaderTypes.add(c); + return true; + } else { + return false; + } + } + } + + /** + * Returns {@code true} if the given class loader type is + * registered as parallel capable. + */ + static boolean isRegistered(Class c) { + synchronized (loaderTypes) { + return loaderTypes.contains(c); + } + } + } + // Maps class name to the corresponding lock object when the current // class loader is parallel capable. // Note: VM also uses this field to decide if the current class loader @@ -237,7 +276,7 @@ public abstract class ClassLoader { private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; - if (parallelLoaders.contains(this.getClass())) { + if (ParallelLoaders.isRegistered(this.getClass())) { parallelLockMap = new ConcurrentHashMap(); package2certs = new ConcurrentHashMap(); domains = @@ -1194,24 +1233,7 @@ public abstract class ClassLoader { * @since 1.7 */ protected static boolean registerAsParallelCapable() { - Class caller = getCaller(1); - Class superCls = caller.getSuperclass(); - boolean result = false; - // Explicit synchronization needed for composite action - synchronized (parallelLoaders) { - if (!parallelLoaders.contains(caller)) { - if (parallelLoaders.contains(superCls)) { - // register the immediate caller as parallel capable - // if and only if all of its super classes are. - // Note: given current classloading sequence, if - // the immediate super class is parallel capable, - // all the super classes higher up must be too. - result = true; - parallelLoaders.add(caller); - } - } else result = true; - } - return result; + return ParallelLoaders.register(getCaller(1)); } /** @@ -2174,4 +2196,3 @@ class SystemClassLoaderAction return sys; } } -