diff -r 67d0e5867568 -r 61d78c23fcdc jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Nov 25 15:36:03 2015 -0500 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Nov 25 18:12:38 2015 -0800 @@ -286,9 +286,15 @@ extends AtomicReferenceFieldUpdater { private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private final long offset; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ + private final Class cclass; + /** class holding the field */ private final Class tclass; + /** field value type */ private final Class vclass; - private final Class cclass; /* * Internal type checks within all update methods contain @@ -340,14 +346,10 @@ if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; + this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; this.tclass = tclass; - if (vclass == Object.class) - this.vclass = null; - else - this.vclass = vclass; - offset = U.objectFieldOffset(field); + this.vclass = vclass; + this.offset = U.objectFieldOffset(field); } /** @@ -366,83 +368,78 @@ return false; } - void targetCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throwAccessCheckException(obj); } - void updateCheck(T obj, V update) { - if (!tclass.isInstance(obj) || - (update != null && vclass != null && !vclass.isInstance(update))) + /** + * Throws access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final void throwAccessCheckException(T obj) { + if (cclass == tclass) throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + else + throw new RuntimeException( + new IllegalAccessException( + "Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName())); } - public boolean compareAndSet(T obj, V expect, V update) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); + private final void valueCheck(V v) { + if (v != null && !(vclass.isInstance(v))) + throwCCE(); + } + + static void throwCCE() { + throw new ClassCastException(); + } + + public final boolean compareAndSet(T obj, V expect, V update) { + accessCheck(obj); + valueCheck(update); return U.compareAndSwapObject(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, V expect, V update) { + public final boolean weakCompareAndSet(T obj, V expect, V update) { // same implementation as strong form for now - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); + accessCheck(obj); + valueCheck(update); return U.compareAndSwapObject(obj, offset, expect, update); } - public void set(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final void set(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); U.putObjectVolatile(obj, offset, newValue); } - public void lazySet(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final void lazySet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); U.putOrderedObject(obj, offset, newValue); } @SuppressWarnings("unchecked") - public V get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) - targetCheck(obj); + public final V get(T obj) { + accessCheck(obj); return (V)U.getObjectVolatile(obj, offset); } @SuppressWarnings("unchecked") - public V getAndSet(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final V getAndSet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); return (V)U.getAndSetObject(obj, offset, newValue); } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } } }