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