src/share/classes/java/lang/Class.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** 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,7 **** --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 325,335 **** --- 325,336 ---- { // NOTE: the following code may not be strictly correct under // 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" ); }
*** 345,368 **** --- 346,369 ---- public Void run() { c.setAccessible(true); return null; } }); ! rh.cachedConstructor = c; } catch (NoSuchMethodException e) { throw (InstantiationException) new InstantiationException(getName()).initCause(e); } } ! Constructor<T> 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 (rh.newInstanceCallerCache != caller) { Reflection.ensureMemberAccess(caller, this, null, modifiers); ! rh.newInstanceCallerCache = caller; } } // Run constructor try { return tmpConstructor.newInstance((Object[])null);
*** 370,381 **** --- 371,380 ---- Unsafe.getUnsafe().throwException(e.getTargetException()); // Not reached return null; } } private volatile transient Constructor<T> cachedConstructor; private volatile transient Class<?> newInstanceCallerCache; /** * Determines if the specified {@code Object} is assignment-compatible * with the object represented by this {@code Class}. This method is
*** 2208,2219 **** --- 2207,2251 ---- /** * Reflection support. */ ! // 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; + + // Helper object to hold reflection specific fields + private volatile transient ReflectionHelper<T> rh; + + /** + * Return a reference to the ReflectionHelper - creating it if necessary + */ + private ReflectionHelper<T> 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<T> raw_rh() { + return rh; + } + + + static class ReflectionHelper<T> { + + private transient volatile Constructor<T> cachedConstructor; + private transient volatile Class<?> newInstanceCallerCache; + private volatile transient SoftReference<Field[]> declaredFields; private volatile transient SoftReference<Field[]> publicFields; private volatile transient SoftReference<Method[]> declaredMethods; private volatile transient SoftReference<Method[]> publicMethods; private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
*** 2220,2229 **** --- 2252,2268 ---- private volatile transient SoftReference<Constructor<T>[]> publicConstructors; // Intermediate results for getFields and getMethods private volatile transient SoftReference<Field[]> declaredPublicFields; private volatile transient SoftReference<Method[]> 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; // Value of classRedefinedCount when we last cleared the cached values
*** 2232,2244 **** --- 2271,2286 ---- // Clears cached values that might possibly have been obsoleted by // 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 // of annotations) ensures that no thread sees the update to // lastRedefinedCount before seeing the caches cleared.
*** 2286,2315 **** --- 2328,2358 ---- // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyField. private Field[] privateGetDeclaredFields(boolean publicOnly) { checkInitted(); Field[] res = null; + final ReflectionHelper<T> rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { ! if (rh.declaredPublicFields != null) { ! res = rh.declaredPublicFields.get(); } } else { ! if (rh.declaredFields != null) { ! res = rh.declaredFields.get(); } } if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); if (useCaches) { if (publicOnly) { ! rh.declaredPublicFields = new SoftReference<>(res); } else { ! rh.declaredFields = new SoftReference<>(res); } } return res; }
*** 2317,2330 **** --- 2360,2374 ---- // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyField. private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) { checkInitted(); Field[] res = null; + final ReflectionHelper<T> rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); ! if (rh.publicFields != null) { ! res = rh.publicFields.get(); } if (res != null) return res; } // No cached value available; compute value recursively.
*** 2355,2365 **** --- 2399,2409 ---- } res = new Field[fields.size()]; fields.toArray(res); if (useCaches) { ! rh.publicFields = new SoftReference<>(res); } return res; } private static void addAll(Collection<Field> c, Field[] o) {
*** 2379,2397 **** --- 2423,2442 ---- // objects must NOT be propagated to the outside world, but must // instead be copied via ReflectionFactory.copyConstructor. private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); Constructor<T>[] res = null; + final ReflectionHelper<T> rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { ! if (rh.publicConstructors != null) { ! res = rh.publicConstructors.get(); } } else { ! if (rh.declaredConstructors != null) { ! res = rh.declaredConstructors.get(); } } if (res != null) return res; } // No cached value available; request value from VM
*** 2402,2414 **** --- 2447,2459 ---- } else { res = getDeclaredConstructors0(publicOnly); } if (useCaches) { if (publicOnly) { ! rh.publicConstructors = new SoftReference<>(res); } else { ! rh.declaredConstructors = new SoftReference<>(res); } } return res; }
*** 2422,2451 **** --- 2467,2497 ---- // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyMethod. private Method[] privateGetDeclaredMethods(boolean publicOnly) { checkInitted(); Method[] res = null; + final ReflectionHelper<T> rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { ! if (rh.declaredPublicMethods != null) { ! res = rh.declaredPublicMethods.get(); } } else { ! if (rh.declaredMethods != null) { ! res = rh.declaredMethods.get(); } } if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); if (useCaches) { if (publicOnly) { ! rh.declaredPublicMethods = new SoftReference<>(res); } else { ! rh.declaredMethods = new SoftReference<>(res); } } return res; }
*** 2544,2557 **** --- 2590,2604 ---- // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyMethod. private Method[] privateGetPublicMethods() { checkInitted(); Method[] res = null; + final ReflectionHelper<T> rh = rh(); if (useCaches) { clearCachesOnClassRedefinition(); ! if (rh.publicMethods != null) { ! res = rh.publicMethods.get(); } if (res != null) return res; } // No cached value available; compute value recursively.
*** 2597,2607 **** --- 2644,2654 ---- } methods.addAllIfNotPresent(inheritedMethods); methods.compactAndTrim(); res = methods.getArray(); if (useCaches) { ! rh.publicMethods = new SoftReference<>(res); } return res; }
*** 3116,3121 **** --- 3163,3169 ---- } AnnotationType getAnnotationType() { return annotationType; } + }

src/share/classes/java/lang/Class.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File