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 ----