aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/util/concurrent
diff options
context:
space:
mode:
authorrobm <none@none>2015-12-04 15:52:11 +0000
committerrobm <none@none>2015-12-04 15:52:11 +0000
commitd9d8fba783acfe3c32fca4f2e27d12335ed5688f (patch)
treef9dd99512a240cb6133f5025ebe9fc08b90fbaa2 /src/share/classes/java/util/concurrent
parented924afee1aac087f84792833a2454d438010157 (diff)
downloadjdk8u_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')
-rw-r--r--src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java131
-rw-r--r--src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java223
-rw-r--r--src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java147
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);
}
}
}