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