OpenJDK / jdk8u / jdk8u / jdk
changeset 11555:f8a528d0379d
8143185: Cleanup for handling proxies
Reviewed-by: chegar
author | robm |
---|---|
date | Tue, 01 Dec 2015 22:38:16 +0000 |
parents | af660750b2f4 |
children | a1679c44c8b2 |
files | src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java |
diffstat | 1 files changed, 45 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Tue Dec 01 08:58:28 2015 -0500 +++ b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Tue Dec 01 22:38:16 2015 +0000 @@ -25,6 +25,7 @@ package sun.reflect.annotation; +import java.io.ObjectInputStream; import java.lang.annotation.*; import java.lang.reflect.*; import java.io.Serializable; @@ -425,35 +426,72 @@ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); + ObjectInputStream.GetField fields = s.readFields(); + + @SuppressWarnings("unchecked") + Class<? extends Annotation> t = (Class<? extends Annotation>)fields.get("type", null); + @SuppressWarnings("unchecked") + Map<String, Object> streamVals = (Map<String, Object>)fields.get("memberValues", null); // Check to make sure that types have not evolved incompatibly AnnotationType annotationType = null; try { - annotationType = AnnotationType.getInstance(type); + annotationType = AnnotationType.getInstance(t); } catch(IllegalArgumentException e) { // Class is no longer an annotation type; time to punch out throw new java.io.InvalidObjectException("Non-annotation type in annotation serial stream"); } Map<String, Class<?>> memberTypes = annotationType.memberTypes(); + // consistent with runtime Map type + Map<String, Object> mv = new LinkedHashMap<>(); // If there are annotation members without values, that // situation is handled by the invoke method. - for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) { + for (Map.Entry<String, Object> memberValue : streamVals.entrySet()) { String name = memberValue.getKey(); + Object value = null; Class<?> memberType = memberTypes.get(name); if (memberType != null) { // i.e. member still exists - Object value = memberValue.getValue(); + value = memberValue.getValue(); if (!(memberType.isInstance(value) || value instanceof ExceptionProxy)) { - memberValue.setValue( - new AnnotationTypeMismatchExceptionProxy( + value = new AnnotationTypeMismatchExceptionProxy( value.getClass() + "[" + value + "]").setMember( - annotationType.members().get(name))); + annotationType.members().get(name)); } } + mv.put(name, value); + } + + UnsafeAccessor.setType(this, t); + UnsafeAccessor.setMemberValues(this, mv); + } + + private static class UnsafeAccessor { + private static final sun.misc.Unsafe unsafe; + private static final long typeOffset; + private static final long memberValuesOffset; + static { + try { + unsafe = sun.misc.Unsafe.getUnsafe(); + typeOffset = unsafe.objectFieldOffset + (AnnotationInvocationHandler.class.getDeclaredField("type")); + memberValuesOffset = unsafe.objectFieldOffset + (AnnotationInvocationHandler.class.getDeclaredField("memberValues")); + } catch (Exception ex) { + throw new ExceptionInInitializerError(ex); + } + } + static void setType(AnnotationInvocationHandler o, + Class<? extends Annotation> type) { + unsafe.putObject(o, typeOffset, type); + } + + static void setMemberValues(AnnotationInvocationHandler o, + Map<String, Object> memberValues) { + unsafe.putObject(o, memberValuesOffset, memberValues); } } }