# HG changeset patch # User chegar # Date 1448973508 0 # Node ID 80c40839a17e886babe46e37618087e91a6094f9 # Parent 959a17ea6598353551e134d9d0021b34716bd6d9 8143185: Cleanup for handling proxies Reviewed-by: alanb, darcy, robm, rriggs, skoivu, rriggs diff -r 959a17ea6598 -r 80c40839a17e jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java --- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Thu Nov 26 16:25:48 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Tue Dec 01 12:38:28 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; @@ -431,35 +432,72 @@ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); + ObjectInputStream.GetField fields = s.readFields(); + + @SuppressWarnings("unchecked") + Class t = (Class)fields.get("type", null); + @SuppressWarnings("unchecked") + Map streamVals = (Map)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> memberTypes = annotationType.memberTypes(); + // consistent with runtime Map type + Map mv = new LinkedHashMap<>(); // If there are annotation members without values, that // situation is handled by the invoke method. - for (Map.Entry memberValue : memberValues.entrySet()) { + for (Map.Entry 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 jdk.internal.misc.Unsafe unsafe; + private static final long typeOffset; + private static final long memberValuesOffset; + static { + try { + unsafe = jdk.internal.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 type) { + unsafe.putObject(o, typeOffset, type); + } + + static void setMemberValues(AnnotationInvocationHandler o, + Map memberValues) { + unsafe.putObject(o, memberValuesOffset, memberValues); } } }