--- old/src/share/classes/java/lang/Class.java Wed Apr 4 22:50:19 2012 +++ new/src/share/classes/java/lang/Class.java Wed Apr 4 22:50:16 2012 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,14 +108,14 @@ * @since JDK1.0 */ public final - class Class implements java.io.Serializable, - java.lang.reflect.GenericDeclaration, - java.lang.reflect.Type, - java.lang.reflect.AnnotatedElement { + class Class implements java.io.Serializable, + java.lang.reflect.GenericDeclaration, + java.lang.reflect.Type, + java.lang.reflect.AnnotatedElement { private static final int ANNOTATION= 0x00002000; private static final int ENUM = 0x00004000; private static final int SYNTHETIC = 0x00001000; - + private static native void registerNatives(); static { registerNatives(); @@ -327,7 +327,8 @@ // the current Java memory model. // Constructor lookup - if (cachedConstructor == null) { + final ReflectionHelper rh = rh(); + if (rh.cachedConstructor == null) { if (this == Class.class) { throw new IllegalAccessException( "Can not call newInstance() on the Class for java.lang.Class" @@ -347,20 +348,20 @@ return null; } }); - cachedConstructor = c; + rh.cachedConstructor = c; } catch (NoSuchMethodException e) { throw (InstantiationException) new InstantiationException(getName()).initCause(e); } } - Constructor tmpConstructor = cachedConstructor; + Constructor tmpConstructor = rh.cachedConstructor; // Security check (same as in java.lang.reflect.Constructor) int modifiers = tmpConstructor.getModifiers(); if (!Reflection.quickCheckMemberAccess(this, modifiers)) { Class caller = Reflection.getCallerClass(3); - if (newInstanceCallerCache != caller) { + if (rh.newInstanceCallerCache != caller) { Reflection.ensureMemberAccess(caller, this, null, modifiers); - newInstanceCallerCache = caller; + rh.newInstanceCallerCache = caller; } } // Run constructor @@ -372,8 +373,6 @@ return null; } } - private volatile transient Constructor cachedConstructor; - private volatile transient Class newInstanceCallerCache; /** @@ -2210,18 +2209,58 @@ * Reflection support. */ - // Caches for certain reflective results + // Caches for certain reflective results are stored + // in an auxiliary helper object - so that we only + // need allocate them if used + private static boolean useCaches = true; - private volatile transient SoftReference declaredFields; - private volatile transient SoftReference publicFields; - private volatile transient SoftReference declaredMethods; - private volatile transient SoftReference publicMethods; - private volatile transient SoftReference[]> declaredConstructors; - private volatile transient SoftReference[]> publicConstructors; - // Intermediate results for getFields and getMethods - private volatile transient SoftReference declaredPublicFields; - private volatile transient SoftReference declaredPublicMethods; + // Helper object to hold reflection specific fields + private volatile transient ReflectionHelper rh; + + /** + * Return a reference to the ReflectionHelper - creating it if necessary + */ + private ReflectionHelper rh() { + if (rh == null) { + synchronized(this) { + if (rh == null) + rh = new ReflectionHelper<>(); + } + } + return rh; + } + + /** + * Return a reference to the ReflectionHelper if it exists + */ + private ReflectionHelper raw_rh() { + return rh; + } + + + static class ReflectionHelper { + + private transient volatile Constructor cachedConstructor; + private transient volatile Class newInstanceCallerCache; + + private volatile transient SoftReference declaredFields; + private volatile transient SoftReference publicFields; + private volatile transient SoftReference declaredMethods; + private volatile transient SoftReference publicMethods; + private volatile transient SoftReference[]> declaredConstructors; + private volatile transient SoftReference[]> publicConstructors; + // Intermediate results for getFields and getMethods + private volatile transient SoftReference declaredPublicFields; + private volatile transient SoftReference declaredPublicMethods; + + private void clearCachesOnClassRedefinition() { + declaredFields = publicFields = declaredPublicFields = null; + declaredMethods = publicMethods = declaredPublicMethods = null; + declaredConstructors = publicConstructors = null; + } + } + // Incremented by the VM on each call to JVM TI RedefineClasses() // that redefines this class or a superclass. private volatile transient int classRedefinedCount = 0; @@ -2234,9 +2273,12 @@ // a class redefinition. private void clearCachesOnClassRedefinition() { if (lastRedefinedCount != classRedefinedCount) { - declaredFields = publicFields = declaredPublicFields = null; - declaredMethods = publicMethods = declaredPublicMethods = null; - declaredConstructors = publicConstructors = null; + // If there's no ReflectionHelper then there is nothing to clear, + // and we don't want to create the ReflectionHelper unnecessarily + final ReflectionHelper rh = raw_rh(); + if (rh != null) + rh.clearCachesOnClassRedefinition(); + annotations = declaredAnnotations = null; // Use of "volatile" (and synchronization by caller in the case @@ -2288,15 +2330,16 @@ private Field[] privateGetDeclaredFields(boolean publicOnly) { checkInitted(); Field[] res = null; + final ReflectionHelper rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { - if (declaredPublicFields != null) { - res = declaredPublicFields.get(); + if (rh.declaredPublicFields != null) { + res = rh.declaredPublicFields.get(); } } else { - if (declaredFields != null) { - res = declaredFields.get(); + if (rh.declaredFields != null) { + res = rh.declaredFields.get(); } } if (res != null) return res; @@ -2305,9 +2348,9 @@ res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicFields = new SoftReference<>(res); + rh.declaredPublicFields = new SoftReference<>(res); } else { - declaredFields = new SoftReference<>(res); + rh.declaredFields = new SoftReference<>(res); } } return res; @@ -2319,10 +2362,11 @@ private Field[] privateGetPublicFields(Set> traversedInterfaces) { checkInitted(); Field[] res = null; + final ReflectionHelper rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); - if (publicFields != null) { - res = publicFields.get(); + if (rh.publicFields != null) { + res = rh.publicFields.get(); } if (res != null) return res; } @@ -2357,7 +2401,7 @@ res = new Field[fields.size()]; fields.toArray(res); if (useCaches) { - publicFields = new SoftReference<>(res); + rh.publicFields = new SoftReference<>(res); } return res; } @@ -2381,15 +2425,16 @@ private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); Constructor[] res = null; + final ReflectionHelper rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { - if (publicConstructors != null) { - res = publicConstructors.get(); + if (rh.publicConstructors != null) { + res = rh.publicConstructors.get(); } } else { - if (declaredConstructors != null) { - res = declaredConstructors.get(); + if (rh.declaredConstructors != null) { + res = rh.declaredConstructors.get(); } } if (res != null) return res; @@ -2404,9 +2449,9 @@ } if (useCaches) { if (publicOnly) { - publicConstructors = new SoftReference<>(res); + rh.publicConstructors = new SoftReference<>(res); } else { - declaredConstructors = new SoftReference<>(res); + rh.declaredConstructors = new SoftReference<>(res); } } return res; @@ -2424,15 +2469,16 @@ private Method[] privateGetDeclaredMethods(boolean publicOnly) { checkInitted(); Method[] res = null; + final ReflectionHelper rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { - if (declaredPublicMethods != null) { - res = declaredPublicMethods.get(); + if (rh.declaredPublicMethods != null) { + res = rh.declaredPublicMethods.get(); } } else { - if (declaredMethods != null) { - res = declaredMethods.get(); + if (rh.declaredMethods != null) { + res = rh.declaredMethods.get(); } } if (res != null) return res; @@ -2441,9 +2487,9 @@ res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicMethods = new SoftReference<>(res); + rh.declaredPublicMethods = new SoftReference<>(res); } else { - declaredMethods = new SoftReference<>(res); + rh.declaredMethods = new SoftReference<>(res); } } return res; @@ -2546,10 +2592,11 @@ private Method[] privateGetPublicMethods() { checkInitted(); Method[] res = null; + final ReflectionHelper rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); - if (publicMethods != null) { - res = publicMethods.get(); + if (rh.publicMethods != null) { + res = rh.publicMethods.get(); } if (res != null) return res; } @@ -2599,7 +2646,7 @@ methods.compactAndTrim(); res = methods.getArray(); if (useCaches) { - publicMethods = new SoftReference<>(res); + rh.publicMethods = new SoftReference<>(res); } return res; } @@ -3118,4 +3165,5 @@ AnnotationType getAnnotationType() { return annotationType; } + }