1 /*
2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.HotSpotIntrinsicCandidate;
29 import jdk.internal.util.Preconditions;
30 import jdk.internal.vm.annotation.ForceInline;
31 import jdk.internal.vm.annotation.Stable;
32
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.function.BiFunction;
37 import java.util.function.Function;
38
39 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
40 import static java.lang.invoke.MethodHandleStatics.newInternalError;
41
42 /**
43 * A VarHandle is a dynamically strongly typed reference to a variable, or to a
44 * parametrically-defined family of variables, including static fields,
45 * non-static fields, array elements, or components of an off-heap data
46 * structure. Access to such variables is supported under various
47 * <em>access modes</em>, including plain read/write access, volatile
48 * read/write access, and compare-and-set.
49 *
50 * <p>VarHandles are immutable and have no visible state. VarHandles cannot be
51 * subclassed by the user.
52 *
53 * <p>A VarHandle has:
54 * <ul>
55 * <li>a {@link #varType variable type} T, the type of every variable referenced
56 * by this VarHandle; and
57 * <li>a list of {@link #coordinateTypes coordinate types}
58 * {@code CT1, CT2, ..., CTn}, the types of <em>coordinate expressions</em> that
59 * jointly locate a variable referenced by this VarHandle.
60 * </ul>
61 * Variable and coordinate types may be primitive or reference, and are
62 * represented by {@code Class} objects. The list of coordinate types may be
63 * empty.
64 *
65 * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
66 * lookup} VarHandle instances document the supported variable type and the list
67 * of coordinate types.
68 *
69 * <p>Each access mode is associated with one <em>access mode method</em>, a
70 * <a href="MethodHandle.html#sigpoly">signature polymorphic</a> method named
71 * for the access mode. When an access mode method is invoked on a VarHandle
72 * instance, the initial arguments to the invocation are coordinate expressions
73 * that indicate in precisely which object the variable is to be accessed.
74 * Trailing arguments to the invocation represent values of importance to the
75 * access mode. For example, the various compare-and-set or compare-and-exchange
76 * access modes require two trailing arguments for the variable's expected value
77 * and new value.
78 *
79 * <p>The arity and types of arguments to the invocation of an access mode
80 * method are not checked statically. Instead, each access mode method
81 * specifies an {@link #accessModeType(AccessMode) access mode type},
82 * represented as an instance of {@link MethodType}, that serves as a kind of
83 * method signature against which the arguments are checked dynamically. An
84 * access mode type gives formal parameter types in terms of the coordinate
85 * types of a VarHandle instance and the types for values of importance to the
86 * access mode. An access mode type also gives a return type, often in terms of
87 * the variable type of a VarHandle instance. When an access mode method is
88 * invoked on a VarHandle instance, the symbolic type descriptor at the
89 * call site, the run time types of arguments to the invocation, and the run
90 * time type of the return value, must <a href="#invoke">match</a> the types
91 * given in the access mode type. A runtime exception will be thrown if the
92 * match fails.
93 *
94 * For example, the access mode method {@link #compareAndSet} specifies that if
95 * its receiver is a VarHandle instance with coordinate types
96 * {@code CT1, ..., CTn} and variable type {@code T}, then its access mode type
97 * is {@code (CT1 c1, ..., CTn cn, T expectedValue, T newValue)boolean}.
98 * Suppose that a VarHandle instance can access array elements, and that its
99 * coordinate types are {@code String[]} and {@code int} while its variable type
100 * is {@code String}. The access mode type for {@code compareAndSet} on this
101 * VarHandle instance would be
102 * {@code (String[] c1, int c2, String expectedValue, String newValue)boolean}.
103 * Such a VarHandle instance may be produced by the
104 * {@link MethodHandles#arrayElementVarHandle(Class) array factory method} and
105 * access array elements as follows:
106 * <pre> {@code
107 * String[] sa = ...
108 * VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
109 * boolean r = avh.compareAndSet(sa, 10, "expected", "new");
110 * }</pre>
111 *
112 * <p>Access modes control atomicity and consistency properties.
113 * <em>Plain</em> read ({@code get}) and write ({@code set})
114 * accesses are guaranteed to be bitwise atomic only for references
115 * and for primitive values of at most 32 bits, and impose no observable
116 * ordering constraints with respect to threads other than the
117 * executing thread. <em>Opaque</em> operations are bitwise atomic and
118 * coherently ordered with respect to accesses to the same variable.
119 * In addition to obeying Opaque properties, <em>Acquire</em> mode
120 * reads and their subsequent accesses are ordered after matching
121 * <em>Release</em> mode writes and their previous accesses. In
122 * addition to obeying Acquire and Release properties, all
123 * <em>Volatile</em> operations are totally ordered with respect to
124 * each other.
125 *
126 * <p>Access modes are grouped into the following categories:
127 * <ul>
128 * <li>read access modes that get the value of a variable under specified
129 * memory ordering effects.
130 * The set of corresponding access mode methods belonging to this group
131 * consists of the methods
132 * {@link #get get},
133 * {@link #getVolatile getVolatile},
134 * {@link #getAcquire getAcquire},
135 * {@link #getOpaque getOpaque}.
136 * <li>write access modes that set the value of a variable under specified
137 * memory ordering effects.
138 * The set of corresponding access mode methods belonging to this group
139 * consists of the methods
140 * {@link #set set},
141 * {@link #setVolatile setVolatile},
142 * {@link #setRelease setRelease},
143 * {@link #setOpaque setOpaque}.
144 * <li>atomic update access modes that, for example, atomically compare and set
145 * the value of a variable under specified memory ordering effects.
146 * The set of corresponding access mode methods belonging to this group
147 * consists of the methods
148 * {@link #compareAndSet compareAndSet},
149 * {@link #weakCompareAndSetPlain weakCompareAndSetPlain},
150 * {@link #weakCompareAndSet weakCompareAndSet},
151 * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
152 * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
153 * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
154 * {@link #compareAndExchange compareAndExchange},
155 * {@link #compareAndExchangeRelease compareAndExchangeRelease},
156 * {@link #getAndSet getAndSet},
157 * {@link #getAndSetAcquire getAndSetAcquire},
158 * {@link #getAndSetRelease getAndSetRelease}.
159 * <li>numeric atomic update access modes that, for example, atomically get and
160 * set with addition the value of a variable under specified memory ordering
161 * effects.
162 * The set of corresponding access mode methods belonging to this group
163 * consists of the methods
164 * {@link #getAndAdd getAndAdd},
165 * {@link #getAndAddAcquire getAndAddAcquire},
166 * {@link #getAndAddRelease getAndAddRelease},
167 * <li>bitwise atomic update access modes that, for example, atomically get and
168 * bitwise OR the value of a variable under specified memory ordering
169 * effects.
170 * The set of corresponding access mode methods belonging to this group
171 * consists of the methods
172 * {@link #getAndBitwiseOr getAndBitwiseOr},
173 * {@link #getAndBitwiseOrAcquire getAndBitwiseOrAcquire},
174 * {@link #getAndBitwiseOrRelease getAndBitwiseOrRelease},
175 * {@link #getAndBitwiseAnd getAndBitwiseAnd},
176 * {@link #getAndBitwiseAndAcquire getAndBitwiseAndAcquire},
177 * {@link #getAndBitwiseAndRelease getAndBitwiseAndRelease},
178 * {@link #getAndBitwiseXor getAndBitwiseXor},
179 * {@link #getAndBitwiseXorAcquire getAndBitwiseXorAcquire},
180 * {@link #getAndBitwiseXorRelease getAndBitwiseXorRelease}.
181 * </ul>
182 *
183 * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
184 * lookup} VarHandle instances document the set of access modes that are
185 * supported, which may also include documenting restrictions based on the
186 * variable type and whether a variable is read-only. If an access mode is not
187 * supported then the corresponding access mode method will on invocation throw
188 * an {@code UnsupportedOperationException}. Factory methods should document
189 * any additional undeclared exceptions that may be thrown by access mode
190 * methods.
191 * The {@link #get get} access mode is supported for all
192 * VarHandle instances and the corresponding method never throws
193 * {@code UnsupportedOperationException}.
194 * If a VarHandle references a read-only variable (for example a {@code final}
195 * field) then write, atomic update, numeric atomic update, and bitwise atomic
196 * update access modes are not supported and corresponding methods throw
197 * {@code UnsupportedOperationException}.
198 * Read/write access modes (if supported), with the exception of
199 * {@code get} and {@code set}, provide atomic access for
200 * reference types and all primitive types.
201 * Unless stated otherwise in the documentation of a factory method, the access
202 * modes {@code get} and {@code set} (if supported) provide atomic access for
203 * reference types and all primitives types, with the exception of {@code long}
204 * and {@code double} on 32-bit platforms.
205 *
206 * <p>Access modes will override any memory ordering effects specified at
207 * the declaration site of a variable. For example, a VarHandle accessing
208 * a field using the {@code get} access mode will access the field as
209 * specified <em>by its access mode</em> even if that field is declared
210 * {@code volatile}. When mixed access is performed extreme care should be
211 * taken since the Java Memory Model may permit surprising results.
212 *
213 * <p>In addition to supporting access to variables under various access modes,
214 * a set of static methods, referred to as memory fence methods, is also
215 * provided for fine-grained control of memory ordering.
216 *
217 * The Java Language Specification permits other threads to observe operations
218 * as if they were executed in orders different than are apparent in program
219 * source code, subject to constraints arising, for example, from the use of
220 * locks, {@code volatile} fields or VarHandles. The static methods,
221 * {@link #fullFence fullFence}, {@link #acquireFence acquireFence},
222 * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and
223 * {@link #storeStoreFence storeStoreFence}, can also be used to impose
224 * constraints. Their specifications, as is the case for certain access modes,
225 * are phrased in terms of the lack of "reorderings" -- observable ordering
226 * effects that might otherwise occur if the fence was not present. More
227 * precise phrasing of the specification of access mode methods and memory fence
228 * methods may accompany future updates of the Java Language Specification.
229 *
230 * <h1>Compiling invocation of access mode methods</h1>
231 * A Java method call expression naming an access mode method can invoke a
232 * VarHandle from Java source code. From the viewpoint of source code, these
233 * methods can take any arguments and their polymorphic result (if expressed)
234 * can be cast to any return type. Formally this is accomplished by giving the
235 * access mode methods variable arity {@code Object} arguments and
236 * {@code Object} return types (if the return type is polymorphic), but they
237 * have an additional quality called <em>signature polymorphism</em> which
238 * connects this freedom of invocation directly to the JVM execution stack.
239 * <p>
240 * As is usual with virtual methods, source-level calls to access mode methods
241 * compile to an {@code invokevirtual} instruction. More unusually, the
242 * compiler must record the actual argument types, and may not perform method
243 * invocation conversions on the arguments. Instead, it must generate
244 * instructions to push them on the stack according to their own unconverted
245 * types. The VarHandle object itself will be pushed on the stack before the
246 * arguments. The compiler then generates an {@code invokevirtual} instruction
247 * that invokes the access mode method with a symbolic type descriptor which
248 * describes the argument and return types.
249 * <p>
250 * To issue a complete symbolic type descriptor, the compiler must also
251 * determine the return type (if polymorphic). This is based on a cast on the
252 * method invocation expression, if there is one, or else {@code Object} if the
253 * invocation is an expression, or else {@code void} if the invocation is a
254 * statement. The cast may be to a primitive type (but not {@code void}).
255 * <p>
256 * As a corner case, an uncasted {@code null} argument is given a symbolic type
257 * descriptor of {@code java.lang.Void}. The ambiguity with the type
258 * {@code Void} is harmless, since there are no references of type {@code Void}
259 * except the null reference.
260 *
261 *
262 * <h1><a id="invoke">Performing invocation of access mode methods</a></h1>
263 * The first time an {@code invokevirtual} instruction is executed it is linked
264 * by symbolically resolving the names in the instruction and verifying that
265 * the method call is statically legal. This also holds for calls to access mode
266 * methods. In this case, the symbolic type descriptor emitted by the compiler
267 * is checked for correct syntax, and names it contains are resolved. Thus, an
268 * {@code invokevirtual} instruction which invokes an access mode method will
269 * always link, as long as the symbolic type descriptor is syntactically
270 * well-formed and the types exist.
271 * <p>
272 * When the {@code invokevirtual} is executed after linking, the receiving
273 * VarHandle's access mode type is first checked by the JVM to ensure that it
274 * matches the symbolic type descriptor. If the type
275 * match fails, it means that the access mode method which the caller is
276 * invoking is not present on the individual VarHandle being invoked.
277 *
278 * <p>
279 * Invocation of an access mode method behaves as if an invocation of
280 * {@link MethodHandle#invoke}, where the receiving method handle accepts the
281 * VarHandle instance as the leading argument. More specifically, the
282 * following, where {@code {access-mode}} corresponds to the access mode method
283 * name:
284 * <pre> {@code
285 * VarHandle vh = ..
286 * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
287 * }</pre>
288 * behaves as if:
289 * <pre> {@code
290 * VarHandle vh = ..
291 * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
292 * MethodHandle mh = MethodHandles.varHandleExactInvoker(
293 * am,
294 * vh.accessModeType(am));
295 *
296 * R r = (R) mh.invoke(vh, p1, p2, ..., pN)
297 * }</pre>
298 * (modulo access mode methods do not declare throwing of {@code Throwable}).
299 * This is equivalent to:
300 * <pre> {@code
301 * MethodHandle mh = MethodHandles.lookup().findVirtual(
302 * VarHandle.class,
303 * "{access-mode}",
304 * MethodType.methodType(R, p1, p2, ..., pN));
305 *
306 * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
307 * }</pre>
308 * where the desired method type is the symbolic type descriptor and a
309 * {@link MethodHandle#invokeExact} is performed, since before invocation of the
310 * target, the handle will apply reference casts as necessary and box, unbox, or
311 * widen primitive values, as if by {@link MethodHandle#asType asType} (see also
312 * {@link MethodHandles#varHandleInvoker}).
313 *
314 * More concisely, such behaviour is equivalent to:
315 * <pre> {@code
316 * VarHandle vh = ..
317 * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
318 * MethodHandle mh = vh.toMethodHandle(am);
319 *
320 * R r = (R) mh.invoke(p1, p2, ..., pN)
321 * }</pre>
322 * Where, in this case, the method handle is bound to the VarHandle instance.
323 *
324 *
325 * <h1>Invocation checking</h1>
326 * In typical programs, VarHandle access mode type matching will usually
327 * succeed. But if a match fails, the JVM will throw a
328 * {@link WrongMethodTypeException}.
329 * <p>
330 * Thus, an access mode type mismatch which might show up as a linkage error
331 * in a statically typed program can show up as a dynamic
332 * {@code WrongMethodTypeException} in a program which uses VarHandles.
333 * <p>
334 * Because access mode types contain "live" {@code Class} objects, method type
335 * matching takes into account both type names and class loaders.
336 * Thus, even if a VarHandle {@code VH} is created in one class loader
337 * {@code L1} and used in another {@code L2}, VarHandle access mode method
338 * calls are type-safe, because the caller's symbolic type descriptor, as
339 * resolved in {@code L2}, is matched against the original callee method's
340 * symbolic type descriptor, as resolved in {@code L1}. The resolution in
341 * {@code L1} happens when {@code VH} is created and its access mode types are
342 * assigned, while the resolution in {@code L2} happens when the
343 * {@code invokevirtual} instruction is linked.
344 * <p>
345 * Apart from type descriptor checks, a VarHandles's capability to
346 * access it's variables is unrestricted.
347 * If a VarHandle is formed on a non-public variable by a class that has access
348 * to that variable, the resulting VarHandle can be used in any place by any
349 * caller who receives a reference to it.
350 * <p>
351 * Unlike with the Core Reflection API, where access is checked every time a
352 * reflective method is invoked, VarHandle access checking is performed
353 * <a href="MethodHandles.Lookup.html#access">when the VarHandle is
354 * created</a>.
355 * Thus, VarHandles to non-public variables, or to variables in non-public
356 * classes, should generally be kept secret. They should not be passed to
357 * untrusted code unless their use from the untrusted code would be harmless.
358 *
359 *
360 * <h1>VarHandle creation</h1>
361 * Java code can create a VarHandle that directly accesses any field that is
362 * accessible to that code. This is done via a reflective, capability-based
363 * API called {@link java.lang.invoke.MethodHandles.Lookup
364 * MethodHandles.Lookup}.
365 * For example, a VarHandle for a non-static field can be obtained
366 * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle
367 * Lookup.findVarHandle}.
368 * There is also a conversion method from Core Reflection API objects,
369 * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
370 * Lookup.unreflectVarHandle}.
371 * <p>
372 * Access to protected field members is restricted to receivers only of the
373 * accessing class, or one of its subclasses, and the accessing class must in
374 * turn be a subclass (or package sibling) of the protected member's defining
375 * class. If a VarHandle refers to a protected non-static field of a declaring
376 * class outside the current package, the receiver argument will be narrowed to
377 * the type of the accessing class.
378 *
379 * <h1>Interoperation between VarHandles and the Core Reflection API</h1>
380 * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup
381 * Lookup} API, any field represented by a Core Reflection API object
382 * can be converted to a behaviorally equivalent VarHandle.
383 * For example, a reflective {@link java.lang.reflect.Field Field} can
384 * be converted to a VarHandle using
385 * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
386 * Lookup.unreflectVarHandle}.
387 * The resulting VarHandles generally provide more direct and efficient
388 * access to the underlying fields.
389 * <p>
390 * As a special case, when the Core Reflection API is used to view the
391 * signature polymorphic access mode methods in this class, they appear as
392 * ordinary non-polymorphic methods. Their reflective appearance, as viewed by
393 * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
394 * is unaffected by their special status in this API.
395 * For example, {@link java.lang.reflect.Method#getModifiers
396 * Method.getModifiers}
397 * will report exactly those modifier bits required for any similarly
398 * declared method, including in this case {@code native} and {@code varargs}
399 * bits.
400 * <p>
401 * As with any reflected method, these methods (when reflected) may be invoked
402 * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke},
403 * via JNI, or indirectly via
404 * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
405 * However, such reflective calls do not result in access mode method
406 * invocations. Such a call, if passed the required argument (a single one, of
407 * type {@code Object[]}), will ignore the argument and will throw an
408 * {@code UnsupportedOperationException}.
409 * <p>
410 * Since {@code invokevirtual} instructions can natively invoke VarHandle
411 * access mode methods under any symbolic type descriptor, this reflective view
412 * conflicts with the normal presentation of these methods via bytecodes.
413 * Thus, these native methods, when reflectively viewed by
414 * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
415 * <p>
416 * In order to obtain an invoker method for a particular access mode type,
417 * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or
418 * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. The
419 * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
420 * API is also able to return a method handle to call an access mode method for
421 * any specified access mode type and is equivalent in behaviour to
422 * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
423 *
424 * <h1>Interoperation between VarHandles and Java generics</h1>
425 * A VarHandle can be obtained for a variable, such as a field, which is
426 * declared with Java generic types. As with the Core Reflection API, the
427 * VarHandle's variable type will be constructed from the erasure of the
428 * source-level type. When a VarHandle access mode method is invoked, the
429 * types
430 * of its arguments or the return value cast type may be generic types or type
431 * instances. If this occurs, the compiler will replace those types by their
432 * erasures when it constructs the symbolic type descriptor for the
433 * {@code invokevirtual} instruction.
434 *
435 * @see MethodHandle
436 * @see MethodHandles
437 * @see MethodType
438 * @since 9
439 */
440 public abstract class VarHandle {
441 final VarForm vform;
442
443 VarHandle(VarForm vform) {
444 this.vform = vform;
445 }
446
447 RuntimeException unsupported() {
448 return new UnsupportedOperationException();
449 }
450
451 // Plain accessors
452
453 /**
454 * Returns the value of a variable, with memory semantics of reading as
455 * if the variable was declared non-{@code volatile}. Commonly referred to
456 * as plain read access.
457 *
458 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
459 *
460 * <p>The symbolic type descriptor at the call site of {@code get}
461 * must match the access mode type that is the result of calling
462 * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
463 *
464 * <p>This access mode is supported by all VarHandle instances and never
465 * throws {@code UnsupportedOperationException}.
466 *
467 * @param args the signature-polymorphic parameter list of the form
468 * {@code (CT1 ct1, ..., CTn)}
469 * , statically represented using varargs.
470 * @return the signature-polymorphic result that is the value of the
471 * variable
472 * , statically represented using {@code Object}.
473 * @throws WrongMethodTypeException if the access mode type does not
474 * match the caller's symbolic type descriptor.
475 * @throws ClassCastException if the access mode type matches the caller's
476 * symbolic type descriptor, but a reference cast fails.
477 */
478 public final native
479 @MethodHandle.PolymorphicSignature
480 @HotSpotIntrinsicCandidate
481 Object get(Object... args);
482
483 /**
484 * Sets the value of a variable to the {@code newValue}, with memory
485 * semantics of setting as if the variable was declared non-{@code volatile}
486 * and non-{@code final}. Commonly referred to as plain write access.
487 *
488 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}
489 *
490 * <p>The symbolic type descriptor at the call site of {@code set}
491 * must match the access mode type that is the result of calling
492 * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
493 *
494 * @param args the signature-polymorphic parameter list of the form
495 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
496 * , statically represented using varargs.
497 * @throws UnsupportedOperationException if the access mode is unsupported
498 * for this VarHandle.
499 * @throws WrongMethodTypeException if the access mode type does not
500 * match the caller's symbolic type descriptor.
501 * @throws ClassCastException if the access mode type matches the caller's
502 * symbolic type descriptor, but a reference cast fails.
503 */
504 public final native
505 @MethodHandle.PolymorphicSignature
506 @HotSpotIntrinsicCandidate
507 void set(Object... args);
508
509
510 // Volatile accessors
511
512 /**
513 * Returns the value of a variable, with memory semantics of reading as if
514 * the variable was declared {@code volatile}.
515 *
516 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
517 *
518 * <p>The symbolic type descriptor at the call site of {@code getVolatile}
519 * must match the access mode type that is the result of calling
520 * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
521 * VarHandle.
522 *
523 * @param args the signature-polymorphic parameter list of the form
524 * {@code (CT1 ct1, ..., CTn ctn)}
525 * , statically represented using varargs.
526 * @return the signature-polymorphic result that is the value of the
527 * variable
528 * , statically represented using {@code Object}.
529 * @throws UnsupportedOperationException if the access mode is unsupported
530 * for this VarHandle.
531 * @throws WrongMethodTypeException if the access mode type does not
532 * match the caller's symbolic type descriptor.
533 * @throws ClassCastException if the access mode type matches the caller's
534 * symbolic type descriptor, but a reference cast fails.
535 */
536 public final native
537 @MethodHandle.PolymorphicSignature
538 @HotSpotIntrinsicCandidate
539 Object getVolatile(Object... args);
540
541 /**
542 * Sets the value of a variable to the {@code newValue}, with memory
543 * semantics of setting as if the variable was declared {@code volatile}.
544 *
545 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
546 *
547 * <p>The symbolic type descriptor at the call site of {@code setVolatile}
548 * must match the access mode type that is the result of calling
549 * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
550 * VarHandle.
551 *
552 * @apiNote
553 * Ignoring the many semantic differences from C and C++, this method has
554 * memory ordering effects compatible with {@code memory_order_seq_cst}.
555 *
556 * @param args the signature-polymorphic parameter list of the form
557 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
558 * , statically represented using varargs.
559 * @throws UnsupportedOperationException if the access mode is unsupported
560 * for this VarHandle.
561 * @throws WrongMethodTypeException if the access mode type does not
562 * match the caller's symbolic type descriptor.
563 * @throws ClassCastException if the access mode type matches the caller's
564 * symbolic type descriptor, but a reference cast fails.
565 */
566 public final native
567 @MethodHandle.PolymorphicSignature
568 @HotSpotIntrinsicCandidate
569 void setVolatile(Object... args);
570
571
572 /**
573 * Returns the value of a variable, accessed in program order, but with no
574 * assurance of memory ordering effects with respect to other threads.
575 *
576 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
577 *
578 * <p>The symbolic type descriptor at the call site of {@code getOpaque}
579 * must match the access mode type that is the result of calling
580 * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
581 * VarHandle.
582 *
583 * @param args the signature-polymorphic parameter list of the form
584 * {@code (CT1 ct1, ..., CTn ctn)}
585 * , statically represented using varargs.
586 * @return the signature-polymorphic result that is the value of the
587 * variable
588 * , statically represented using {@code Object}.
589 * @throws UnsupportedOperationException if the access mode is unsupported
590 * for this VarHandle.
591 * @throws WrongMethodTypeException if the access mode type does not
592 * match the caller's symbolic type descriptor.
593 * @throws ClassCastException if the access mode type matches the caller's
594 * symbolic type descriptor, but a reference cast fails.
595 */
596 public final native
597 @MethodHandle.PolymorphicSignature
598 @HotSpotIntrinsicCandidate
599 Object getOpaque(Object... args);
600
601 /**
602 * Sets the value of a variable to the {@code newValue}, in program order,
603 * but with no assurance of memory ordering effects with respect to other
604 * threads.
605 *
606 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
607 *
608 * <p>The symbolic type descriptor at the call site of {@code setOpaque}
609 * must match the access mode type that is the result of calling
610 * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
611 * VarHandle.
612 *
613 * @param args the signature-polymorphic parameter list of the form
614 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
615 * , statically represented using varargs.
616 * @throws UnsupportedOperationException if the access mode is unsupported
617 * for this VarHandle.
618 * @throws WrongMethodTypeException if the access mode type does not
619 * match the caller's symbolic type descriptor.
620 * @throws ClassCastException if the access mode type matches the caller's
621 * symbolic type descriptor, but a reference cast fails.
622 */
623 public final native
624 @MethodHandle.PolymorphicSignature
625 @HotSpotIntrinsicCandidate
626 void setOpaque(Object... args);
627
628
629 // Lazy accessors
630
631 /**
632 * Returns the value of a variable, and ensures that subsequent loads and
633 * stores are not reordered before this access.
634 *
635 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
636 *
637 * <p>The symbolic type descriptor at the call site of {@code getAcquire}
638 * must match the access mode type that is the result of calling
639 * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
640 * VarHandle.
641 *
642 * @apiNote
643 * Ignoring the many semantic differences from C and C++, this method has
644 * memory ordering effects compatible with {@code memory_order_acquire}
645 * ordering.
646 *
647 * @param args the signature-polymorphic parameter list of the form
648 * {@code (CT1 ct1, ..., CTn ctn)}
649 * , statically represented using varargs.
650 * @return the signature-polymorphic result that is the value of the
651 * variable
652 * , statically represented using {@code Object}.
653 * @throws UnsupportedOperationException if the access mode is unsupported
654 * for this VarHandle.
655 * @throws WrongMethodTypeException if the access mode type does not
656 * match the caller's symbolic type descriptor.
657 * @throws ClassCastException if the access mode type matches the caller's
658 * symbolic type descriptor, but a reference cast fails.
659 */
660 public final native
661 @MethodHandle.PolymorphicSignature
662 @HotSpotIntrinsicCandidate
663 Object getAcquire(Object... args);
664
665 /**
666 * Sets the value of a variable to the {@code newValue}, and ensures that
667 * prior loads and stores are not reordered after this access.
668 *
669 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
670 *
671 * <p>The symbolic type descriptor at the call site of {@code setRelease}
672 * must match the access mode type that is the result of calling
673 * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
674 * VarHandle.
675 *
676 * @apiNote
677 * Ignoring the many semantic differences from C and C++, this method has
678 * memory ordering effects compatible with {@code memory_order_release}
679 * ordering.
680 *
681 * @param args the signature-polymorphic parameter list of the form
682 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
683 * , statically represented using varargs.
684 * @throws UnsupportedOperationException if the access mode is unsupported
685 * for this VarHandle.
686 * @throws WrongMethodTypeException if the access mode type does not
687 * match the caller's symbolic type descriptor.
688 * @throws ClassCastException if the access mode type matches the caller's
689 * symbolic type descriptor, but a reference cast fails.
690 */
691 public final native
692 @MethodHandle.PolymorphicSignature
693 @HotSpotIntrinsicCandidate
694 void setRelease(Object... args);
695
696
697 // Compare and set accessors
698
699 /**
700 * Atomically sets the value of a variable to the {@code newValue} with the
701 * memory semantics of {@link #setVolatile} if the variable's current value,
702 * referred to as the <em>witness value</em>, {@code ==} the
703 * {@code expectedValue}, as accessed with the memory semantics of
704 * {@link #getVolatile}.
705 *
706 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
707 *
708 * <p>The symbolic type descriptor at the call site of {@code
709 * compareAndSet} must match the access mode type that is the result of
710 * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
711 * this VarHandle.
712 *
713 * @param args the signature-polymorphic parameter list of the form
714 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
715 * , statically represented using varargs.
716 * @return {@code true} if successful, otherwise {@code false} if the
717 * witness value was not the same as the {@code expectedValue}.
718 * @throws UnsupportedOperationException if the access mode is unsupported
719 * for this VarHandle.
720 * @throws WrongMethodTypeException if the access mode type does not
721 * match the caller's symbolic type descriptor.
722 * @throws ClassCastException if the access mode type matches the caller's
723 * symbolic type descriptor, but a reference cast fails.
724 * @see #setVolatile(Object...)
725 * @see #getVolatile(Object...)
726 */
727 public final native
728 @MethodHandle.PolymorphicSignature
729 @HotSpotIntrinsicCandidate
730 boolean compareAndSet(Object... args);
731
732 /**
733 * Atomically sets the value of a variable to the {@code newValue} with the
734 * memory semantics of {@link #setVolatile} if the variable's current value,
735 * referred to as the <em>witness value</em>, {@code ==} the
736 * {@code expectedValue}, as accessed with the memory semantics of
737 * {@link #getVolatile}.
738 *
739 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
740 *
741 * <p>The symbolic type descriptor at the call site of {@code
742 * compareAndExchange}
743 * must match the access mode type that is the result of calling
744 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)}
745 * on this VarHandle.
746 *
747 * @param args the signature-polymorphic parameter list of the form
748 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
749 * , statically represented using varargs.
750 * @return the signature-polymorphic result that is the witness value, which
751 * will be the same as the {@code expectedValue} if successful
752 * , statically represented using {@code Object}.
753 * @throws UnsupportedOperationException if the access mode is unsupported
754 * for this VarHandle.
755 * @throws WrongMethodTypeException if the access mode type is not
756 * compatible with the caller's symbolic type descriptor.
757 * @throws ClassCastException if the access mode type is compatible with the
758 * caller's symbolic type descriptor, but a reference cast fails.
759 * @see #setVolatile(Object...)
760 * @see #getVolatile(Object...)
761 */
762 public final native
763 @MethodHandle.PolymorphicSignature
764 @HotSpotIntrinsicCandidate
765 Object compareAndExchange(Object... args);
766
767 /**
768 * Atomically sets the value of a variable to the {@code newValue} with the
769 * memory semantics of {@link #set} if the variable's current value,
770 * referred to as the <em>witness value</em>, {@code ==} the
771 * {@code expectedValue}, as accessed with the memory semantics of
772 * {@link #getAcquire}.
773 *
774 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
775 *
776 * <p>The symbolic type descriptor at the call site of {@code
777 * compareAndExchangeAcquire}
778 * must match the access mode type that is the result of calling
779 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
780 * this VarHandle.
781 *
782 * @param args the signature-polymorphic parameter list of the form
783 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
784 * , statically represented using varargs.
785 * @return the signature-polymorphic result that is the witness value, which
786 * will be the same as the {@code expectedValue} if successful
787 * , statically represented using {@code Object}.
788 * @throws UnsupportedOperationException if the access mode is unsupported
789 * for this VarHandle.
790 * @throws WrongMethodTypeException if the access mode type does not
791 * match the caller's symbolic type descriptor.
792 * @throws ClassCastException if the access mode type matches the caller's
793 * symbolic type descriptor, but a reference cast fails.
794 * @see #set(Object...)
795 * @see #getAcquire(Object...)
796 */
797 public final native
798 @MethodHandle.PolymorphicSignature
799 @HotSpotIntrinsicCandidate
800 Object compareAndExchangeAcquire(Object... args);
801
802 /**
803 * Atomically sets the value of a variable to the {@code newValue} with the
804 * memory semantics of {@link #setRelease} if the variable's current value,
805 * referred to as the <em>witness value</em>, {@code ==} the
806 * {@code expectedValue}, as accessed with the memory semantics of
807 * {@link #get}.
808 *
809 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
810 *
811 * <p>The symbolic type descriptor at the call site of {@code
812 * compareAndExchangeRelease}
813 * must match the access mode type that is the result of calling
814 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
815 * on this VarHandle.
816 *
817 * @param args the signature-polymorphic parameter list of the form
818 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
819 * , statically represented using varargs.
820 * @return the signature-polymorphic result that is the witness value, which
821 * will be the same as the {@code expectedValue} if successful
822 * , statically represented using {@code Object}.
823 * @throws UnsupportedOperationException if the access mode is unsupported
824 * for this VarHandle.
825 * @throws WrongMethodTypeException if the access mode type does not
826 * match the caller's symbolic type descriptor.
827 * @throws ClassCastException if the access mode type matches the caller's
828 * symbolic type descriptor, but a reference cast fails.
829 * @see #setRelease(Object...)
830 * @see #get(Object...)
831 */
832 public final native
833 @MethodHandle.PolymorphicSignature
834 @HotSpotIntrinsicCandidate
835 Object compareAndExchangeRelease(Object... args);
836
837 // Weak (spurious failures allowed)
838
839 /**
840 * Possibly atomically sets the value of a variable to the {@code newValue}
841 * with the semantics of {@link #set} if the variable's current value,
842 * referred to as the <em>witness value</em>, {@code ==} the
843 * {@code expectedValue}, as accessed with the memory semantics of
844 * {@link #get}.
845 *
846 * <p>This operation may fail spuriously (typically, due to memory
847 * contention) even if the witness value does match the expected value.
848 *
849 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
850 *
851 * <p>The symbolic type descriptor at the call site of {@code
852 * weakCompareAndSetPlain} must match the access mode type that is the result of
853 * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)}
854 * on this VarHandle.
855 *
856 * @param args the signature-polymorphic parameter list of the form
857 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
858 * , statically represented using varargs.
859 * @return {@code true} if successful, otherwise {@code false} if the
860 * witness value was not the same as the {@code expectedValue} or if this
861 * operation spuriously failed.
862 * @throws UnsupportedOperationException if the access mode is unsupported
863 * for this VarHandle.
864 * @throws WrongMethodTypeException if the access mode type does not
865 * match the caller's symbolic type descriptor.
866 * @throws ClassCastException if the access mode type matches the caller's
867 * symbolic type descriptor, but a reference cast fails.
868 * @see #set(Object...)
869 * @see #get(Object...)
870 */
871 public final native
872 @MethodHandle.PolymorphicSignature
873 @HotSpotIntrinsicCandidate
874 boolean weakCompareAndSetPlain(Object... args);
875
876 /**
877 * Possibly atomically sets the value of a variable to the {@code newValue}
878 * with the memory semantics of {@link #setVolatile} if the variable's
879 * current value, referred to as the <em>witness value</em>, {@code ==} the
880 * {@code expectedValue}, as accessed with the memory semantics of
881 * {@link #getVolatile}.
882 *
883 * <p>This operation may fail spuriously (typically, due to memory
884 * contention) even if the witness value does match the expected value.
885 *
886 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
887 *
888 * <p>The symbolic type descriptor at the call site of {@code
889 * weakCompareAndSet} must match the access mode type that is the
890 * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
891 * on this VarHandle.
892 *
893 * @param args the signature-polymorphic parameter list of the form
894 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
895 * , statically represented using varargs.
896 * @return {@code true} if successful, otherwise {@code false} if the
897 * witness value was not the same as the {@code expectedValue} or if this
898 * operation spuriously failed.
899 * @throws UnsupportedOperationException if the access mode is unsupported
900 * for this VarHandle.
901 * @throws WrongMethodTypeException if the access mode type does not
902 * match the caller's symbolic type descriptor.
903 * @throws ClassCastException if the access mode type matches the caller's
904 * symbolic type descriptor, but a reference cast fails.
905 * @see #setVolatile(Object...)
906 * @see #getVolatile(Object...)
907 */
908 public final native
909 @MethodHandle.PolymorphicSignature
910 @HotSpotIntrinsicCandidate
911 boolean weakCompareAndSet(Object... args);
912
913 /**
914 * Possibly atomically sets the value of a variable to the {@code newValue}
915 * with the semantics of {@link #set} if the variable's current value,
916 * referred to as the <em>witness value</em>, {@code ==} the
917 * {@code expectedValue}, as accessed with the memory semantics of
918 * {@link #getAcquire}.
919 *
920 * <p>This operation may fail spuriously (typically, due to memory
921 * contention) even if the witness value does match the expected value.
922 *
923 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
924 *
925 * <p>The symbolic type descriptor at the call site of {@code
926 * weakCompareAndSetAcquire}
927 * must match the access mode type that is the result of calling
928 * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
929 * on this VarHandle.
930 *
931 * @param args the signature-polymorphic parameter list of the form
932 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
933 * , statically represented using varargs.
934 * @return {@code true} if successful, otherwise {@code false} if the
935 * witness value was not the same as the {@code expectedValue} or if this
936 * operation spuriously failed.
937 * @throws UnsupportedOperationException if the access mode is unsupported
938 * for this VarHandle.
939 * @throws WrongMethodTypeException if the access mode type does not
940 * match the caller's symbolic type descriptor.
941 * @throws ClassCastException if the access mode type matches the caller's
942 * symbolic type descriptor, but a reference cast fails.
943 * @see #set(Object...)
944 * @see #getAcquire(Object...)
945 */
946 public final native
947 @MethodHandle.PolymorphicSignature
948 @HotSpotIntrinsicCandidate
949 boolean weakCompareAndSetAcquire(Object... args);
950
951 /**
952 * Possibly atomically sets the value of a variable to the {@code newValue}
953 * with the semantics of {@link #setRelease} if the variable's current
954 * value, referred to as the <em>witness value</em>, {@code ==} the
955 * {@code expectedValue}, as accessed with the memory semantics of
956 * {@link #get}.
957 *
958 * <p>This operation may fail spuriously (typically, due to memory
959 * contention) even if the witness value does match the expected value.
960 *
961 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
962 *
963 * <p>The symbolic type descriptor at the call site of {@code
964 * weakCompareAndSetRelease}
965 * must match the access mode type that is the result of calling
966 * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
967 * on this VarHandle.
968 *
969 * @param args the signature-polymorphic parameter list of the form
970 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
971 * , statically represented using varargs.
972 * @return {@code true} if successful, otherwise {@code false} if the
973 * witness value was not the same as the {@code expectedValue} or if this
974 * operation spuriously failed.
975 * @throws UnsupportedOperationException if the access mode is unsupported
976 * for this VarHandle.
977 * @throws WrongMethodTypeException if the access mode type does not
978 * match the caller's symbolic type descriptor.
979 * @throws ClassCastException if the access mode type matches the caller's
980 * symbolic type descriptor, but a reference cast fails.
981 * @see #setRelease(Object...)
982 * @see #get(Object...)
983 */
984 public final native
985 @MethodHandle.PolymorphicSignature
986 @HotSpotIntrinsicCandidate
987 boolean weakCompareAndSetRelease(Object... args);
988
989 /**
990 * Atomically sets the value of a variable to the {@code newValue} with the
991 * memory semantics of {@link #setVolatile} and returns the variable's
992 * previous value, as accessed with the memory semantics of
993 * {@link #getVolatile}.
994 *
995 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
996 *
997 * <p>The symbolic type descriptor at the call site of {@code getAndSet}
998 * must match the access mode type that is the result of calling
999 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
1000 * VarHandle.
1001 *
1002 * @param args the signature-polymorphic parameter list of the form
1003 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
1004 * , statically represented using varargs.
1005 * @return the signature-polymorphic result that is the previous value of
1006 * the variable
1007 * , statically represented using {@code Object}.
1008 * @throws UnsupportedOperationException if the access mode is unsupported
1009 * for this VarHandle.
1010 * @throws WrongMethodTypeException if the access mode type does not
1011 * match the caller's symbolic type descriptor.
1012 * @throws ClassCastException if the access mode type matches the caller's
1013 * symbolic type descriptor, but a reference cast fails.
1014 * @see #setVolatile(Object...)
1015 * @see #getVolatile(Object...)
1016 */
1017 public final native
1018 @MethodHandle.PolymorphicSignature
1019 @HotSpotIntrinsicCandidate
1020 Object getAndSet(Object... args);
1021
1022 /**
1023 * Atomically sets the value of a variable to the {@code newValue} with the
1024 * memory semantics of {@link #set} and returns the variable's
1025 * previous value, as accessed with the memory semantics of
1026 * {@link #getAcquire}.
1027 *
1028 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
1029 *
1030 * <p>The symbolic type descriptor at the call site of {@code getAndSetAcquire}
1031 * must match the access mode type that is the result of calling
1032 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)} on this
1033 * VarHandle.
1034 *
1035 * @param args the signature-polymorphic parameter list of the form
1036 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
1037 * , statically represented using varargs.
1038 * @return the signature-polymorphic result that is the previous value of
1039 * the variable
1040 * , statically represented using {@code Object}.
1041 * @throws UnsupportedOperationException if the access mode is unsupported
1042 * for this VarHandle.
1043 * @throws WrongMethodTypeException if the access mode type does not
1044 * match the caller's symbolic type descriptor.
1045 * @throws ClassCastException if the access mode type matches the caller's
1046 * symbolic type descriptor, but a reference cast fails.
1047 * @see #setVolatile(Object...)
1048 * @see #getVolatile(Object...)
1049 */
1050 public final native
1051 @MethodHandle.PolymorphicSignature
1052 @HotSpotIntrinsicCandidate
1053 Object getAndSetAcquire(Object... args);
1054
1055 /**
1056 * Atomically sets the value of a variable to the {@code newValue} with the
1057 * memory semantics of {@link #setRelease} and returns the variable's
1058 * previous value, as accessed with the memory semantics of
1059 * {@link #get}.
1060 *
1061 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
1062 *
1063 * <p>The symbolic type descriptor at the call site of {@code getAndSetRelease}
1064 * must match the access mode type that is the result of calling
1065 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_RELEASE)} on this
1066 * VarHandle.
1067 *
1068 * @param args the signature-polymorphic parameter list of the form
1069 * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
1070 * , statically represented using varargs.
1071 * @return the signature-polymorphic result that is the previous value of
1072 * the variable
1073 * , statically represented using {@code Object}.
1074 * @throws UnsupportedOperationException if the access mode is unsupported
1075 * for this VarHandle.
1076 * @throws WrongMethodTypeException if the access mode type does not
1077 * match the caller's symbolic type descriptor.
1078 * @throws ClassCastException if the access mode type matches the caller's
1079 * symbolic type descriptor, but a reference cast fails.
1080 * @see #setVolatile(Object...)
1081 * @see #getVolatile(Object...)
1082 */
1083 public final native
1084 @MethodHandle.PolymorphicSignature
1085 @HotSpotIntrinsicCandidate
1086 Object getAndSetRelease(Object... args);
1087
1088 // Primitive adders
1089 // Throw UnsupportedOperationException for refs
1090
1091 /**
1092 * Atomically adds the {@code value} to the current value of a variable with
1093 * the memory semantics of {@link #setVolatile}, and returns the variable's
1094 * previous value, as accessed with the memory semantics of
1095 * {@link #getVolatile}.
1096 *
1097 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
1098 *
1099 * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
1100 * must match the access mode type that is the result of calling
1101 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
1102 * VarHandle.
1103 *
1104 * @param args the signature-polymorphic parameter list of the form
1105 * {@code (CT1 ct1, ..., CTn ctn, T value)}
1106 * , statically represented using varargs.
1107 * @return the signature-polymorphic result that is the previous value of
1108 * the variable
1109 * , statically represented using {@code Object}.
1110 * @throws UnsupportedOperationException if the access mode is unsupported
1111 * for this VarHandle.
1112 * @throws WrongMethodTypeException if the access mode type does not
1113 * match the caller's symbolic type descriptor.
1114 * @throws ClassCastException if the access mode type matches the caller's
1115 * symbolic type descriptor, but a reference cast fails.
1116 * @see #setVolatile(Object...)
1117 * @see #getVolatile(Object...)
1118 */
1119 public final native
1120 @MethodHandle.PolymorphicSignature
1121 @HotSpotIntrinsicCandidate
1122 Object getAndAdd(Object... args);
1123
1124 /**
1125 * Atomically adds the {@code value} to the current value of a variable with
1126 * the memory semantics of {@link #set}, and returns the variable's
1127 * previous value, as accessed with the memory semantics of
1128 * {@link #getAcquire}.
1129 *
1130 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
1131 *
1132 * <p>The symbolic type descriptor at the call site of {@code getAndAddAcquire}
1133 * must match the access mode type that is the result of calling
1134 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)} on this
1135 * VarHandle.
1136 *
1137 * @param args the signature-polymorphic parameter list of the form
1138 * {@code (CT1 ct1, ..., CTn ctn, T value)}
1139 * , statically represented using varargs.
1140 * @return the signature-polymorphic result that is the previous value of
1141 * the variable
1142 * , statically represented using {@code Object}.
1143 * @throws UnsupportedOperationException if the access mode is unsupported
1144 * for this VarHandle.
1145 * @throws WrongMethodTypeException if the access mode type does not
1146 * match the caller's symbolic type descriptor.
1147 * @throws ClassCastException if the access mode type matches the caller's
1148 * symbolic type descriptor, but a reference cast fails.
1149 * @see #setVolatile(Object...)
1150 * @see #getVolatile(Object...)
1151 */
1152 public final native
1153 @MethodHandle.PolymorphicSignature
1154 @HotSpotIntrinsicCandidate
1155 Object getAndAddAcquire(Object... args);
1156
1157 /**
1158 * Atomically adds the {@code value} to the current value of a variable with
1159 * the memory semantics of {@link #setRelease}, and returns the variable's
1160 * previous value, as accessed with the memory semantics of
1161 * {@link #get}.
1162 *
1163 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
1164 *
1165 * <p>The symbolic type descriptor at the call site of {@code getAndAddRelease}
1166 * must match the access mode type that is the result of calling
1167 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_RELEASE)} on this
1168 * VarHandle.
1169 *
1170 * @param args the signature-polymorphic parameter list of the form
1171 * {@code (CT1 ct1, ..., CTn ctn, T value)}
1172 * , statically represented using varargs.
1173 * @return the signature-polymorphic result that is the previous value of
1174 * the variable
1175 * , statically represented using {@code Object}.
1176 * @throws UnsupportedOperationException if the access mode is unsupported
1177 * for this VarHandle.
1178 * @throws WrongMethodTypeException if the access mode type does not
1179 * match the caller's symbolic type descriptor.
1180 * @throws ClassCastException if the access mode type matches the caller's
1181 * symbolic type descriptor, but a reference cast fails.
1182 * @see #setVolatile(Object...)
1183 * @see #getVolatile(Object...)
1184 */
1185 public final native
1186 @MethodHandle.PolymorphicSignature
1187 @HotSpotIntrinsicCandidate
1188 Object getAndAddRelease(Object... args);
1189
1190
1191 // Bitwise operations
1192 // Throw UnsupportedOperationException for refs
1193
1194 /**
1195 * Atomically sets the value of a variable to the result of
1196 * bitwise OR between the variable's current value and the {@code mask}
1197 * with the memory semantics of {@link #setVolatile} and returns the
1198 * variable's previous value, as accessed with the memory semantics of
1199 * {@link #getVolatile}.
1200 *
1201 * <p>If the variable type is the non-integral {@code boolean} type then a
1202 * logical OR is performed instead of a bitwise OR.
1203 *
1204 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1205 *
1206 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOr}
1207 * must match the access mode type that is the result of calling
1208 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR)} on this
1209 * VarHandle.
1210 *
1211 * @param args the signature-polymorphic parameter list of the form
1212 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1213 * , statically represented using varargs.
1214 * @return the signature-polymorphic result that is the previous value of
1215 * the variable
1216 * , statically represented using {@code Object}.
1217 * @throws UnsupportedOperationException if the access mode is unsupported
1218 * for this VarHandle.
1219 * @throws WrongMethodTypeException if the access mode type does not
1220 * match the caller's symbolic type descriptor.
1221 * @throws ClassCastException if the access mode type matches the caller's
1222 * symbolic type descriptor, but a reference cast fails.
1223 * @see #setVolatile(Object...)
1224 * @see #getVolatile(Object...)
1225 */
1226 public final native
1227 @MethodHandle.PolymorphicSignature
1228 @HotSpotIntrinsicCandidate
1229 Object getAndBitwiseOr(Object... args);
1230
1231 /**
1232 * Atomically sets the value of a variable to the result of
1233 * bitwise OR between the variable's current value and the {@code mask}
1234 * with the memory semantics of {@link #set} and returns the
1235 * variable's previous value, as accessed with the memory semantics of
1236 * {@link #getAcquire}.
1237 *
1238 * <p>If the variable type is the non-integral {@code boolean} type then a
1239 * logical OR is performed instead of a bitwise OR.
1240 *
1241 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1242 *
1243 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrAcquire}
1244 * must match the access mode type that is the result of calling
1245 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)} on this
1246 * VarHandle.
1247 *
1248 * @param args the signature-polymorphic parameter list of the form
1249 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1250 * , statically represented using varargs.
1251 * @return the signature-polymorphic result that is the previous value of
1252 * the variable
1253 * , statically represented using {@code Object}.
1254 * @throws UnsupportedOperationException if the access mode is unsupported
1255 * for this VarHandle.
1256 * @throws WrongMethodTypeException if the access mode type does not
1257 * match the caller's symbolic type descriptor.
1258 * @throws ClassCastException if the access mode type matches the caller's
1259 * symbolic type descriptor, but a reference cast fails.
1260 * @see #set(Object...)
1261 * @see #getAcquire(Object...)
1262 */
1263 public final native
1264 @MethodHandle.PolymorphicSignature
1265 @HotSpotIntrinsicCandidate
1266 Object getAndBitwiseOrAcquire(Object... args);
1267
1268 /**
1269 * Atomically sets the value of a variable to the result of
1270 * bitwise OR between the variable's current value and the {@code mask}
1271 * with the memory semantics of {@link #setRelease} and returns the
1272 * variable's previous value, as accessed with the memory semantics of
1273 * {@link #get}.
1274 *
1275 * <p>If the variable type is the non-integral {@code boolean} type then a
1276 * logical OR is performed instead of a bitwise OR.
1277 *
1278 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1279 *
1280 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrRelease}
1281 * must match the access mode type that is the result of calling
1282 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)} on this
1283 * VarHandle.
1284 *
1285 * @param args the signature-polymorphic parameter list of the form
1286 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1287 * , statically represented using varargs.
1288 * @return the signature-polymorphic result that is the previous value of
1289 * the variable
1290 * , statically represented using {@code Object}.
1291 * @throws UnsupportedOperationException if the access mode is unsupported
1292 * for this VarHandle.
1293 * @throws WrongMethodTypeException if the access mode type does not
1294 * match the caller's symbolic type descriptor.
1295 * @throws ClassCastException if the access mode type matches the caller's
1296 * symbolic type descriptor, but a reference cast fails.
1297 * @see #setRelease(Object...)
1298 * @see #get(Object...)
1299 */
1300 public final native
1301 @MethodHandle.PolymorphicSignature
1302 @HotSpotIntrinsicCandidate
1303 Object getAndBitwiseOrRelease(Object... args);
1304
1305 /**
1306 * Atomically sets the value of a variable to the result of
1307 * bitwise AND between the variable's current value and the {@code mask}
1308 * with the memory semantics of {@link #setVolatile} and returns the
1309 * variable's previous value, as accessed with the memory semantics of
1310 * {@link #getVolatile}.
1311 *
1312 * <p>If the variable type is the non-integral {@code boolean} type then a
1313 * logical AND is performed instead of a bitwise AND.
1314 *
1315 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1316 *
1317 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAnd}
1318 * must match the access mode type that is the result of calling
1319 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND)} on this
1320 * VarHandle.
1321 *
1322 * @param args the signature-polymorphic parameter list of the form
1323 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1324 * , statically represented using varargs.
1325 * @return the signature-polymorphic result that is the previous value of
1326 * the variable
1327 * , statically represented using {@code Object}.
1328 * @throws UnsupportedOperationException if the access mode is unsupported
1329 * for this VarHandle.
1330 * @throws WrongMethodTypeException if the access mode type does not
1331 * match the caller's symbolic type descriptor.
1332 * @throws ClassCastException if the access mode type matches the caller's
1333 * symbolic type descriptor, but a reference cast fails.
1334 * @see #setVolatile(Object...)
1335 * @see #getVolatile(Object...)
1336 */
1337 public final native
1338 @MethodHandle.PolymorphicSignature
1339 @HotSpotIntrinsicCandidate
1340 Object getAndBitwiseAnd(Object... args);
1341
1342 /**
1343 * Atomically sets the value of a variable to the result of
1344 * bitwise AND between the variable's current value and the {@code mask}
1345 * with the memory semantics of {@link #set} and returns the
1346 * variable's previous value, as accessed with the memory semantics of
1347 * {@link #getAcquire}.
1348 *
1349 * <p>If the variable type is the non-integral {@code boolean} type then a
1350 * logical AND is performed instead of a bitwise AND.
1351 *
1352 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1353 *
1354 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndAcquire}
1355 * must match the access mode type that is the result of calling
1356 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)} on this
1357 * VarHandle.
1358 *
1359 * @param args the signature-polymorphic parameter list of the form
1360 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1361 * , statically represented using varargs.
1362 * @return the signature-polymorphic result that is the previous value of
1363 * the variable
1364 * , statically represented using {@code Object}.
1365 * @throws UnsupportedOperationException if the access mode is unsupported
1366 * for this VarHandle.
1367 * @throws WrongMethodTypeException if the access mode type does not
1368 * match the caller's symbolic type descriptor.
1369 * @throws ClassCastException if the access mode type matches the caller's
1370 * symbolic type descriptor, but a reference cast fails.
1371 * @see #set(Object...)
1372 * @see #getAcquire(Object...)
1373 */
1374 public final native
1375 @MethodHandle.PolymorphicSignature
1376 @HotSpotIntrinsicCandidate
1377 Object getAndBitwiseAndAcquire(Object... args);
1378
1379 /**
1380 * Atomically sets the value of a variable to the result of
1381 * bitwise AND between the variable's current value and the {@code mask}
1382 * with the memory semantics of {@link #setRelease} and returns the
1383 * variable's previous value, as accessed with the memory semantics of
1384 * {@link #get}.
1385 *
1386 * <p>If the variable type is the non-integral {@code boolean} type then a
1387 * logical AND is performed instead of a bitwise AND.
1388 *
1389 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1390 *
1391 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndRelease}
1392 * must match the access mode type that is the result of calling
1393 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)} on this
1394 * VarHandle.
1395 *
1396 * @param args the signature-polymorphic parameter list of the form
1397 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1398 * , statically represented using varargs.
1399 * @return the signature-polymorphic result that is the previous value of
1400 * the variable
1401 * , statically represented using {@code Object}.
1402 * @throws UnsupportedOperationException if the access mode is unsupported
1403 * for this VarHandle.
1404 * @throws WrongMethodTypeException if the access mode type does not
1405 * match the caller's symbolic type descriptor.
1406 * @throws ClassCastException if the access mode type matches the caller's
1407 * symbolic type descriptor, but a reference cast fails.
1408 * @see #setRelease(Object...)
1409 * @see #get(Object...)
1410 */
1411 public final native
1412 @MethodHandle.PolymorphicSignature
1413 @HotSpotIntrinsicCandidate
1414 Object getAndBitwiseAndRelease(Object... args);
1415
1416 /**
1417 * Atomically sets the value of a variable to the result of
1418 * bitwise XOR between the variable's current value and the {@code mask}
1419 * with the memory semantics of {@link #setVolatile} and returns the
1420 * variable's previous value, as accessed with the memory semantics of
1421 * {@link #getVolatile}.
1422 *
1423 * <p>If the variable type is the non-integral {@code boolean} type then a
1424 * logical XOR is performed instead of a bitwise XOR.
1425 *
1426 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1427 *
1428 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXor}
1429 * must match the access mode type that is the result of calling
1430 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR)} on this
1431 * VarHandle.
1432 *
1433 * @param args the signature-polymorphic parameter list of the form
1434 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1435 * , statically represented using varargs.
1436 * @return the signature-polymorphic result that is the previous value of
1437 * the variable
1438 * , statically represented using {@code Object}.
1439 * @throws UnsupportedOperationException if the access mode is unsupported
1440 * for this VarHandle.
1441 * @throws WrongMethodTypeException if the access mode type does not
1442 * match the caller's symbolic type descriptor.
1443 * @throws ClassCastException if the access mode type matches the caller's
1444 * symbolic type descriptor, but a reference cast fails.
1445 * @see #setVolatile(Object...)
1446 * @see #getVolatile(Object...)
1447 */
1448 public final native
1449 @MethodHandle.PolymorphicSignature
1450 @HotSpotIntrinsicCandidate
1451 Object getAndBitwiseXor(Object... args);
1452
1453 /**
1454 * Atomically sets the value of a variable to the result of
1455 * bitwise XOR between the variable's current value and the {@code mask}
1456 * with the memory semantics of {@link #set} and returns the
1457 * variable's previous value, as accessed with the memory semantics of
1458 * {@link #getAcquire}.
1459 *
1460 * <p>If the variable type is the non-integral {@code boolean} type then a
1461 * logical XOR is performed instead of a bitwise XOR.
1462 *
1463 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1464 *
1465 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorAcquire}
1466 * must match the access mode type that is the result of calling
1467 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)} on this
1468 * VarHandle.
1469 *
1470 * @param args the signature-polymorphic parameter list of the form
1471 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1472 * , statically represented using varargs.
1473 * @return the signature-polymorphic result that is the previous value of
1474 * the variable
1475 * , statically represented using {@code Object}.
1476 * @throws UnsupportedOperationException if the access mode is unsupported
1477 * for this VarHandle.
1478 * @throws WrongMethodTypeException if the access mode type does not
1479 * match the caller's symbolic type descriptor.
1480 * @throws ClassCastException if the access mode type matches the caller's
1481 * symbolic type descriptor, but a reference cast fails.
1482 * @see #set(Object...)
1483 * @see #getAcquire(Object...)
1484 */
1485 public final native
1486 @MethodHandle.PolymorphicSignature
1487 @HotSpotIntrinsicCandidate
1488 Object getAndBitwiseXorAcquire(Object... args);
1489
1490 /**
1491 * Atomically sets the value of a variable to the result of
1492 * bitwise XOR between the variable's current value and the {@code mask}
1493 * with the memory semantics of {@link #setRelease} and returns the
1494 * variable's previous value, as accessed with the memory semantics of
1495 * {@link #get}.
1496 *
1497 * <p>If the variable type is the non-integral {@code boolean} type then a
1498 * logical XOR is performed instead of a bitwise XOR.
1499 *
1500 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
1501 *
1502 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorRelease}
1503 * must match the access mode type that is the result of calling
1504 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)} on this
1505 * VarHandle.
1506 *
1507 * @param args the signature-polymorphic parameter list of the form
1508 * {@code (CT1 ct1, ..., CTn ctn, T mask)}
1509 * , statically represented using varargs.
1510 * @return the signature-polymorphic result that is the previous value of
1511 * the variable
1512 * , statically represented using {@code Object}.
1513 * @throws UnsupportedOperationException if the access mode is unsupported
1514 * for this VarHandle.
1515 * @throws WrongMethodTypeException if the access mode type does not
1516 * match the caller's symbolic type descriptor.
1517 * @throws ClassCastException if the access mode type matches the caller's
1518 * symbolic type descriptor, but a reference cast fails.
1519 * @see #setRelease(Object...)
1520 * @see #get(Object...)
1521 */
1522 public final native
1523 @MethodHandle.PolymorphicSignature
1524 @HotSpotIntrinsicCandidate
1525 Object getAndBitwiseXorRelease(Object... args);
1526
1527
1528 enum AccessType {
1529 GET(Object.class),
1530 SET(void.class),
1531 COMPARE_AND_SET(boolean.class),
1532 COMPARE_AND_EXCHANGE(Object.class),
1533 GET_AND_UPDATE(Object.class);
1534
1535 final Class<?> returnType;
1536 final boolean isMonomorphicInReturnType;
1537
1538 AccessType(Class<?> returnType) {
1539 this.returnType = returnType;
1540 isMonomorphicInReturnType = returnType != Object.class;
1541 }
1542
1543 MethodType accessModeType(Class<?> receiver, Class<?> value,
1544 Class<?>... intermediate) {
1545 Class<?>[] ps;
1546 int i;
1547 switch (this) {
1548 case GET:
1549 ps = allocateParameters(0, receiver, intermediate);
1550 fillParameters(ps, receiver, intermediate);
1551 return MethodType.methodType(value, ps);
1552 case SET:
1553 ps = allocateParameters(1, receiver, intermediate);
1554 i = fillParameters(ps, receiver, intermediate);
1555 ps[i] = value;
1556 return MethodType.methodType(void.class, ps);
1557 case COMPARE_AND_SET:
1558 ps = allocateParameters(2, receiver, intermediate);
1559 i = fillParameters(ps, receiver, intermediate);
1560 ps[i++] = value;
1561 ps[i] = value;
1562 return MethodType.methodType(boolean.class, ps);
1563 case COMPARE_AND_EXCHANGE:
1564 ps = allocateParameters(2, receiver, intermediate);
1565 i = fillParameters(ps, receiver, intermediate);
1566 ps[i++] = value;
1567 ps[i] = value;
1568 return MethodType.methodType(value, ps);
1569 case GET_AND_UPDATE:
1570 ps = allocateParameters(1, receiver, intermediate);
1571 i = fillParameters(ps, receiver, intermediate);
1572 ps[i] = value;
1573 return MethodType.methodType(value, ps);
1574 default:
1575 throw new InternalError("Unknown AccessType");
1576 }
1577 }
1578
1579 private static Class<?>[] allocateParameters(int values,
1580 Class<?> receiver, Class<?>... intermediate) {
1581 int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
1582 return new Class<?>[size];
1583 }
1584
1585 private static int fillParameters(Class<?>[] ps,
1586 Class<?> receiver, Class<?>... intermediate) {
1587 int i = 0;
1588 if (receiver != null)
1589 ps[i++] = receiver;
1590 for (int j = 0; j < intermediate.length; j++)
1591 ps[i++] = intermediate[j];
1592 return i;
1593 }
1594 }
1595
1596 /**
1597 * The set of access modes that specify how a variable, referenced by a
1598 * VarHandle, is accessed.
1599 */
1600 public enum AccessMode {
1601 /**
1602 * The access mode whose access is specified by the corresponding
1603 * method
1604 * {@link VarHandle#get VarHandle.get}
1605 */
1606 GET("get", AccessType.GET),
1607 /**
1608 * The access mode whose access is specified by the corresponding
1609 * method
1610 * {@link VarHandle#set VarHandle.set}
1611 */
1612 SET("set", AccessType.SET),
1613 /**
1614 * The access mode whose access is specified by the corresponding
1615 * method
1616 * {@link VarHandle#getVolatile VarHandle.getVolatile}
1617 */
1618 GET_VOLATILE("getVolatile", AccessType.GET),
1619 /**
1620 * The access mode whose access is specified by the corresponding
1621 * method
1622 * {@link VarHandle#setVolatile VarHandle.setVolatile}
1623 */
1624 SET_VOLATILE("setVolatile", AccessType.SET),
1625 /**
1626 * The access mode whose access is specified by the corresponding
1627 * method
1628 * {@link VarHandle#getAcquire VarHandle.getAcquire}
1629 */
1630 GET_ACQUIRE("getAcquire", AccessType.GET),
1631 /**
1632 * The access mode whose access is specified by the corresponding
1633 * method
1634 * {@link VarHandle#setRelease VarHandle.setRelease}
1635 */
1636 SET_RELEASE("setRelease", AccessType.SET),
1637 /**
1638 * The access mode whose access is specified by the corresponding
1639 * method
1640 * {@link VarHandle#getOpaque VarHandle.getOpaque}
1641 */
1642 GET_OPAQUE("getOpaque", AccessType.GET),
1643 /**
1644 * The access mode whose access is specified by the corresponding
1645 * method
1646 * {@link VarHandle#setOpaque VarHandle.setOpaque}
1647 */
1648 SET_OPAQUE("setOpaque", AccessType.SET),
1649 /**
1650 * The access mode whose access is specified by the corresponding
1651 * method
1652 * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
1653 */
1654 COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SET),
1655 /**
1656 * The access mode whose access is specified by the corresponding
1657 * method
1658 * {@link VarHandle#compareAndExchange VarHandle.compareAndExchange}
1659 */
1660 COMPARE_AND_EXCHANGE("compareAndExchange", AccessType.COMPARE_AND_EXCHANGE),
1661 /**
1662 * The access mode whose access is specified by the corresponding
1663 * method
1664 * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
1665 */
1666 COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
1667 /**
1668 * The access mode whose access is specified by the corresponding
1669 * method
1670 * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
1671 */
1672 COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
1673 /**
1674 * The access mode whose access is specified by the corresponding
1675 * method
1676 * {@link VarHandle#weakCompareAndSetPlain VarHandle.weakCompareAndSetPlain}
1677 */
1678 WEAK_COMPARE_AND_SET_PLAIN("weakCompareAndSetPlain", AccessType.COMPARE_AND_SET),
1679 /**
1680 * The access mode whose access is specified by the corresponding
1681 * method
1682 * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
1683 */
1684 WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SET),
1685 /**
1686 * The access mode whose access is specified by the corresponding
1687 * method
1688 * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
1689 */
1690 WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SET),
1691 /**
1692 * The access mode whose access is specified by the corresponding
1693 * method
1694 * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
1695 */
1696 WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SET),
1697 /**
1698 * The access mode whose access is specified by the corresponding
1699 * method
1700 * {@link VarHandle#getAndSet VarHandle.getAndSet}
1701 */
1702 GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
1703 /**
1704 * The access mode whose access is specified by the corresponding
1705 * method
1706 * {@link VarHandle#getAndSetAcquire VarHandle.getAndSetAcquire}
1707 */
1708 GET_AND_SET_ACQUIRE("getAndSetAcquire", AccessType.GET_AND_UPDATE),
1709 /**
1710 * The access mode whose access is specified by the corresponding
1711 * method
1712 * {@link VarHandle#getAndSetRelease VarHandle.getAndSetRelease}
1713 */
1714 GET_AND_SET_RELEASE("getAndSetRelease", AccessType.GET_AND_UPDATE),
1715 /**
1716 * The access mode whose access is specified by the corresponding
1717 * method
1718 * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
1719 */
1720 GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE),
1721 /**
1722 * The access mode whose access is specified by the corresponding
1723 * method
1724 * {@link VarHandle#getAndAddAcquire VarHandle.getAndAddAcquire}
1725 */
1726 GET_AND_ADD_ACQUIRE("getAndAddAcquire", AccessType.GET_AND_UPDATE),
1727 /**
1728 * The access mode whose access is specified by the corresponding
1729 * method
1730 * {@link VarHandle#getAndAddRelease VarHandle.getAndAddRelease}
1731 */
1732 GET_AND_ADD_RELEASE("getAndAddRelease", AccessType.GET_AND_UPDATE),
1733 /**
1734 * The access mode whose access is specified by the corresponding
1735 * method
1736 * {@link VarHandle#getAndBitwiseOr VarHandle.getAndBitwiseOr}
1737 */
1738 GET_AND_BITWISE_OR("getAndBitwiseOr", AccessType.GET_AND_UPDATE),
1739 /**
1740 * The access mode whose access is specified by the corresponding
1741 * method
1742 * {@link VarHandle#getAndBitwiseOrRelease VarHandle.getAndBitwiseOrRelease}
1743 */
1744 GET_AND_BITWISE_OR_RELEASE("getAndBitwiseOrRelease", AccessType.GET_AND_UPDATE),
1745 /**
1746 * The access mode whose access is specified by the corresponding
1747 * method
1748 * {@link VarHandle#getAndBitwiseOrAcquire VarHandle.getAndBitwiseOrAcquire}
1749 */
1750 GET_AND_BITWISE_OR_ACQUIRE("getAndBitwiseOrAcquire", AccessType.GET_AND_UPDATE),
1751 /**
1752 * The access mode whose access is specified by the corresponding
1753 * method
1754 * {@link VarHandle#getAndBitwiseAnd VarHandle.getAndBitwiseAnd}
1755 */
1756 GET_AND_BITWISE_AND("getAndBitwiseAnd", AccessType.GET_AND_UPDATE),
1757 /**
1758 * The access mode whose access is specified by the corresponding
1759 * method
1760 * {@link VarHandle#getAndBitwiseAndRelease VarHandle.getAndBitwiseAndRelease}
1761 */
1762 GET_AND_BITWISE_AND_RELEASE("getAndBitwiseAndRelease", AccessType.GET_AND_UPDATE),
1763 /**
1764 * The access mode whose access is specified by the corresponding
1765 * method
1766 * {@link VarHandle#getAndBitwiseAndAcquire VarHandle.getAndBitwiseAndAcquire}
1767 */
1768 GET_AND_BITWISE_AND_ACQUIRE("getAndBitwiseAndAcquire", AccessType.GET_AND_UPDATE),
1769 /**
1770 * The access mode whose access is specified by the corresponding
1771 * method
1772 * {@link VarHandle#getAndBitwiseXor VarHandle.getAndBitwiseXor}
1773 */
1774 GET_AND_BITWISE_XOR("getAndBitwiseXor", AccessType.GET_AND_UPDATE),
1775 /**
1776 * The access mode whose access is specified by the corresponding
1777 * method
1778 * {@link VarHandle#getAndBitwiseXorRelease VarHandle.getAndBitwiseXorRelease}
1779 */
1780 GET_AND_BITWISE_XOR_RELEASE("getAndBitwiseXorRelease", AccessType.GET_AND_UPDATE),
1781 /**
1782 * The access mode whose access is specified by the corresponding
1783 * method
1784 * {@link VarHandle#getAndBitwiseXorAcquire VarHandle.getAndBitwiseXorAcquire}
1785 */
1786 GET_AND_BITWISE_XOR_ACQUIRE("getAndBitwiseXorAcquire", AccessType.GET_AND_UPDATE),
1787 ;
1788
1789 static final Map<String, AccessMode> methodNameToAccessMode;
1790 static {
1791 AccessMode[] values = AccessMode.values();
1792 // Initial capacity of # values divided by the load factor is sufficient
1793 // to avoid resizes for the smallest table size (64)
1794 int initialCapacity = (int)(values.length / 0.75f) + 1;
1795 methodNameToAccessMode = new HashMap<>(initialCapacity);
1796 for (AccessMode am : values) {
1797 methodNameToAccessMode.put(am.methodName, am);
1798 }
1799 }
1800
1801 final String methodName;
1802 final AccessType at;
1803
1804 AccessMode(final String methodName, AccessType at) {
1805 this.methodName = methodName;
1806 this.at = at;
1807 }
1808
1809 /**
1810 * Returns the {@code VarHandle} signature-polymorphic method name
1811 * associated with this {@code AccessMode} value.
1812 *
1813 * @return the signature-polymorphic method name
1814 * @see #valueFromMethodName
1815 */
1816 public String methodName() {
1817 return methodName;
1818 }
1819
1820 /**
1821 * Returns the {@code AccessMode} value associated with the specified
1822 * {@code VarHandle} signature-polymorphic method name.
1823 *
1824 * @param methodName the signature-polymorphic method name
1825 * @return the {@code AccessMode} value
1826 * @throws IllegalArgumentException if there is no {@code AccessMode}
1827 * value associated with method name (indicating the method
1828 * name does not correspond to a {@code VarHandle}
1829 * signature-polymorphic method name).
1830 * @see #methodName()
1831 */
1832 public static AccessMode valueFromMethodName(String methodName) {
1833 AccessMode am = methodNameToAccessMode.get(methodName);
1834 if (am != null) return am;
1835 throw new IllegalArgumentException("No AccessMode value for method name " + methodName);
1836 }
1837
1838 @ForceInline
1839 static MemberName getMemberName(int ordinal, VarForm vform) {
1840 return vform.memberName_table[ordinal];
1841 }
1842 }
1843
1844 static final class AccessDescriptor {
1845 final MethodType symbolicMethodTypeErased;
1846 final MethodType symbolicMethodTypeInvoker;
1847 final Class<?> returnType;
1848 final int type;
1849 final int mode;
1850
1851 public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
1852 this.symbolicMethodTypeErased = symbolicMethodType.erase();
1853 this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
1854 this.returnType = symbolicMethodType.returnType();
1855 this.type = type;
1856 this.mode = mode;
1857 }
1858 }
1859
1860 /**
1861 * Returns the variable type of variables referenced by this VarHandle.
1862 *
1863 * @return the variable type of variables referenced by this VarHandle
1864 */
1865 public final Class<?> varType() {
1866 MethodType typeSet = accessModeType(AccessMode.SET);
1867 return typeSet.parameterType(typeSet.parameterCount() - 1);
1868 }
1869
1870 /**
1871 * Returns the coordinate types for this VarHandle.
1872 *
1873 * @return the coordinate types for this VarHandle. The returned
1874 * list is unmodifiable
1875 */
1876 public final List<Class<?>> coordinateTypes() {
1877 MethodType typeGet = accessModeType(AccessMode.GET);
1878 return typeGet.parameterList();
1879 }
1880
1881 /**
1882 * Obtains the access mode type for this VarHandle and a given access mode.
1883 *
1884 * <p>The access mode type's parameter types will consist of a prefix that
1885 * is the coordinate types of this VarHandle followed by further
1886 * types as defined by the access mode method.
1887 * The access mode type's return type is defined by the return type of the
1888 * access mode method.
1889 *
1890 * @param accessMode the access mode, corresponding to the
1891 * signature-polymorphic method of the same name
1892 * @return the access mode type for the given access mode
1893 */
1894 public final MethodType accessModeType(AccessMode accessMode) {
1895 TypesAndInvokers tis = getTypesAndInvokers();
1896 MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
1897 if (mt == null) {
1898 mt = tis.methodType_table[accessMode.at.ordinal()] =
1899 accessModeTypeUncached(accessMode);
1900 }
1901 return mt;
1902 }
1903 abstract MethodType accessModeTypeUncached(AccessMode accessMode);
1904
1905 /**
1906 * Returns {@code true} if the given access mode is supported, otherwise
1907 * {@code false}.
1908 *
1909 * <p>The return of a {@code false} value for a given access mode indicates
1910 * that an {@code UnsupportedOperationException} is thrown on invocation
1911 * of the corresponding access mode method.
1912 *
1913 * @param accessMode the access mode, corresponding to the
1914 * signature-polymorphic method of the same name
1915 * @return {@code true} if the given access mode is supported, otherwise
1916 * {@code false}.
1917 */
1918 public final boolean isAccessModeSupported(AccessMode accessMode) {
1919 return AccessMode.getMemberName(accessMode.ordinal(), vform) != null;
1920 }
1921
1922 /**
1923 * Obtains a method handle bound to this VarHandle and the given access
1924 * mode.
1925 *
1926 * @apiNote This method, for a VarHandle {@code vh} and access mode
1927 * {@code {access-mode}}, returns a method handle that is equivalent to
1928 * method handle {@code bmh} in the following code (though it may be more
1929 * efficient):
1930 * <pre>{@code
1931 * MethodHandle mh = MethodHandles.varHandleExactInvoker(
1932 * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
1933 *
1934 * MethodHandle bmh = mh.bindTo(vh);
1935 * }</pre>
1936 *
1937 * @param accessMode the access mode, corresponding to the
1938 * signature-polymorphic method of the same name
1939 * @return a method handle bound to this VarHandle and the given access mode
1940 */
1941 public final MethodHandle toMethodHandle(AccessMode accessMode) {
1942 MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
1943 if (mn != null) {
1944 MethodHandle mh = getMethodHandle(accessMode.ordinal());
1945 return mh.bindTo(this);
1946 }
1947 else {
1948 // Ensure an UnsupportedOperationException is thrown
1949 return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
1950 bindTo(this);
1951 }
1952 }
1953
1954 @Stable
1955 TypesAndInvokers typesAndInvokers;
1956
1957 static class TypesAndInvokers {
1958 final @Stable
1959 MethodType[] methodType_table =
1960 new MethodType[VarHandle.AccessType.values().length];
1961
1962 final @Stable
1963 MethodHandle[] methodHandle_table =
1964 new MethodHandle[AccessMode.values().length];
1965 }
1966
1967 @ForceInline
1968 private final TypesAndInvokers getTypesAndInvokers() {
1969 TypesAndInvokers tis = typesAndInvokers;
1970 if (tis == null) {
1971 tis = typesAndInvokers = new TypesAndInvokers();
1972 }
1973 return tis;
1974 }
1975
1976 @ForceInline
1977 final MethodHandle getMethodHandle(int mode) {
1978 TypesAndInvokers tis = getTypesAndInvokers();
1979 MethodHandle mh = tis.methodHandle_table[mode];
1980 if (mh == null) {
1981 mh = tis.methodHandle_table[mode] = getMethodHandleUncached(mode);
1982 }
1983 return mh;
1984 }
1985 private final MethodHandle getMethodHandleUncached(int mode) {
1986 MethodType mt = accessModeType(AccessMode.values()[mode]).
1987 insertParameterTypes(0, VarHandle.class);
1988 MemberName mn = vform.getMemberName(mode);
1989 DirectMethodHandle dmh = DirectMethodHandle.make(mn);
1990 // Such a method handle must not be publically exposed directly
1991 // otherwise it can be cracked, it must be transformed or rebound
1992 // before exposure
1993 MethodHandle mh = dmh.copyWith(mt, dmh.form);
1994 assert mh.type().erase() == mn.getMethodType().erase();
1995 return mh;
1996 }
1997
1998
1999 /*non-public*/
2000 final void updateVarForm(VarForm newVForm) {
2001 if (vform == newVForm) return;
2002 UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
2003 UNSAFE.fullFence();
2004 }
2005
2006 static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException>
2007 AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter(
2008 new Function<String, ArrayIndexOutOfBoundsException>() {
2009 @Override
2010 public ArrayIndexOutOfBoundsException apply(String s) {
2011 return new ArrayIndexOutOfBoundsException(s);
2012 }
2013 });
2014
2015 private static final long VFORM_OFFSET;
2016
2017 static {
2018 VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "vform");
2019
2020 // The VarHandleGuards must be initialized to ensure correct
2021 // compilation of the guard methods
2022 UNSAFE.ensureClassInitialized(VarHandleGuards.class);
2023 }
2024
2025
2026 // Fence methods
2027
2028 /**
2029 * Ensures that loads and stores before the fence will not be reordered
2030 * with
2031 * loads and stores after the fence.
2032 *
2033 * @apiNote Ignoring the many semantic differences from C and C++, this
2034 * method has memory ordering effects compatible with
2035 * {@code atomic_thread_fence(memory_order_seq_cst)}
2036 */
2037 @ForceInline
2038 public static void fullFence() {
2039 UNSAFE.fullFence();
2040 }
2041
2042 /**
2043 * Ensures that loads before the fence will not be reordered with loads and
2044 * stores after the fence.
2045 *
2046 * @apiNote Ignoring the many semantic differences from C and C++, this
2047 * method has memory ordering effects compatible with
2048 * {@code atomic_thread_fence(memory_order_acquire)}
2049 */
2050 @ForceInline
2051 public static void acquireFence() {
2052 UNSAFE.loadFence();
2053 }
2054
2055 /**
2056 * Ensures that loads and stores before the fence will not be
2057 * reordered with stores after the fence.
2058 *
2059 * @apiNote Ignoring the many semantic differences from C and C++, this
2060 * method has memory ordering effects compatible with
2061 * {@code atomic_thread_fence(memory_order_release)}
2062 */
2063 @ForceInline
2064 public static void releaseFence() {
2065 UNSAFE.storeFence();
2066 }
2067
2068 /**
2069 * Ensures that loads before the fence will not be reordered with
2070 * loads after the fence.
2071 */
2072 @ForceInline
2073 public static void loadLoadFence() {
2074 UNSAFE.loadLoadFence();
2075 }
2076
2077 /**
2078 * Ensures that stores before the fence will not be reordered with
2079 * stores after the fence.
2080 */
2081 @ForceInline
2082 public static void storeStoreFence() {
2083 UNSAFE.storeStoreFence();
2084 }
2085 }
2086