src/share/classes/java/lang/Class.java
Print this page
*** 2396,2405 ****
--- 2396,2444 ----
}
return name;
}
/**
+ * Atomic operations support.
+ */
+ private static class Atomic {
+ // initialize Unsafe machinery here, since we need to call Class.class instance method
+ // and have to avoid calling it in the static initializer of the Class class...
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ // offset of Class.reflectionData instance field
+ private static final long reflectionDataOffset;
+ // offset of Class.annotationType instance field
+ private static final long annotationTypeOffset;
+
+ static {
+ Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
+ reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
+ annotationTypeOffset = objectFieldOffset(fields, "annotationType");
+ }
+
+ private static long objectFieldOffset(Field[] fields, String fieldName) {
+ Field field = searchFields(fields, fieldName);
+ if (field == null) {
+ throw new Error("No " + fieldName + " field found in java.lang.Class");
+ }
+ return unsafe.objectFieldOffset(field);
+ }
+
+ static <T> boolean casReflectionData(Class<?> clazz,
+ SoftReference<ReflectionData<T>> oldData,
+ SoftReference<ReflectionData<T>> newData) {
+ return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
+ }
+
+ static <T> boolean casAnnotationType(Class<?> clazz,
+ AnnotationType oldType,
+ AnnotationType newType) {
+ return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
+ }
+ }
+
+ /**
* Reflection support.
*/
// Caches for certain reflective results
private static boolean useCaches = true;
*** 2421,2453 ****
final int redefinedCount;
ReflectionData(int redefinedCount) {
this.redefinedCount = redefinedCount;
}
-
- // initialize Unsafe machinery here, since we need to call Class.class instance method
- // and have to avoid calling it in the static initializer of the Class class...
- private static final Unsafe unsafe;
- // offset of Class.reflectionData instance field
- private static final long reflectionDataOffset;
-
- static {
- unsafe = Unsafe.getUnsafe();
- // bypass caches
- Field reflectionDataField = searchFields(Class.class.getDeclaredFields0(false),
- "reflectionData");
- if (reflectionDataField == null) {
- throw new Error("No reflectionData field found in java.lang.Class");
- }
- reflectionDataOffset = unsafe.objectFieldOffset(reflectionDataField);
- }
-
- static <T> boolean compareAndSwap(Class<?> clazz,
- SoftReference<ReflectionData<T>> oldData,
- SoftReference<ReflectionData<T>> newData) {
- return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
- }
}
private volatile transient SoftReference<ReflectionData<T>> reflectionData;
// Incremented by the VM on each call to JVM TI RedefineClasses()
--- 2460,2469 ----
*** 2475,2485 ****
if (!useCaches) return null;
while (true) {
ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
// try to CAS it...
! if (ReflectionData.compareAndSwap(this, oldReflectionData, new SoftReference<>(rd))) {
return rd;
}
// else retry
oldReflectionData = this.reflectionData;
classRedefinedCount = this.classRedefinedCount;
--- 2491,2501 ----
if (!useCaches) return null;
while (true) {
ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
// try to CAS it...
! if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
return rd;
}
// else retry
oldReflectionData = this.reflectionData;
classRedefinedCount = this.classRedefinedCount;
*** 2518,2528 ****
}
return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
}
// Annotations handling
! private native byte[] getRawAnnotations();
// Since 1.8
native byte[] getRawTypeAnnotations();
static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
}
--- 2534,2544 ----
}
return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
}
// Annotations handling
! native byte[] getRawAnnotations();
// Since 1.8
native byte[] getRawTypeAnnotations();
static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
}
*** 3248,3259 ****
* {@code Class} objects that it is willing to accept. A cast would
* generate a compile-time warning, as the correctness of the cast
* could not be checked at runtime (because generic types are implemented
* by erasure).
*
- * @param <U> the type to cast this class object to
- * @param clazz the class of the type to cast this class object to
* @return this {@code Class} object, cast to represent a subclass of
* the specified class object.
* @throws ClassCastException if this {@code Class} object does not
* represent a subclass of the specified class (here "subclass" includes
* the class itself).
--- 3264,3273 ----
*** 3378,3391 ****
}
}
// Annotation types cache their internal (AnnotationType) form
! private AnnotationType annotationType;
! void setAnnotationType(AnnotationType type) {
! annotationType = type;
}
AnnotationType getAnnotationType() {
return annotationType;
}
--- 3392,3406 ----
}
}
// Annotation types cache their internal (AnnotationType) form
! @SuppressWarnings("UnusedDeclaration")
! private volatile transient AnnotationType annotationType;
! boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) {
! return Atomic.casAnnotationType(this, oldType, newType);
}
AnnotationType getAnnotationType() {
return annotationType;
}
*** 3405,3415 ****
* indicate an annotated superclass, the return value is null.
*
* If this Class represents either the Object class, an interface type, an
* array type, a primitive type, or void, the return value is null.
*
- * @return an object representing the superclass
* @since 1.8
*/
public AnnotatedType getAnnotatedSuperclass() {
return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
}
--- 3420,3429 ----
*** 3437,3447 ****
* array of length 0.
*
* If this Class represents either the Object class, an array type, a
* primitive type, or void, the return value is an array of length 0.
*
- * @return an array representing the superinterfaces
* @since 1.8
*/
public AnnotatedType[] getAnnotatedInterfaces() {
return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
}
--- 3451,3460 ----