1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic; 8a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport dalvik.system.VMStack; // android-added 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe; 1091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.lang.reflect.Field; 1191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.lang.reflect.Modifier; 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A reflection-based utility that enables atomic updates to 15bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * designated {@code volatile} reference fields of designated 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * classes. This class is designed for use in atomic data structures 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in which several reference fields of the same node are 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * independently subject to atomic updates. For example, a tree node 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * might be declared as 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <pre> {@code 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class Node { 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * private volatile Node left, right; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater = 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); 278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Node getLeft() { return left; } 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * boolean compareAndSetLeft(Node expect, Node update) { 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return leftUpdater.compareAndSet(this, expect, update); 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * // ... and so on 358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * }}</pre> 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 37bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Note that the guarantees of the {@code compareAndSet} 38bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * method in this class are weaker than in other atomic classes. 39bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Because this class cannot ensure that all uses of the field 40bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * are appropriate for purposes of atomic access, it can 41bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * guarantee atomicity only with respect to other invocations of 42bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code compareAndSet} and {@code set} on the same updater. 43bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <T> The type of the object holding the updatable field 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <V> The type of the field 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravlepublic abstract class AtomicReferenceFieldUpdater<T,V> { 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 52bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Creates and returns an updater for objects with the given field. 53bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The Class arguments are needed to check that reflective types and 54bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * generic types match. 55bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 5691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @param tclass the class of the objects holding the field 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param vclass the class of the field 5891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @param fieldName the name of the field to be updated 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updater 6091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @throws IllegalArgumentException if the field is not a volatile reference type 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws RuntimeException with a nested reflection-based 6291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * exception if the class does not hold field or is the wrong type, 6391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * or the field is inaccessible to the caller according to Java language 6491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * access control 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { 67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, 68bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson vclass, 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fieldName); 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Protected do-nothing constructor for use by subclasses. 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AtomicReferenceFieldUpdater() { 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 79bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the field of the given object managed by this updater 80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to the given updated value if the current value {@code ==} the 81bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * expected value. This method is guaranteed to be atomic with respect to 82bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other calls to {@code compareAndSet} and {@code set}, but not 83bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * necessarily with respect to other changes in the field. 84bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to conditionally set 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 8891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return true if successful 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean compareAndSet(T obj, V expect, V update); 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the field of the given object managed by this updater 94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to the given updated value if the current value {@code ==} the 95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * expected value. This method is guaranteed to be atomic with respect to 96bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other calls to {@code compareAndSet} and {@code set}, but not 97bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * necessarily with respect to other changes in the field. 98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 9991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <p><a href="package-summary.html#weakCompareAndSet">May fail 10091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * spuriously and does not provide ordering guarantees</a>, so is 10191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * only rarely an appropriate alternative to {@code compareAndSet}. 102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to conditionally set 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 10691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return true if successful 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean weakCompareAndSet(T obj, V expect, V update); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 111bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Sets the field of the given object managed by this updater to the 112bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * given updated value. This operation is guaranteed to act as a volatile 113bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * store with respect to subsequent invocations of {@code compareAndSet}. 114bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to set 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract void set(T obj, V newValue); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Eventually sets the field of the given object managed by this 1226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * updater to the given updated value. 1236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param obj An object whose field to set 1256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param newValue the new value 1266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 1276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public abstract void lazySet(T obj, V newValue); 1296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 131bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Gets the current value held in the field of the given object managed 132bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * by this updater. 133bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the current value 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract V get(T obj); 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the field of the given object managed by this updater 141bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to the given value and returns the old value. 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V getAndSet(T obj, V newValue) { 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V current = get(obj); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, newValue)) 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return current; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 155bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private static final class AtomicReferenceFieldUpdaterImpl<T,V> 156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson extends AtomicReferenceFieldUpdater<T,V> { 1576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final Unsafe unsafe = Unsafe.getUnsafe(); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final long offset; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Class<T> tclass; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Class<V> vclass; 161a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private final Class<?> cclass; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /* 164bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Internal type checks within all update methods contain 165bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * internal inlined optimizations checking for the common 166bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * cases where the class is final (in which case a simple 167bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * getClass comparison suffices) or is of type Object (in 168bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * which case no check is needed because all objects are 169bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * instances of Object). The Object case is handled simply by 170bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * setting vclass to null in constructor. The targetCheck and 171bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * updateCheck methods are invoked when these faster 172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * screenings fail. 173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 17591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, 176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Class<V> vclass, 17791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final String fieldName) { 17891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final Field field; 17991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final Class<?> fieldClass; 18091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final Class<?> caller; 18191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final int modifiers; 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 18391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle field = tclass.getDeclaredField(fieldName); // android-changed 1846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson caller = VMStack.getStackClass2(); // android-changed 185bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson modifiers = field.getModifiers(); 18691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // BEGIN android-removed 18791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // sun.reflect.misc.ReflectUtil.ensureMemberAccess( 18891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // caller, tclass, null, modifiers); 18991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // ClassLoader cl = tclass.getClassLoader(); 19091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // ClassLoader ccl = caller.getClassLoader(); 19191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // if ((ccl != null) && (ccl != cl) && 19291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // ((cl == null) || !isAncestor(cl, ccl))) { 19391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 19491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // } 19591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // END android-removed 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fieldClass = field.getType(); 19791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // BEGIN android-removed 19891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // } catch (PrivilegedActionException pae) { 19991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // throw new RuntimeException(pae.getException()); 20091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // END android-removed 201bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } catch (Exception ex) { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new RuntimeException(ex); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 204bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (vclass != fieldClass) 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 207bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (!Modifier.isVolatile(modifiers)) 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Must be volatile type"); 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 211bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.cclass = (Modifier.isProtected(modifiers) && 212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson caller != tclass) ? caller : null; 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tclass = tclass; 214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (vclass == Object.class) 215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.vclass = null; 216bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else 217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.vclass = vclass; 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = unsafe.objectFieldOffset(field); 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 22191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // BEGIN android-removed 22291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // /** 22391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // * Returns true if the second classloader can be found in the first 22491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // * classloader's delegation chain. 22591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // * Equivalent to the inaccessible: first.isAncestor(second). 22691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // */ 22791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // 22891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // private static boolean isAncestor(ClassLoader first, ClassLoader second) { 22991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // ClassLoader acl = first; 23091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // do { 23191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // acl = acl.getParent(); 23291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // if (second == acl) { 23391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // return true; 23491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // } 23591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // } while (acl != null); 23691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // return false; 23791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // } 23891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // END android-removed 23991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle 240bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson void targetCheck(T obj) { 241bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (!tclass.isInstance(obj)) 242bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw new ClassCastException(); 243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (cclass != null) 244bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson ensureProtectedAccess(obj); 245bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 246bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 247bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson void updateCheck(T obj, V update) { 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj) || 249bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson (update != null && vclass != null && !vclass.isInstance(update))) 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 251bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (cclass != null) 252bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson ensureProtectedAccess(obj); 253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 254bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 255bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean compareAndSet(T obj, V expect, V update) { 256bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (obj == null || obj.getClass() != tclass || cclass != null || 257bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson (update != null && vclass != null && 258bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson vclass != update.getClass())) 259bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson updateCheck(obj, update); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.compareAndSwapObject(obj, offset, expect, update); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean weakCompareAndSet(T obj, V expect, V update) { 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // same implementation as strong form for now 265bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (obj == null || obj.getClass() != tclass || cclass != null || 266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson (update != null && vclass != null && 267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson vclass != update.getClass())) 268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson updateCheck(obj, update); 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.compareAndSwapObject(obj, offset, expect, update); 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void set(T obj, V newValue) { 273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (obj == null || obj.getClass() != tclass || cclass != null || 274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson (newValue != null && vclass != null && 275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson vclass != newValue.getClass())) 276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson updateCheck(obj, newValue); 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unsafe.putObjectVolatile(obj, offset, newValue); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void lazySet(T obj, V newValue) { 2816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (obj == null || obj.getClass() != tclass || cclass != null || 2826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (newValue != null && vclass != null && 2836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson vclass != newValue.getClass())) 2846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson updateCheck(obj, newValue); 2856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unsafe.putOrderedObject(obj, offset, newValue); 2866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 28891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle @SuppressWarnings("unchecked") 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V get(T obj) { 290bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (obj == null || obj.getClass() != tclass || cclass != null) 291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson targetCheck(obj); 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (V)unsafe.getObjectVolatile(obj, offset); 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 294bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private void ensureProtectedAccess(T obj) { 296bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (cclass.isInstance(obj)) { 297bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return; 298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 2998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throw new RuntimeException( 300bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson new IllegalAccessException("Class " + 301bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson cclass.getName() + 302bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson " can not access a protected member of class " + 303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson tclass.getName() + 304bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson " using an instance of " + 305bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson obj.getClass().getName() 306bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson ) 307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson ); 308bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 311