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;
87365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson
98eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport dalvik.system.VMStack; // android-added
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe;
1191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.lang.reflect.Field;
1291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.lang.reflect.Modifier;
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A reflection-based utility that enables atomic updates to
16bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * designated {@code volatile long} fields of designated classes.
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is designed for use in atomic data structures in which
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * several fields of the same node are independently subject to atomic
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * updates.
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
21bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Note that the guarantees of the {@code compareAndSet}
22bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * method in this class are weaker than in other atomic classes.
23bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Because this class cannot ensure that all uses of the field
24bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * are appropriate for purposes of atomic access, it can
25bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * guarantee atomicity only with respect to other invocations of
26bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code compareAndSet} and {@code set} on the same updater.
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <T> The type of the object holding the updatable field
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
3291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravlepublic abstract class AtomicLongFieldUpdater<T> {
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates and returns an updater for objects with the given field.
35bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The Class argument is needed to check that reflective types and
36bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * generic types match.
37bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tclass the class of the objects holding the field
3991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @param fieldName the name of the field to be updated
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the updater
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException if the field is not a
4291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * volatile long type
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws RuntimeException with a nested reflection-based
4491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * exception if the class does not hold field or is the wrong type,
4591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * or the field is inaccessible to the caller according to Java language
4691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * access control
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (AtomicLong.VM_SUPPORTS_LONG_CAS)
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new CASUpdater<U>(tclass, fieldName);
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new LockedUpdater<U>(tclass, fieldName);
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Protected do-nothing constructor for use by subclasses.
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected AtomicLongFieldUpdater() {
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
62bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
63bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given updated value if the current value {@code ==} the
64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * expected value. This method is guaranteed to be atomic with respect to
65bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other calls to {@code compareAndSet} and {@code set}, but not
66bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * necessarily with respect to other changes in the field.
67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to conditionally set
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
7191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return true if successful
72bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if {@code obj} is not an instance
7391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * of the class possessing the field established in the constructor
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract boolean compareAndSet(T obj, long expect, long update);
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
79bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given updated value if the current value {@code ==} the
80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * expected value. This method is guaranteed to be atomic with respect to
81bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other calls to {@code compareAndSet} and {@code set}, but not
82bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * necessarily with respect to other changes in the field.
83bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
8491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * <p><a href="package-summary.html#weakCompareAndSet">May fail
8591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * spuriously and does not provide ordering guarantees</a>, so is
8691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * only rarely an appropriate alternative to {@code compareAndSet}.
87bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to conditionally set
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
9191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return true if successful
92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if {@code obj} is not an instance
9391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * of the class possessing the field established in the constructor
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract boolean weakCompareAndSet(T obj, long expect, long update);
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Sets the field of the given object managed by this updater to the
99bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given updated value. This operation is guaranteed to act as a volatile
100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * store with respect to subsequent invocations of {@code compareAndSet}.
101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to set
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract void set(T obj, long newValue);
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Eventually sets the field of the given object managed by this
1096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * updater to the given updated value.
1106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param obj An object whose field to set
1126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param newValue the new value
1136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public abstract void lazySet(T obj, long newValue);
1166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Gets the current value held in the field of the given object managed
119bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * by this updater.
120bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract long get(T obj);
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
127bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
128bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given value and returns the old value.
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the previous value
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndSet(T obj, long newValue) {
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, newValue))
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
143bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically increments by one the current value of the field of the
144bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
145bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndIncrement(T obj) {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + 1;
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
159bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically decrements by one the current value of the field of the
160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
161bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
163bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndDecrement(T obj) {
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current - 1;
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
175bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically adds the given value to the current value of the field of
176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the given object managed by this updater.
177bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param delta the value to add
180bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndAdd(T obj, long delta) {
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + delta;
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically increments by one the current value of the field of the
193bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
194bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
196bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long incrementAndGet(T obj) {
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + 1;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically decrements by one the current value of the field of the
209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
210bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long decrementAndGet(T obj) {
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current - 1;
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
224bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically adds the given value to the current value of the field of
225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the given object managed by this updater.
226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param delta the value to add
229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long addAndGet(T obj, long delta) {
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + delta;
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
241a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private static final Unsafe unsafe = Unsafe.getUnsafe();
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final long offset;
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Class<T> tclass;
244a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private final Class<?> cclass;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        CASUpdater(Class<T> tclass, String fieldName) {
24791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            final Field field;
24891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            final Class<?> caller;
24991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            final int modifiers;
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
25191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                field = tclass.getDeclaredField(fieldName); // android-changed
2526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                caller = VMStack.getStackClass2(); // android-changed
253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                modifiers = field.getModifiers();
2546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // BEGIN android-removed
2556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
2566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                //     caller, tclass, null, modifiers);
25791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // ClassLoader cl = tclass.getClassLoader();
25891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // ClassLoader ccl = caller.getClassLoader();
25991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // if ((ccl != null) && (ccl != cl) &&
26091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                //     ((cl == null) || !isAncestor(cl, ccl))) {
26191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                //   sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
26291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // }
2636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // END android-removed
26491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // BEGIN android-removed
26591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // } catch (PrivilegedActionException pae) {
26691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            //    throw new RuntimeException(pae.getException());
26791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // END android-removed
268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } catch (Exception ex) {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new RuntimeException(ex);
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
271bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
272a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> fieldt = field.getType();
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fieldt != long.class)
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be long type");
275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (!Modifier.isVolatile(modifiers))
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be volatile type");
278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.cclass = (Modifier.isProtected(modifiers) &&
280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                           caller != tclass) ? caller : null;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.tclass = tclass;
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset = unsafe.objectFieldOffset(field);
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
285bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void fullCheck(T obj) {
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!tclass.isInstance(obj))
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ClassCastException();
288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass != null)
289bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ensureProtectedAccess(obj);
290bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
292bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean compareAndSet(T obj, long expect, long update) {
293bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.compareAndSwapLong(obj, offset, expect, update);
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean weakCompareAndSet(T obj, long expect, long update) {
298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.compareAndSwapLong(obj, offset, expect, update);
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void set(T obj, long newValue) {
303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            unsafe.putLongVolatile(obj, offset, newValue);
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public void lazySet(T obj, long newValue) {
3086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
3096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            unsafe.putOrderedLong(obj, offset, newValue);
3106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
3116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public long get(T obj) {
313bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.getLongVolatile(obj, offset);
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void ensureProtectedAccess(T obj) {
318bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass.isInstance(obj)) {
319bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
320bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
3218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new RuntimeException(
322bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                new IllegalAccessException("Class " +
323bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    cclass.getName() +
324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " can not access a protected member of class " +
325bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    tclass.getName() +
326bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " using an instance of " +
327bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    obj.getClass().getName()
328bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                )
329bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            );
330bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
335a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private static final Unsafe unsafe = Unsafe.getUnsafe();
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final long offset;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Class<T> tclass;
338a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private final Class<?> cclass;
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        LockedUpdater(Class<T> tclass, String fieldName) {
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Field field = null;
342a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> caller = null;
343bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int modifiers = 0;
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
34591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                field = tclass.getDeclaredField(fieldName); // android-changed
3466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                caller = VMStack.getStackClass2(); // android-changed
347bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                modifiers = field.getModifiers();
3486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // BEGIN android-removed
3496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
3506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                //     caller, tclass, null, modifiers);
35191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // ClassLoader cl = tclass.getClassLoader();
35291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // ClassLoader ccl = caller.getClassLoader();
35391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // if ((ccl != null) && (ccl != cl) &&
35491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                //     ((cl == null) || !isAncestor(cl, ccl))) {
35591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                //   sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
35691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                // }
3576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // END android-removed
35891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // BEGIN android-removed
35991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // } catch (PrivilegedActionException pae) {
36091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            //     throw new RuntimeException(pae.getException());
36191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            // END android-removed
362bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } catch (Exception ex) {
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new RuntimeException(ex);
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
366a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> fieldt = field.getType();
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fieldt != long.class)
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be long type");
369bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
370bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (!Modifier.isVolatile(modifiers))
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be volatile type");
372bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
373bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.cclass = (Modifier.isProtected(modifiers) &&
374bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                           caller != tclass) ? caller : null;
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.tclass = tclass;
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset = unsafe.objectFieldOffset(field);
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
379bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void fullCheck(T obj) {
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!tclass.isInstance(obj))
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ClassCastException();
382bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass != null)
383bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ensureProtectedAccess(obj);
384bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
385bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
386bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean compareAndSet(T obj, long expect, long update) {
387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
3888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                long v = unsafe.getLong(obj, offset);
390bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (v != expect)
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unsafe.putLong(obj, offset, update);
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean weakCompareAndSet(T obj, long expect, long update) {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return compareAndSet(obj, expect, update);
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void set(T obj, long newValue) {
402bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
4038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unsafe.putLong(obj, offset, newValue);
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public void lazySet(T obj, long newValue) {
409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            set(obj, newValue);
410bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
411bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public long get(T obj) {
413bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
4148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return unsafe.getLong(obj, offset);
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
418bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
419bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void ensureProtectedAccess(T obj) {
420bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass.isInstance(obj)) {
421bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
422bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
4238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new RuntimeException(
424bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                new IllegalAccessException("Class " +
425bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    cclass.getName() +
426bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " can not access a protected member of class " +
427bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    tclass.getName() +
428bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " using an instance of " +
429bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    obj.getClass().getName()
430bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                )
431bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            );
432bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
43491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle
43591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    // BEGIN android-removed
43691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    // /**
43791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //  * Returns true if the second classloader can be found in the first
43891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //  * classloader's delegation chain.
43991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //  * Equivalent to the inaccessible: first.isAncestor(second).
44091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //  */
44191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
44291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //     ClassLoader acl = first;
44391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //     do {
44491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //         acl = acl.getParent();
44591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //         if (second == acl) {
44691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //             return true;
44791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //        }
44891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //     } while (acl != null);
44991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    //     return false;
45091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    // }
45191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    // END android-removed
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
453