2368 private static final Unsafe unsafe = Unsafe.getUnsafe(); |
2369 private static final Unsafe unsafe = Unsafe.getUnsafe(); |
2369 // offset of Class.reflectionData instance field |
2370 // offset of Class.reflectionData instance field |
2370 private static final long reflectionDataOffset; |
2371 private static final long reflectionDataOffset; |
2371 // offset of Class.annotationType instance field |
2372 // offset of Class.annotationType instance field |
2372 private static final long annotationTypeOffset; |
2373 private static final long annotationTypeOffset; |
|
2374 // offset of Class.annotationData instance field |
|
2375 private static final long annotationDataOffset; |
2373 |
2376 |
2374 static { |
2377 static { |
2375 Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches |
2378 Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches |
2376 reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); |
2379 reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); |
2377 annotationTypeOffset = objectFieldOffset(fields, "annotationType"); |
2380 annotationTypeOffset = objectFieldOffset(fields, "annotationType"); |
|
2381 annotationDataOffset = objectFieldOffset(fields, "annotationData"); |
2378 } |
2382 } |
2379 |
2383 |
2380 private static long objectFieldOffset(Field[] fields, String fieldName) { |
2384 private static long objectFieldOffset(Field[] fields, String fieldName) { |
2381 Field field = searchFields(fields, fieldName); |
2385 Field field = searchFields(fields, fieldName); |
2382 if (field == null) { |
2386 if (field == null) { |
2394 static <T> boolean casAnnotationType(Class<?> clazz, |
2398 static <T> boolean casAnnotationType(Class<?> clazz, |
2395 AnnotationType oldType, |
2399 AnnotationType oldType, |
2396 AnnotationType newType) { |
2400 AnnotationType newType) { |
2397 return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); |
2401 return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); |
2398 } |
2402 } |
|
2403 |
|
2404 static <T> boolean casAnnotationData(Class<?> clazz, |
|
2405 AnnotationData oldData, |
|
2406 AnnotationData newData) { |
|
2407 return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData); |
|
2408 } |
2399 } |
2409 } |
2400 |
2410 |
2401 /** |
2411 /** |
2402 * Reflection support. |
2412 * Reflection support. |
2403 */ |
2413 */ |
2404 |
2414 |
2405 // Caches for certain reflective results |
2415 // Caches for certain reflective results |
2406 private static boolean useCaches = true; |
2416 private static boolean useCaches = true; |
2407 |
2417 |
2408 // reflection data that might get invalidated when JVM TI RedefineClasses() is called |
2418 // reflection data that might get invalidated when JVM TI RedefineClasses() is called |
2409 static class ReflectionData<T> { |
2419 private static class ReflectionData<T> { |
2410 volatile Field[] declaredFields; |
2420 volatile Field[] declaredFields; |
2411 volatile Field[] publicFields; |
2421 volatile Field[] publicFields; |
2412 volatile Method[] declaredMethods; |
2422 volatile Method[] declaredMethods; |
2413 volatile Method[] publicMethods; |
2423 volatile Method[] publicMethods; |
2414 volatile Constructor<T>[] declaredConstructors; |
2424 volatile Constructor<T>[] declaredConstructors; |
3294 @Override |
3301 @Override |
3295 @SuppressWarnings("unchecked") |
3302 @SuppressWarnings("unchecked") |
3296 public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) { |
3303 public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) { |
3297 Objects.requireNonNull(annotationClass); |
3304 Objects.requireNonNull(annotationClass); |
3298 |
3305 |
3299 initAnnotationsIfNecessary(); |
3306 return (A) annotationData().declaredAnnotations.get(annotationClass); |
3300 return (A) declaredAnnotations.get(annotationClass); |
|
3301 } |
3307 } |
3302 |
3308 |
3303 /** |
3309 /** |
3304 * @throws NullPointerException {@inheritDoc} |
3310 * @throws NullPointerException {@inheritDoc} |
3305 * @since 1.8 |
3311 * @since 1.8 |
3306 */ |
3312 */ |
3307 @Override |
3313 @Override |
3308 public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) { |
3314 public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) { |
3309 Objects.requireNonNull(annotationClass); |
3315 Objects.requireNonNull(annotationClass); |
3310 |
3316 |
3311 initAnnotationsIfNecessary(); |
3317 return AnnotationSupport.getMultipleAnnotations(annotationData().declaredAnnotations, annotationClass); |
3312 return AnnotationSupport.getMultipleAnnotations(declaredAnnotations, annotationClass); |
|
3313 } |
3318 } |
3314 |
3319 |
3315 /** |
3320 /** |
3316 * @since 1.5 |
3321 * @since 1.5 |
3317 */ |
3322 */ |
3318 public Annotation[] getDeclaredAnnotations() { |
3323 public Annotation[] getDeclaredAnnotations() { |
3319 initAnnotationsIfNecessary(); |
3324 return AnnotationParser.toArray(annotationData().declaredAnnotations); |
3320 return AnnotationParser.toArray(declaredAnnotations); |
3325 } |
|
3326 |
|
3327 // annotation data that might get invalidated when JVM TI RedefineClasses() is called |
|
3328 private static class AnnotationData { |
|
3329 final Map<Class<? extends Annotation>, Annotation> annotations; |
|
3330 final Map<Class<? extends Annotation>, Annotation> declaredAnnotations; |
|
3331 |
|
3332 // Value of classRedefinedCount when we created this AnnotationData instance |
|
3333 final int redefinedCount; |
|
3334 |
|
3335 AnnotationData(Map<Class<? extends Annotation>, Annotation> annotations, |
|
3336 Map<Class<? extends Annotation>, Annotation> declaredAnnotations, |
|
3337 int redefinedCount) { |
|
3338 this.annotations = annotations; |
|
3339 this.declaredAnnotations = declaredAnnotations; |
|
3340 this.redefinedCount = redefinedCount; |
|
3341 } |
3321 } |
3342 } |
3322 |
3343 |
3323 // Annotations cache |
3344 // Annotations cache |
3324 private transient Map<Class<? extends Annotation>, Annotation> annotations; |
3345 @SuppressWarnings("UnusedDeclaration") |
3325 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; |
3346 private volatile transient AnnotationData annotationData; |
3326 // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields |
3347 |
3327 private transient int lastAnnotationsRedefinedCount = 0; |
3348 private AnnotationData annotationData() { |
3328 |
3349 while (true) { // retry loop |
3329 // Clears cached values that might possibly have been obsoleted by |
3350 AnnotationData annotationData = this.annotationData; |
3330 // a class redefinition. |
3351 int classRedefinedCount = this.classRedefinedCount; |
3331 private void clearAnnotationCachesOnClassRedefinition() { |
3352 if (annotationData != null && |
3332 if (lastAnnotationsRedefinedCount != classRedefinedCount) { |
3353 annotationData.redefinedCount == classRedefinedCount) { |
3333 annotations = declaredAnnotations = null; |
3354 return annotationData; |
3334 lastAnnotationsRedefinedCount = classRedefinedCount; |
3355 } |
3335 } |
3356 // null or stale annotationData -> optimistically create new instance |
3336 } |
3357 AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount); |
3337 |
3358 // try to install it |
3338 private synchronized void initAnnotationsIfNecessary() { |
3359 if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) { |
3339 clearAnnotationCachesOnClassRedefinition(); |
3360 // successfully installed new AnnotationData |
3340 if (annotations != null) |
3361 return newAnnotationData; |
3341 return; |
3362 } |
3342 declaredAnnotations = AnnotationParser.parseAnnotations( |
3363 } |
3343 getRawAnnotations(), getConstantPool(), this); |
3364 } |
|
3365 |
|
3366 private AnnotationData createAnnotationData(int classRedefinedCount) { |
|
3367 Map<Class<? extends Annotation>, Annotation> declaredAnnotations = |
|
3368 AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this); |
3344 Class<?> superClass = getSuperclass(); |
3369 Class<?> superClass = getSuperclass(); |
3345 if (superClass == null) { |
3370 Map<Class<? extends Annotation>, Annotation> annotations = null; |
|
3371 if (superClass != null) { |
|
3372 Map<Class<? extends Annotation>, Annotation> superAnnotations = |
|
3373 superClass.annotationData().annotations; |
|
3374 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superAnnotations.entrySet()) { |
|
3375 Class<? extends Annotation> annotationClass = e.getKey(); |
|
3376 if (AnnotationType.getInstance(annotationClass).isInherited()) { |
|
3377 if (annotations == null) { // lazy construction |
|
3378 annotations = new LinkedHashMap<>((Math.max( |
|
3379 declaredAnnotations.size(), |
|
3380 Math.min(12, declaredAnnotations.size() + superAnnotations.size()) |
|
3381 ) * 4 + 2) / 3 |
|
3382 ); |
|
3383 } |
|
3384 annotations.put(annotationClass, e.getValue()); |
|
3385 } |
|
3386 } |
|
3387 } |
|
3388 if (annotations == null) { |
|
3389 // no inherited annotations -> share the Map with declaredAnnotations |
3346 annotations = declaredAnnotations; |
3390 annotations = declaredAnnotations; |
3347 } else { |
3391 } else { |
3348 annotations = new HashMap<>(); |
3392 // at least one inherited annotation -> declared may override inherited |
3349 superClass.initAnnotationsIfNecessary(); |
|
3350 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) { |
|
3351 Class<? extends Annotation> annotationClass = e.getKey(); |
|
3352 if (AnnotationType.getInstance(annotationClass).isInherited()) |
|
3353 annotations.put(annotationClass, e.getValue()); |
|
3354 } |
|
3355 annotations.putAll(declaredAnnotations); |
3393 annotations.putAll(declaredAnnotations); |
3356 } |
3394 } |
|
3395 return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount); |
3357 } |
3396 } |
3358 |
3397 |
3359 // Annotation types cache their internal (AnnotationType) form |
3398 // Annotation types cache their internal (AnnotationType) form |
3360 |
3399 |
3361 @SuppressWarnings("UnusedDeclaration") |
3400 @SuppressWarnings("UnusedDeclaration") |