diff options
author | robm <none@none> | 2015-12-04 15:52:11 +0000 |
---|---|---|
committer | robm <none@none> | 2015-12-04 15:52:11 +0000 |
commit | d9d8fba783acfe3c32fca4f2e27d12335ed5688f (patch) | |
tree | f9dd99512a240cb6133f5025ebe9fc08b90fbaa2 /src/share/classes/java/util/concurrent | |
parent | ed924afee1aac087f84792833a2454d438010157 (diff) | |
download | jdk8u_jdk-d9d8fba783acfe3c32fca4f2e27d12335ed5688f.tar.gz |
8140587: Atomic*FieldUpdaters should use Class.isInstance instead of direct class check
Reviewed-by: martin
Diffstat (limited to 'src/share/classes/java/util/concurrent')
3 files changed, 261 insertions, 240 deletions
diff --git a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index a60b7ce621..c10abcc72e 100644 --- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.IntUnaryOperator; -import java.util.function.IntBinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.function.IntBinaryOperator; +import java.util.function.IntUnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -363,14 +363,19 @@ public abstract class AtomicIntegerFieldUpdater<T> { } /** - * Standard hotspot implementation using intrinsics + * Standard hotspot implementation using intrinsics. */ - private static class AtomicIntegerFieldUpdaterImpl<T> - extends AtomicIntegerFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final class AtomicIntegerFieldUpdaterImpl<T> + extends AtomicIntegerFieldUpdater<T> { + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; - private final Class<T> tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class<?> cclass; + /** class holding the field */ + private final Class<T> tclass; AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName, @@ -391,7 +396,7 @@ public abstract class AtomicIntegerFieldUpdater<T> { ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -399,17 +404,15 @@ public abstract class AtomicIntegerFieldUpdater<T> { throw new RuntimeException(ex); } - Class<?> fieldt = field.getType(); - if (fieldt != int.class) + if (field.getType() != int.class) throw new IllegalArgumentException("Must be integer type"); 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; - offset = unsafe.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); } /** @@ -428,81 +431,87 @@ public abstract class AtomicIntegerFieldUpdater<T> { return false; } - private void fullCheck(T obj) { - if (!tclass.isInstance(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); + } + + /** + * 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, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); + public final boolean compareAndSet(T obj, int expect, int update) { + accessCheck(obj); + return U.compareAndSwapInt(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); + public final boolean weakCompareAndSet(T obj, int expect, int update) { + accessCheck(obj); + return U.compareAndSwapInt(obj, offset, expect, update); } - public void set(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putIntVolatile(obj, offset, newValue); + public final void set(T obj, int newValue) { + accessCheck(obj); + U.putIntVolatile(obj, offset, newValue); } - public void lazySet(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedInt(obj, offset, newValue); + public final void lazySet(T obj, int newValue) { + accessCheck(obj); + U.putOrderedInt(obj, offset, newValue); } public final int get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getIntVolatile(obj, offset); + accessCheck(obj); + return U.getIntVolatile(obj, offset); } - public int getAndSet(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndSetInt(obj, offset, newValue); + public final int getAndSet(T obj, int newValue) { + accessCheck(obj); + return U.getAndSetInt(obj, offset, newValue); } - public int getAndIncrement(T obj) { - return getAndAdd(obj, 1); + public final int getAndAdd(T obj, int delta) { + accessCheck(obj); + return U.getAndAddInt(obj, offset, delta); } - public int getAndDecrement(T obj) { - return getAndAdd(obj, -1); + public final int getAndIncrement(T obj) { + return getAndAdd(obj, 1); } - public int getAndAdd(T obj, int delta) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndAddInt(obj, offset, delta); + public final int getAndDecrement(T obj) { + return getAndAdd(obj, -1); } - public int incrementAndGet(T obj) { + public final int incrementAndGet(T obj) { return getAndAdd(obj, 1) + 1; } - public int decrementAndGet(T obj) { - return getAndAdd(obj, -1) - 1; + public final int decrementAndGet(T obj) { + return getAndAdd(obj, -1) - 1; } - public int addAndGet(T obj, int delta) { + public final int addAndGet(T obj, int delta) { return getAndAdd(obj, delta) + delta; } - 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() - ) - ); - } } } diff --git a/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index aae2b248a1..e701c67005 100644 --- a/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.LongUnaryOperator; -import java.util.function.LongBinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.function.LongBinaryOperator; +import java.util.function.LongUnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -365,11 +365,16 @@ public abstract class AtomicLongFieldUpdater<T> { return next; } - private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> { + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; - private final Class<T> tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class<?> cclass; + /** class holding the field */ + private final Class<T> tclass; CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) { @@ -389,7 +394,7 @@ public abstract class AtomicLongFieldUpdater<T> { ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -397,103 +402,110 @@ public abstract class AtomicLongFieldUpdater<T> { throw new RuntimeException(ex); } - Class<?> fieldt = field.getType(); - if (fieldt != long.class) + if (field.getType() != long.class) throw new IllegalArgumentException("Must be long type"); 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; - offset = unsafe.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); + } + + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throwAccessCheckException(obj); } - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) + /** + * 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, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); + public final boolean compareAndSet(T obj, long expect, long update) { + accessCheck(obj); + return U.compareAndSwapLong(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); + public final boolean weakCompareAndSet(T obj, long expect, long update) { + accessCheck(obj); + return U.compareAndSwapLong(obj, offset, expect, update); } - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putLongVolatile(obj, offset, newValue); + public final void set(T obj, long newValue) { + accessCheck(obj); + U.putLongVolatile(obj, offset, newValue); } - public void lazySet(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedLong(obj, offset, newValue); + public final void lazySet(T obj, long newValue) { + accessCheck(obj); + U.putOrderedLong(obj, offset, newValue); } - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getLongVolatile(obj, offset); + public final long get(T obj) { + accessCheck(obj); + return U.getLongVolatile(obj, offset); } - public long getAndSet(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndSetLong(obj, offset, newValue); + public final long getAndSet(T obj, long newValue) { + accessCheck(obj); + return U.getAndSetLong(obj, offset, newValue); } - public long getAndIncrement(T obj) { - return getAndAdd(obj, 1); + public final long getAndAdd(T obj, long delta) { + accessCheck(obj); + return U.getAndAddLong(obj, offset, delta); } - public long getAndDecrement(T obj) { - return getAndAdd(obj, -1); + public final long getAndIncrement(T obj) { + return getAndAdd(obj, 1); } - public long getAndAdd(T obj, long delta) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndAddLong(obj, offset, delta); + public final long getAndDecrement(T obj) { + return getAndAdd(obj, -1); } - public long incrementAndGet(T obj) { + public final long incrementAndGet(T obj) { return getAndAdd(obj, 1) + 1; } - public long decrementAndGet(T obj) { - return getAndAdd(obj, -1) - 1; + public final long decrementAndGet(T obj) { + return getAndAdd(obj, -1) - 1; } - public long addAndGet(T obj, long delta) { + public final long addAndGet(T obj, long delta) { return getAndAdd(obj, delta) + delta; } - - 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() - ) - ); - } } - - private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; - private final Class<T> tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class<?> cclass; + /** class holding the field */ + private final Class<T> tclass; LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) { @@ -513,7 +525,7 @@ public abstract class AtomicLongFieldUpdater<T> { ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -521,72 +533,75 @@ public abstract class AtomicLongFieldUpdater<T> { throw new RuntimeException(ex); } - Class<?> fieldt = field.getType(); - if (fieldt != long.class) + if (field.getType() != long.class) throw new IllegalArgumentException("Must be long type"); 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; - offset = unsafe.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); } - private void fullCheck(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)) + throw accessCheckException(obj); + } + + /** + * Returns access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final RuntimeException accessCheckException(T obj) { + if (cclass == tclass) + return new ClassCastException(); + else + return 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, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final boolean compareAndSet(T obj, long expect, long update) { + accessCheck(obj); synchronized (this) { - long v = unsafe.getLong(obj, offset); + long v = U.getLong(obj, offset); if (v != expect) return false; - unsafe.putLong(obj, offset, update); + U.putLong(obj, offset, update); return true; } } - public boolean weakCompareAndSet(T obj, long expect, long update) { + public final boolean weakCompareAndSet(T obj, long expect, long update) { return compareAndSet(obj, expect, update); } - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void set(T obj, long newValue) { + accessCheck(obj); synchronized (this) { - unsafe.putLong(obj, offset, newValue); + U.putLong(obj, offset, newValue); } } - public void lazySet(T obj, long newValue) { + public final void lazySet(T obj, long newValue) { set(obj, newValue); } - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final long get(T obj) { + accessCheck(obj); synchronized (this) { - return unsafe.getLong(obj, offset); - } - } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; + return U.getLong(obj, offset); } - 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() - ) - ); } } @@ -595,7 +610,7 @@ public abstract class AtomicLongFieldUpdater<T> { * classloader's delegation chain. * Equivalent to the inaccessible: first.isAncestor(second). */ - private static boolean isAncestor(ClassLoader first, ClassLoader second) { + static boolean isAncestor(ClassLoader first, ClassLoader second) { ClassLoader acl = first; do { acl = acl.getParent(); diff --git a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index 4408ff3b1d..76fa0a761c 100644 --- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.UnaryOperator; -import java.util.function.BinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -53,7 +53,7 @@ import sun.reflect.Reflection; * independently subject to atomic updates. For example, a tree node * might be declared as * - * <pre> {@code + * <pre> {@code * class Node { * private volatile Node left, right; * @@ -62,7 +62,7 @@ import sun.reflect.Reflection; * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); * - * Node getLeft() { return left; } + * Node getLeft() { return left; } * boolean compareAndSetLeft(Node expect, Node update) { * return leftUpdater.compareAndSet(this, expect, update); * } @@ -284,11 +284,17 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { private static final class AtomicReferenceFieldUpdaterImpl<T,V> extends AtomicReferenceFieldUpdater<T,V> { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final sun.misc.Unsafe U = sun.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<T> tclass; + /** field value type */ private final Class<V> vclass; - private final Class<?> cclass; /* * Internal type checks within all update methods contain @@ -323,7 +329,7 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } fieldClass = field.getType(); } catch (PrivilegedActionException pae) { @@ -340,14 +346,10 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { 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 = unsafe.objectFieldOffset(field); + this.vclass = vclass; + this.offset = U.objectFieldOffset(field); } /** @@ -366,83 +368,78 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { 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); - return unsafe.compareAndSwapObject(obj, offset, expect, update); + private final void valueCheck(V v) { + if (v != null && !(vclass.isInstance(v))) + throwCCE(); } - public 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); - return unsafe.compareAndSwapObject(obj, offset, expect, update); + static void throwCCE() { + throw new ClassCastException(); } - 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); - unsafe.putObjectVolatile(obj, offset, newValue); + public final boolean compareAndSet(T obj, V expect, V update) { + accessCheck(obj); + valueCheck(update); + return U.compareAndSwapObject(obj, offset, expect, update); } - 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); - unsafe.putOrderedObject(obj, offset, newValue); + public final boolean weakCompareAndSet(T obj, V expect, V update) { + // same implementation as strong form for now + accessCheck(obj); + valueCheck(update); + return U.compareAndSwapObject(obj, offset, expect, update); } - @SuppressWarnings("unchecked") - public V get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) - targetCheck(obj); - return (V)unsafe.getObjectVolatile(obj, offset); + public final void set(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); + U.putObjectVolatile(obj, offset, newValue); + } + + public final void lazySet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); + U.putOrderedObject(obj, offset, newValue); } @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); - return (V)unsafe.getAndSetObject(obj, offset, newValue); + public final V get(T obj) { + accessCheck(obj); + return (V)U.getObjectVolatile(obj, offset); } - 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() - ) - ); + @SuppressWarnings("unchecked") + public final V getAndSet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); + return (V)U.getAndSetObject(obj, offset, newValue); } } } |