src/share/classes/java/lang/reflect/Field.java
Print this page
rev 10466 : 8054987: (reflect) Add sharing of annotations between instances of Executable
Reviewed-by: duke
*** 79,88 ****
--- 79,91 ----
// Cached field accessor created with override
private FieldAccessor overrideFieldAccessor;
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
+ //
+ // If this branching structure would ever contain cycles, deadlocks can
+ // occur in annotation code.
private Field root;
// Generics infrastructure
private String getGenericSignature() {return signature;}
*** 139,148 ****
--- 142,154 ----
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
+ if (this.root != null)
+ throw new IllegalArgumentException("Can not copy a non-root Field");
+
Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
res.root = this;
// Might as well eagerly propagate this if already present
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
*** 1135,1149 ****
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
declaredAnnotations = AnnotationParser.parseAnnotations(
! annotations, sun.misc.SharedSecrets.getJavaLangAccess().
! getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
return declaredAnnotations;
}
private native byte[] getTypeAnnotationBytes0();
--- 1141,1160 ----
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
+ Field root = this.root;
+ if (root != null) {
+ declaredAnnotations = root.declaredAnnotations();
+ } else {
declaredAnnotations = AnnotationParser.parseAnnotations(
! annotations,
! sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
+ }
return declaredAnnotations;
}
private native byte[] getTypeAnnotationBytes0();