# HG changeset patch
# User shade
# Date 1371472102 -14400
# Node ID 7c8f4bafffa7bc48e82c7305fd43980c28a9cce9
# Parent bad604b15314b00c056392371572b057ffdec0ba
8016236: Class.getGenericInterfaces performance improvement
Summary: cache more reflective data and lookup results.
Reviewed-by: alanb, plevart, psandoz, dl
Contributed-by: Doug Lea
, Aleksey Shipilev
diff -r bad604b15314 -r 7c8f4bafffa7 src/share/classes/java/lang/Class.java
--- a/src/share/classes/java/lang/Class.java Sun Jun 16 22:36:41 2013 -0700
+++ b/src/share/classes/java/lang/Class.java Mon Jun 17 16:28:22 2013 +0400
@@ -708,8 +708,9 @@
*/
@SuppressWarnings("unchecked")
public TypeVariable>[] getTypeParameters() {
- if (getGenericSignature() != null)
- return (TypeVariable>[])getGenericInfo().getTypeParameters();
+ ClassRepository info = getGenericInfo();
+ if (info != null)
+ return (TypeVariable>[])info.getTypeParameters();
else
return (TypeVariable>[])new TypeVariable>[0];
}
@@ -759,15 +760,19 @@
* @since 1.5
*/
public Type getGenericSuperclass() {
- if (getGenericSignature() != null) {
- // Historical irregularity:
- // Generic signature marks interfaces with superclass = Object
- // but this API returns null for interfaces
- if (isInterface())
- return null;
- return getGenericInfo().getSuperclass();
- } else
+ ClassRepository info = getGenericInfo();
+ if (info == null) {
return getSuperclass();
+ }
+
+ // Historical irregularity:
+ // Generic signature marks interfaces with superclass = Object
+ // but this API returns null for interfaces
+ if (isInterface()) {
+ return null;
+ }
+
+ return info.getSuperclass();
}
/**
@@ -830,7 +835,23 @@
*
* @return an array of interfaces implemented by this class.
*/
- public native Class>[] getInterfaces();
+ public Class>[] getInterfaces() {
+ ReflectionData rd = reflectionData();
+ if (rd == null) {
+ // no cloning required
+ return getInterfaces0();
+ } else {
+ Class>[] interfaces = rd.interfaces;
+ if (interfaces == null) {
+ interfaces = getInterfaces0();
+ rd.interfaces = interfaces;
+ }
+ // defensively copy before handing over to user code
+ return interfaces.clone();
+ }
+ }
+
+ private native Class>[] getInterfaces0();
/**
* Returns the {@code Type}s representing the interfaces
@@ -882,10 +903,8 @@
* @since 1.5
*/
public Type[] getGenericInterfaces() {
- if (getGenericSignature() != null)
- return getGenericInfo().getSuperInterfaces();
- else
- return getInterfaces();
+ ClassRepository info = getGenericInfo();
+ return (info == null) ? getInterfaces() : info.getSuperInterfaces();
}
@@ -2313,6 +2332,8 @@
// Intermediate results for getFields and getMethods
volatile Field[] declaredPublicFields;
volatile Method[] declaredPublicMethods;
+ volatile Class>[] interfaces;
+
// Value of classRedefinedCount when we created this ReflectionData instance
final int redefinedCount;
@@ -2388,10 +2409,10 @@
}
// Generic signature handling
- private native String getGenericSignature();
+ private native String getGenericSignature0();
// Generic info repository; lazily initialized
- private transient ClassRepository genericInfo;
+ private volatile transient ClassRepository genericInfo;
// accessor for factory
private GenericsFactory getFactory() {
@@ -2399,15 +2420,20 @@
return CoreReflectionFactory.make(this, ClassScope.make(this));
}
- // accessor for generic info repository
+ // accessor for generic info repository;
+ // generic info is lazily initialized
private ClassRepository getGenericInfo() {
- // lazily initialize repository if necessary
+ ClassRepository genericInfo = this.genericInfo;
if (genericInfo == null) {
- // create and cache generic info repository
- genericInfo = ClassRepository.make(getGenericSignature(),
- getFactory());
+ String signature = getGenericSignature0();
+ if (signature == null) {
+ genericInfo = ClassRepository.NONE;
+ } else {
+ genericInfo = ClassRepository.make(signature, getFactory());
+ }
+ this.genericInfo = genericInfo;
}
- return genericInfo; //return cached repository
+ return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
}
// Annotations handling
diff -r bad604b15314 -r 7c8f4bafffa7 src/share/classes/sun/reflect/generics/repository/ClassRepository.java
--- a/src/share/classes/sun/reflect/generics/repository/ClassRepository.java Sun Jun 16 22:36:41 2013 -0700
+++ b/src/share/classes/sun/reflect/generics/repository/ClassRepository.java Mon Jun 17 16:28:22 2013 +0400
@@ -40,6 +40,8 @@
*/
public class ClassRepository extends GenericDeclRepository {
+ public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
+
private Type superclass; // caches the generic superclass info
private Type[] superInterfaces; // caches the generic superinterface info
diff -r bad604b15314 -r 7c8f4bafffa7 src/share/native/java/lang/Class.c
--- a/src/share/native/java/lang/Class.c Sun Jun 16 22:36:41 2013 -0700
+++ b/src/share/native/java/lang/Class.c Mon Jun 17 16:28:22 2013 +0400
@@ -55,7 +55,7 @@
static JNINativeMethod methods[] = {
{"getName0", "()" STR, (void *)&JVM_GetClassName},
{"getSuperclass", "()" CLS, NULL},
- {"getInterfaces", "()[" CLS, (void *)&JVM_GetClassInterfaces},
+ {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
{"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
{"isInterface", "()Z", (void *)&JVM_IsInterface},
{"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
@@ -70,7 +70,7 @@
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
{"getDeclaringClass", "()" CLS, (void *)&JVM_GetDeclaringClass},
- {"getGenericSignature", "()" STR, (void *)&JVM_GetClassSignature},
+ {"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
{"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},