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 VarHandleValues.Array, 511 VarHandleValues.FieldInstanceReadOnly, 512 VarHandleValues.FieldStaticReadOnly { 513 final VarForm vform; 514 final boolean exact; 515 516 VarHandle(VarForm vform) { 517 this(vform, false); 518 } 519 520 VarHandle(VarForm vform, boolean exact) { 521 this.vform = vform; 522 this.exact = exact; 523 } 524 525 /** 526 * Returns the target VarHandle. Subclasses may override this method to implement 527 * additional logic for example lazily initializing the declaring class of a static field var handle. 528 */ 529 @ForceInline 530 VarHandle target() { 531 return asDirect(); 532 } 533 534 /** 535 * Returns the direct target VarHandle. Indirect VarHandle subclasses should implement 536 * this method. 537 * 538 * @see #getMethodHandle(int) 539 * @see #checkAccessModeThenIsDirect(AccessDescriptor) 540 */ 541 @ForceInline 542 VarHandle asDirect() { 543 return this; 544 } 545 546 /** 547 * Returns {@code true} if this VarHandle has <a href="#invoke-exact-behavior"><em>invoke-exact behavior</em></a>. 548 * 549 * @see #withInvokeExactBehavior() 550 * @see #withInvokeBehavior() 551 * @return {@code true} if this VarHandle has <a href="#invoke-exact-behavior"><em>invoke-exact behavior</em></a>. 552 * @since 16 553 */ 554 public boolean hasInvokeExactBehavior() { 555 return exact; 556 } 557 558 // Plain accessors 559 560 /** 561 * Returns the value of a variable, with memory semantics of reading as 562 * if the variable was declared non-{@code volatile}. Commonly referred to 563 * as plain read access. 564 * 565 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}. 566 * 567 * <p>The symbolic type descriptor at the call site of {@code get} 568 * must match the access mode type that is the result of calling 569 * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle. 570 * 571 * <p>This access mode is supported by all VarHandle instances and never 572 * throws {@code UnsupportedOperationException}. 573 * 574 * @param args the signature-polymorphic parameter list of the form 575 * {@code (CT1 ct1, ..., CTn)} 576 * , statically represented using varargs. 577 * @return the signature-polymorphic result that is the value of the 578 * variable 579 * , statically represented using {@code Object}. 580 * @throws WrongMethodTypeException if the access mode type does not 581 * match the caller's symbolic type descriptor. 582 * @throws ClassCastException if the access mode type matches the caller's 583 * symbolic type descriptor, but a reference cast fails. 584 */ 585 public final native 586 @MethodHandle.PolymorphicSignature 587 @IntrinsicCandidate 588 Object get(Object... args); 589 590 /** 591 * Sets the value of a variable to the {@code newValue}, with memory 592 * semantics of setting as if the variable was declared non-{@code volatile} 593 * and non-{@code final}. Commonly referred to as plain write access. 594 * 595 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void} 596 * 597 * <p>The symbolic type descriptor at the call site of {@code set} 598 * must match the access mode type that is the result of calling 599 * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle. 600 * 601 * @param args the signature-polymorphic parameter list of the form 602 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 603 * , statically represented using varargs. 604 * @throws UnsupportedOperationException if the access mode is unsupported 605 * for this VarHandle. 606 * @throws WrongMethodTypeException if the access mode type does not 607 * match the caller's symbolic type descriptor. 608 * @throws ClassCastException if the access mode type matches the caller's 609 * symbolic type descriptor, but a reference cast fails. 610 */ 611 public final native 612 @MethodHandle.PolymorphicSignature 613 @IntrinsicCandidate 614 void set(Object... args); 615 616 617 // Volatile accessors 618 619 /** 620 * Returns the value of a variable, with memory semantics of reading as if 621 * the variable was declared {@code volatile}. 622 * 623 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}. 624 * 625 * <p>The symbolic type descriptor at the call site of {@code getVolatile} 626 * must match the access mode type that is the result of calling 627 * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this 628 * VarHandle. 629 * 630 * @param args the signature-polymorphic parameter list of the form 631 * {@code (CT1 ct1, ..., CTn ctn)} 632 * , statically represented using varargs. 633 * @return the signature-polymorphic result that is the value of the 634 * variable 635 * , statically represented using {@code Object}. 636 * @throws UnsupportedOperationException if the access mode is unsupported 637 * for this VarHandle. 638 * @throws WrongMethodTypeException if the access mode type does not 639 * match the caller's symbolic type descriptor. 640 * @throws ClassCastException if the access mode type matches the caller's 641 * symbolic type descriptor, but a reference cast fails. 642 */ 643 public final native 644 @MethodHandle.PolymorphicSignature 645 @IntrinsicCandidate 646 Object getVolatile(Object... args); 647 648 /** 649 * Sets the value of a variable to the {@code newValue}, with memory 650 * semantics of setting as if the variable was declared {@code volatile}. 651 * 652 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}. 653 * 654 * <p>The symbolic type descriptor at the call site of {@code setVolatile} 655 * must match the access mode type that is the result of calling 656 * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this 657 * VarHandle. 658 * 659 * @apiNote 660 * Ignoring the many semantic differences from C and C++, this method has 661 * memory ordering effects compatible with {@code memory_order_seq_cst}. 662 * 663 * @param args the signature-polymorphic parameter list of the form 664 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 665 * , statically represented using varargs. 666 * @throws UnsupportedOperationException if the access mode is unsupported 667 * for this VarHandle. 668 * @throws WrongMethodTypeException if the access mode type does not 669 * match the caller's symbolic type descriptor. 670 * @throws ClassCastException if the access mode type matches the caller's 671 * symbolic type descriptor, but a reference cast fails. 672 */ 673 public final native 674 @MethodHandle.PolymorphicSignature 675 @IntrinsicCandidate 676 void setVolatile(Object... args); 677 678 679 /** 680 * Returns the value of a variable, accessed in program order, but with no 681 * assurance of memory ordering effects with respect to other threads. 682 * 683 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}. 684 * 685 * <p>The symbolic type descriptor at the call site of {@code getOpaque} 686 * must match the access mode type that is the result of calling 687 * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this 688 * VarHandle. 689 * 690 * @param args the signature-polymorphic parameter list of the form 691 * {@code (CT1 ct1, ..., CTn ctn)} 692 * , statically represented using varargs. 693 * @return the signature-polymorphic result that is the value of the 694 * variable 695 * , statically represented using {@code Object}. 696 * @throws UnsupportedOperationException if the access mode is unsupported 697 * for this VarHandle. 698 * @throws WrongMethodTypeException if the access mode type does not 699 * match the caller's symbolic type descriptor. 700 * @throws ClassCastException if the access mode type matches the caller's 701 * symbolic type descriptor, but a reference cast fails. 702 */ 703 public final native 704 @MethodHandle.PolymorphicSignature 705 @IntrinsicCandidate 706 Object getOpaque(Object... args); 707 708 /** 709 * Sets the value of a variable to the {@code newValue}, in program order, 710 * but with no assurance of memory ordering effects with respect to other 711 * threads. 712 * 713 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}. 714 * 715 * <p>The symbolic type descriptor at the call site of {@code setOpaque} 716 * must match the access mode type that is the result of calling 717 * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this 718 * VarHandle. 719 * 720 * @param args the signature-polymorphic parameter list of the form 721 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 722 * , statically represented using varargs. 723 * @throws UnsupportedOperationException if the access mode is unsupported 724 * for this VarHandle. 725 * @throws WrongMethodTypeException if the access mode type does not 726 * match the caller's symbolic type descriptor. 727 * @throws ClassCastException if the access mode type matches the caller's 728 * symbolic type descriptor, but a reference cast fails. 729 */ 730 public final native 731 @MethodHandle.PolymorphicSignature 732 @IntrinsicCandidate 733 void setOpaque(Object... args); 734 735 736 // Lazy accessors 737 738 /** 739 * Returns the value of a variable, and ensures that subsequent loads and 740 * stores are not reordered before this access. 741 * 742 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}. 743 * 744 * <p>The symbolic type descriptor at the call site of {@code getAcquire} 745 * must match the access mode type that is the result of calling 746 * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this 747 * VarHandle. 748 * 749 * @apiNote 750 * Ignoring the many semantic differences from C and C++, this method has 751 * memory ordering effects compatible with {@code memory_order_acquire} 752 * ordering. 753 * 754 * @param args the signature-polymorphic parameter list of the form 755 * {@code (CT1 ct1, ..., CTn ctn)} 756 * , statically represented using varargs. 757 * @return the signature-polymorphic result that is the value of the 758 * variable 759 * , statically represented using {@code Object}. 760 * @throws UnsupportedOperationException if the access mode is unsupported 761 * for this VarHandle. 762 * @throws WrongMethodTypeException if the access mode type does not 763 * match the caller's symbolic type descriptor. 764 * @throws ClassCastException if the access mode type matches the caller's 765 * symbolic type descriptor, but a reference cast fails. 766 */ 767 public final native 768 @MethodHandle.PolymorphicSignature 769 @IntrinsicCandidate 770 Object getAcquire(Object... args); 771 772 /** 773 * Sets the value of a variable to the {@code newValue}, and ensures that 774 * prior loads and stores are not reordered after this access. 775 * 776 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}. 777 * 778 * <p>The symbolic type descriptor at the call site of {@code setRelease} 779 * must match the access mode type that is the result of calling 780 * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this 781 * VarHandle. 782 * 783 * @apiNote 784 * Ignoring the many semantic differences from C and C++, this method has 785 * memory ordering effects compatible with {@code memory_order_release} 786 * ordering. 787 * 788 * @param args the signature-polymorphic parameter list of the form 789 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 790 * , statically represented using varargs. 791 * @throws UnsupportedOperationException if the access mode is unsupported 792 * for this VarHandle. 793 * @throws WrongMethodTypeException if the access mode type does not 794 * match the caller's symbolic type descriptor. 795 * @throws ClassCastException if the access mode type matches the caller's 796 * symbolic type descriptor, but a reference cast fails. 797 */ 798 public final native 799 @MethodHandle.PolymorphicSignature 800 @IntrinsicCandidate 801 void setRelease(Object... args); 802 803 804 // Compare and set accessors 805 806 /** 807 * Atomically sets the value of a variable to the {@code newValue} with the 808 * memory semantics of {@link #setVolatile} if the variable's current value, 809 * referred to as the <em>witness value</em>, {@code ==} the 810 * {@code expectedValue}, as accessed with the memory semantics of 811 * {@link #getVolatile}. 812 * 813 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}. 814 * 815 * <p>The symbolic type descriptor at the call site of {@code 816 * compareAndSet} must match the access mode type that is the result of 817 * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on 818 * this VarHandle. 819 * 820 * @param args the signature-polymorphic parameter list of the form 821 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 822 * , statically represented using varargs. 823 * @return {@code true} if successful, otherwise {@code false} if the 824 * <em>witness value</em> was not the same as the {@code expectedValue}. 825 * @throws UnsupportedOperationException if the access mode is unsupported 826 * for this VarHandle. 827 * @throws WrongMethodTypeException if the access mode type does not 828 * match the caller's symbolic type descriptor. 829 * @throws ClassCastException if the access mode type matches the caller's 830 * symbolic type descriptor, but a reference cast fails. 831 * @see #setVolatile(Object...) 832 * @see #getVolatile(Object...) 833 */ 834 public final native 835 @MethodHandle.PolymorphicSignature 836 @IntrinsicCandidate 837 boolean compareAndSet(Object... args); 838 839 /** 840 * Atomically sets the value of a variable to the {@code newValue} with the 841 * memory semantics of {@link #setVolatile} if the variable's current value, 842 * referred to as the <em>witness value</em>, {@code ==} the 843 * {@code expectedValue}, as accessed with the memory semantics of 844 * {@link #getVolatile}. 845 * 846 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}. 847 * 848 * <p>The symbolic type descriptor at the call site of {@code 849 * compareAndExchange} 850 * must match the access mode type that is the result of calling 851 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)} 852 * on this VarHandle. 853 * 854 * @param args the signature-polymorphic parameter list of the form 855 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 856 * , statically represented using varargs. 857 * @return the signature-polymorphic result that is the <em>witness value</em>, which 858 * will be the same as the {@code expectedValue} if successful 859 * , statically represented using {@code Object}. 860 * @throws UnsupportedOperationException if the access mode is unsupported 861 * for this VarHandle. 862 * @throws WrongMethodTypeException if the access mode type is not 863 * compatible with the caller's symbolic type descriptor. 864 * @throws ClassCastException if the access mode type is compatible with the 865 * caller's symbolic type descriptor, but a reference cast fails. 866 * @see #setVolatile(Object...) 867 * @see #getVolatile(Object...) 868 */ 869 public final native 870 @MethodHandle.PolymorphicSignature 871 @IntrinsicCandidate 872 Object compareAndExchange(Object... args); 873 874 /** 875 * Atomically sets the value of a variable to the {@code newValue} with the 876 * memory semantics of {@link #set} if the variable's current value, 877 * referred to as the <em>witness value</em>, {@code ==} the 878 * {@code expectedValue}, as accessed with the memory semantics of 879 * {@link #getAcquire}. 880 * 881 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}. 882 * 883 * <p>The symbolic type descriptor at the call site of {@code 884 * compareAndExchangeAcquire} 885 * must match the access mode type that is the result of calling 886 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on 887 * this VarHandle. 888 * 889 * @param args the signature-polymorphic parameter list of the form 890 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 891 * , statically represented using varargs. 892 * @return the signature-polymorphic result that is the <em>witness value</em>, which 893 * will be the same as the {@code expectedValue} if successful 894 * , statically represented using {@code Object}. 895 * @throws UnsupportedOperationException if the access mode is unsupported 896 * for this VarHandle. 897 * @throws WrongMethodTypeException if the access mode type does not 898 * match the caller's symbolic type descriptor. 899 * @throws ClassCastException if the access mode type matches the caller's 900 * symbolic type descriptor, but a reference cast fails. 901 * @see #set(Object...) 902 * @see #getAcquire(Object...) 903 */ 904 public final native 905 @MethodHandle.PolymorphicSignature 906 @IntrinsicCandidate 907 Object compareAndExchangeAcquire(Object... args); 908 909 /** 910 * Atomically sets the value of a variable to the {@code newValue} with the 911 * memory semantics of {@link #setRelease} if the variable's current value, 912 * referred to as the <em>witness value</em>, {@code ==} the 913 * {@code expectedValue}, as accessed with the memory semantics of 914 * {@link #get}. 915 * 916 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}. 917 * 918 * <p>The symbolic type descriptor at the call site of {@code 919 * compareAndExchangeRelease} 920 * must match the access mode type that is the result of calling 921 * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)} 922 * on this VarHandle. 923 * 924 * @param args the signature-polymorphic parameter list of the form 925 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 926 * , statically represented using varargs. 927 * @return the signature-polymorphic result that is the <em>witness value</em>, which 928 * will be the same as the {@code expectedValue} if successful 929 * , statically represented using {@code Object}. 930 * @throws UnsupportedOperationException if the access mode is unsupported 931 * for this VarHandle. 932 * @throws WrongMethodTypeException if the access mode type does not 933 * match the caller's symbolic type descriptor. 934 * @throws ClassCastException if the access mode type matches the caller's 935 * symbolic type descriptor, but a reference cast fails. 936 * @see #setRelease(Object...) 937 * @see #get(Object...) 938 */ 939 public final native 940 @MethodHandle.PolymorphicSignature 941 @IntrinsicCandidate 942 Object compareAndExchangeRelease(Object... args); 943 944 // Weak (spurious failures allowed) 945 946 /** 947 * Possibly atomically sets the value of a variable to the {@code newValue} 948 * with the semantics of {@link #set} if the variable's current value, 949 * referred to as the <em>witness value</em>, {@code ==} the 950 * {@code expectedValue}, as accessed with the memory semantics of 951 * {@link #get}. 952 * 953 * <p>This operation may fail spuriously (typically, due to memory 954 * contention) even if the <em>witness value</em> does match the expected value. 955 * 956 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}. 957 * 958 * <p>The symbolic type descriptor at the call site of {@code 959 * weakCompareAndSetPlain} must match the access mode type that is the result of 960 * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)} 961 * on this VarHandle. 962 * 963 * @param args the signature-polymorphic parameter list of the form 964 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 965 * , statically represented using varargs. 966 * @return {@code true} if successful, otherwise {@code false} if the 967 * <em>witness value</em> was not the same as the {@code expectedValue} or if this 968 * operation spuriously failed. 969 * @throws UnsupportedOperationException if the access mode is unsupported 970 * for this VarHandle. 971 * @throws WrongMethodTypeException if the access mode type does not 972 * match the caller's symbolic type descriptor. 973 * @throws ClassCastException if the access mode type matches the caller's 974 * symbolic type descriptor, but a reference cast fails. 975 * @see #set(Object...) 976 * @see #get(Object...) 977 */ 978 public final native 979 @MethodHandle.PolymorphicSignature 980 @IntrinsicCandidate 981 boolean weakCompareAndSetPlain(Object... args); 982 983 /** 984 * Possibly atomically sets the value of a variable to the {@code newValue} 985 * with the memory semantics of {@link #setVolatile} if the variable's 986 * current value, referred to as the <em>witness value</em>, {@code ==} the 987 * {@code expectedValue}, as accessed with the memory semantics of 988 * {@link #getVolatile}. 989 * 990 * <p>This operation may fail spuriously (typically, due to memory 991 * contention) even if the <em>witness value</em> does match the expected value. 992 * 993 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}. 994 * 995 * <p>The symbolic type descriptor at the call site of {@code 996 * weakCompareAndSet} must match the access mode type that is the 997 * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)} 998 * on this VarHandle. 999 * 1000 * @param args the signature-polymorphic parameter list of the form 1001 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 1002 * , statically represented using varargs. 1003 * @return {@code true} if successful, otherwise {@code false} if the 1004 * <em>witness value</em> was not the same as the {@code expectedValue} or if this 1005 * operation spuriously failed. 1006 * @throws UnsupportedOperationException if the access mode is unsupported 1007 * for this VarHandle. 1008 * @throws WrongMethodTypeException if the access mode type does not 1009 * match the caller's symbolic type descriptor. 1010 * @throws ClassCastException if the access mode type matches the caller's 1011 * symbolic type descriptor, but a reference cast fails. 1012 * @see #setVolatile(Object...) 1013 * @see #getVolatile(Object...) 1014 */ 1015 public final native 1016 @MethodHandle.PolymorphicSignature 1017 @IntrinsicCandidate 1018 boolean weakCompareAndSet(Object... args); 1019 1020 /** 1021 * Possibly atomically sets the value of a variable to the {@code newValue} 1022 * with the semantics of {@link #set} if the variable's current value, 1023 * referred to as the <em>witness value</em>, {@code ==} the 1024 * {@code expectedValue}, as accessed with the memory semantics of 1025 * {@link #getAcquire}. 1026 * 1027 * <p>This operation may fail spuriously (typically, due to memory 1028 * contention) even if the <em>witness value</em> does match the expected value. 1029 * 1030 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}. 1031 * 1032 * <p>The symbolic type descriptor at the call site of {@code 1033 * weakCompareAndSetAcquire} 1034 * must match the access mode type that is the result of calling 1035 * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)} 1036 * on this VarHandle. 1037 * 1038 * @param args the signature-polymorphic parameter list of the form 1039 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 1040 * , statically represented using varargs. 1041 * @return {@code true} if successful, otherwise {@code false} if the 1042 * <em>witness value</em> was not the same as the {@code expectedValue} or if this 1043 * operation spuriously failed. 1044 * @throws UnsupportedOperationException if the access mode is unsupported 1045 * for this VarHandle. 1046 * @throws WrongMethodTypeException if the access mode type does not 1047 * match the caller's symbolic type descriptor. 1048 * @throws ClassCastException if the access mode type matches the caller's 1049 * symbolic type descriptor, but a reference cast fails. 1050 * @see #set(Object...) 1051 * @see #getAcquire(Object...) 1052 */ 1053 public final native 1054 @MethodHandle.PolymorphicSignature 1055 @IntrinsicCandidate 1056 boolean weakCompareAndSetAcquire(Object... args); 1057 1058 /** 1059 * Possibly atomically sets the value of a variable to the {@code newValue} 1060 * with the semantics of {@link #setRelease} if the variable's current 1061 * value, referred to as the <em>witness value</em>, {@code ==} the 1062 * {@code expectedValue}, as accessed with the memory semantics of 1063 * {@link #get}. 1064 * 1065 * <p>This operation may fail spuriously (typically, due to memory 1066 * contention) even if the <em>witness value</em> does match the expected value. 1067 * 1068 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}. 1069 * 1070 * <p>The symbolic type descriptor at the call site of {@code 1071 * weakCompareAndSetRelease} 1072 * must match the access mode type that is the result of calling 1073 * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)} 1074 * on this VarHandle. 1075 * 1076 * @param args the signature-polymorphic parameter list of the form 1077 * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)} 1078 * , statically represented using varargs. 1079 * @return {@code true} if successful, otherwise {@code false} if the 1080 * <em>witness value</em> was not the same as the {@code expectedValue} or if this 1081 * operation spuriously failed. 1082 * @throws UnsupportedOperationException if the access mode is unsupported 1083 * for this VarHandle. 1084 * @throws WrongMethodTypeException if the access mode type does not 1085 * match the caller's symbolic type descriptor. 1086 * @throws ClassCastException if the access mode type matches the caller's 1087 * symbolic type descriptor, but a reference cast fails. 1088 * @see #setRelease(Object...) 1089 * @see #get(Object...) 1090 */ 1091 public final native 1092 @MethodHandle.PolymorphicSignature 1093 @IntrinsicCandidate 1094 boolean weakCompareAndSetRelease(Object... args); 1095 1096 /** 1097 * Atomically sets the value of a variable to the {@code newValue} with the 1098 * memory semantics of {@link #setVolatile} and returns the variable's 1099 * previous value, as accessed with the memory semantics of 1100 * {@link #getVolatile}. 1101 * 1102 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}. 1103 * 1104 * <p>The symbolic type descriptor at the call site of {@code getAndSet} 1105 * must match the access mode type that is the result of calling 1106 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this 1107 * VarHandle. 1108 * 1109 * @param args the signature-polymorphic parameter list of the form 1110 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 1111 * , statically represented using varargs. 1112 * @return the signature-polymorphic result that is the previous value of 1113 * the variable 1114 * , statically represented using {@code Object}. 1115 * @throws UnsupportedOperationException if the access mode is unsupported 1116 * for this VarHandle. 1117 * @throws WrongMethodTypeException if the access mode type does not 1118 * match the caller's symbolic type descriptor. 1119 * @throws ClassCastException if the access mode type matches the caller's 1120 * symbolic type descriptor, but a reference cast fails. 1121 * @see #setVolatile(Object...) 1122 * @see #getVolatile(Object...) 1123 */ 1124 public final native 1125 @MethodHandle.PolymorphicSignature 1126 @IntrinsicCandidate 1127 Object getAndSet(Object... args); 1128 1129 /** 1130 * Atomically sets the value of a variable to the {@code newValue} with the 1131 * memory semantics of {@link #set} and returns the variable's 1132 * previous value, as accessed with the memory semantics of 1133 * {@link #getAcquire}. 1134 * 1135 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}. 1136 * 1137 * <p>The symbolic type descriptor at the call site of {@code getAndSetAcquire} 1138 * must match the access mode type that is the result of calling 1139 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)} on this 1140 * VarHandle. 1141 * 1142 * @param args the signature-polymorphic parameter list of the form 1143 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 1144 * , statically represented using varargs. 1145 * @return the signature-polymorphic result that is the previous value of 1146 * the variable 1147 * , statically represented using {@code Object}. 1148 * @throws UnsupportedOperationException if the access mode is unsupported 1149 * for this VarHandle. 1150 * @throws WrongMethodTypeException if the access mode type does not 1151 * match the caller's symbolic type descriptor. 1152 * @throws ClassCastException if the access mode type matches the caller's 1153 * symbolic type descriptor, but a reference cast fails. 1154 * @see #setVolatile(Object...) 1155 * @see #getVolatile(Object...) 1156 */ 1157 public final native 1158 @MethodHandle.PolymorphicSignature 1159 @IntrinsicCandidate 1160 Object getAndSetAcquire(Object... args); 1161 1162 /** 1163 * Atomically sets the value of a variable to the {@code newValue} with the 1164 * memory semantics of {@link #setRelease} and returns the variable's 1165 * previous value, as accessed with the memory semantics of 1166 * {@link #get}. 1167 * 1168 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}. 1169 * 1170 * <p>The symbolic type descriptor at the call site of {@code getAndSetRelease} 1171 * must match the access mode type that is the result of calling 1172 * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_RELEASE)} on this 1173 * VarHandle. 1174 * 1175 * @param args the signature-polymorphic parameter list of the form 1176 * {@code (CT1 ct1, ..., CTn ctn, T newValue)} 1177 * , statically represented using varargs. 1178 * @return the signature-polymorphic result that is the previous value of 1179 * the variable 1180 * , statically represented using {@code Object}. 1181 * @throws UnsupportedOperationException if the access mode is unsupported 1182 * for this VarHandle. 1183 * @throws WrongMethodTypeException if the access mode type does not 1184 * match the caller's symbolic type descriptor. 1185 * @throws ClassCastException if the access mode type matches the caller's 1186 * symbolic type descriptor, but a reference cast fails. 1187 * @see #setVolatile(Object...) 1188 * @see #getVolatile(Object...) 1189 */ 1190 public final native 1191 @MethodHandle.PolymorphicSignature 1192 @IntrinsicCandidate 1193 Object getAndSetRelease(Object... args); 1194 1195 // Primitive adders 1196 // Throw UnsupportedOperationException for refs 1197 1198 /** 1199 * Atomically adds the {@code value} to the current value of a variable with 1200 * the memory semantics of {@link #setVolatile}, and returns the variable's 1201 * previous value, as accessed with the memory semantics of 1202 * {@link #getVolatile}. 1203 * 1204 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}. 1205 * 1206 * <p>The symbolic type descriptor at the call site of {@code getAndAdd} 1207 * must match the access mode type that is the result of calling 1208 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this 1209 * VarHandle. 1210 * 1211 * @param args the signature-polymorphic parameter list of the form 1212 * {@code (CT1 ct1, ..., CTn ctn, T value)} 1213 * , statically represented using varargs. 1214 * @return the signature-polymorphic result that is the previous value of 1215 * the variable 1216 * , statically represented using {@code Object}. 1217 * @throws UnsupportedOperationException if the access mode is unsupported 1218 * for this VarHandle. 1219 * @throws WrongMethodTypeException if the access mode type does not 1220 * match the caller's symbolic type descriptor. 1221 * @throws ClassCastException if the access mode type matches the caller's 1222 * symbolic type descriptor, but a reference cast fails. 1223 * @see #setVolatile(Object...) 1224 * @see #getVolatile(Object...) 1225 */ 1226 public final native 1227 @MethodHandle.PolymorphicSignature 1228 @IntrinsicCandidate 1229 Object getAndAdd(Object... args); 1230 1231 /** 1232 * Atomically adds the {@code value} to the current value of a variable with 1233 * the memory semantics of {@link #set}, and returns the variable's 1234 * previous value, as accessed with the memory semantics of 1235 * {@link #getAcquire}. 1236 * 1237 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}. 1238 * 1239 * <p>The symbolic type descriptor at the call site of {@code getAndAddAcquire} 1240 * must match the access mode type that is the result of calling 1241 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)} on this 1242 * VarHandle. 1243 * 1244 * @param args the signature-polymorphic parameter list of the form 1245 * {@code (CT1 ct1, ..., CTn ctn, T value)} 1246 * , statically represented using varargs. 1247 * @return the signature-polymorphic result that is the previous value of 1248 * the variable 1249 * , statically represented using {@code Object}. 1250 * @throws UnsupportedOperationException if the access mode is unsupported 1251 * for this VarHandle. 1252 * @throws WrongMethodTypeException if the access mode type does not 1253 * match the caller's symbolic type descriptor. 1254 * @throws ClassCastException if the access mode type matches the caller's 1255 * symbolic type descriptor, but a reference cast fails. 1256 * @see #setVolatile(Object...) 1257 * @see #getVolatile(Object...) 1258 */ 1259 public final native 1260 @MethodHandle.PolymorphicSignature 1261 @IntrinsicCandidate 1262 Object getAndAddAcquire(Object... args); 1263 1264 /** 1265 * Atomically adds the {@code value} to the current value of a variable with 1266 * the memory semantics of {@link #setRelease}, and returns the variable's 1267 * previous value, as accessed with the memory semantics of 1268 * {@link #get}. 1269 * 1270 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}. 1271 * 1272 * <p>The symbolic type descriptor at the call site of {@code getAndAddRelease} 1273 * must match the access mode type that is the result of calling 1274 * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_RELEASE)} on this 1275 * VarHandle. 1276 * 1277 * @param args the signature-polymorphic parameter list of the form 1278 * {@code (CT1 ct1, ..., CTn ctn, T value)} 1279 * , statically represented using varargs. 1280 * @return the signature-polymorphic result that is the previous value of 1281 * the variable 1282 * , statically represented using {@code Object}. 1283 * @throws UnsupportedOperationException if the access mode is unsupported 1284 * for this VarHandle. 1285 * @throws WrongMethodTypeException if the access mode type does not 1286 * match the caller's symbolic type descriptor. 1287 * @throws ClassCastException if the access mode type matches the caller's 1288 * symbolic type descriptor, but a reference cast fails. 1289 * @see #setVolatile(Object...) 1290 * @see #getVolatile(Object...) 1291 */ 1292 public final native 1293 @MethodHandle.PolymorphicSignature 1294 @IntrinsicCandidate 1295 Object getAndAddRelease(Object... args); 1296 1297 1298 // Bitwise operations 1299 // Throw UnsupportedOperationException for refs 1300 1301 /** 1302 * Atomically sets the value of a variable to the result of 1303 * bitwise OR between the variable's current value and the {@code mask} 1304 * with the memory semantics of {@link #setVolatile} and returns the 1305 * variable's previous value, as accessed with the memory semantics of 1306 * {@link #getVolatile}. 1307 * 1308 * <p>If the variable type is the non-integral {@code boolean} type then a 1309 * logical OR is performed instead of a bitwise OR. 1310 * 1311 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1312 * 1313 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOr} 1314 * must match the access mode type that is the result of calling 1315 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR)} on this 1316 * VarHandle. 1317 * 1318 * @param args the signature-polymorphic parameter list of the form 1319 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1320 * , statically represented using varargs. 1321 * @return the signature-polymorphic result that is the previous value of 1322 * the variable 1323 * , statically represented using {@code Object}. 1324 * @throws UnsupportedOperationException if the access mode is unsupported 1325 * for this VarHandle. 1326 * @throws WrongMethodTypeException if the access mode type does not 1327 * match the caller's symbolic type descriptor. 1328 * @throws ClassCastException if the access mode type matches the caller's 1329 * symbolic type descriptor, but a reference cast fails. 1330 * @see #setVolatile(Object...) 1331 * @see #getVolatile(Object...) 1332 */ 1333 public final native 1334 @MethodHandle.PolymorphicSignature 1335 @IntrinsicCandidate 1336 Object getAndBitwiseOr(Object... args); 1337 1338 /** 1339 * Atomically sets the value of a variable to the result of 1340 * bitwise OR between the variable's current value and the {@code mask} 1341 * with the memory semantics of {@link #set} and returns the 1342 * variable's previous value, as accessed with the memory semantics of 1343 * {@link #getAcquire}. 1344 * 1345 * <p>If the variable type is the non-integral {@code boolean} type then a 1346 * logical OR is performed instead of a bitwise OR. 1347 * 1348 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1349 * 1350 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrAcquire} 1351 * must match the access mode type that is the result of calling 1352 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)} on this 1353 * VarHandle. 1354 * 1355 * @param args the signature-polymorphic parameter list of the form 1356 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1357 * , statically represented using varargs. 1358 * @return the signature-polymorphic result that is the previous value of 1359 * the variable 1360 * , statically represented using {@code Object}. 1361 * @throws UnsupportedOperationException if the access mode is unsupported 1362 * for this VarHandle. 1363 * @throws WrongMethodTypeException if the access mode type does not 1364 * match the caller's symbolic type descriptor. 1365 * @throws ClassCastException if the access mode type matches the caller's 1366 * symbolic type descriptor, but a reference cast fails. 1367 * @see #set(Object...) 1368 * @see #getAcquire(Object...) 1369 */ 1370 public final native 1371 @MethodHandle.PolymorphicSignature 1372 @IntrinsicCandidate 1373 Object getAndBitwiseOrAcquire(Object... args); 1374 1375 /** 1376 * Atomically sets the value of a variable to the result of 1377 * bitwise OR between the variable's current value and the {@code mask} 1378 * with the memory semantics of {@link #setRelease} and returns the 1379 * variable's previous value, as accessed with the memory semantics of 1380 * {@link #get}. 1381 * 1382 * <p>If the variable type is the non-integral {@code boolean} type then a 1383 * logical OR is performed instead of a bitwise OR. 1384 * 1385 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1386 * 1387 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrRelease} 1388 * must match the access mode type that is the result of calling 1389 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)} on this 1390 * VarHandle. 1391 * 1392 * @param args the signature-polymorphic parameter list of the form 1393 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1394 * , statically represented using varargs. 1395 * @return the signature-polymorphic result that is the previous value of 1396 * the variable 1397 * , statically represented using {@code Object}. 1398 * @throws UnsupportedOperationException if the access mode is unsupported 1399 * for this VarHandle. 1400 * @throws WrongMethodTypeException if the access mode type does not 1401 * match the caller's symbolic type descriptor. 1402 * @throws ClassCastException if the access mode type matches the caller's 1403 * symbolic type descriptor, but a reference cast fails. 1404 * @see #setRelease(Object...) 1405 * @see #get(Object...) 1406 */ 1407 public final native 1408 @MethodHandle.PolymorphicSignature 1409 @IntrinsicCandidate 1410 Object getAndBitwiseOrRelease(Object... args); 1411 1412 /** 1413 * Atomically sets the value of a variable to the result of 1414 * bitwise AND between the variable's current value and the {@code mask} 1415 * with the memory semantics of {@link #setVolatile} and returns the 1416 * variable's previous value, as accessed with the memory semantics of 1417 * {@link #getVolatile}. 1418 * 1419 * <p>If the variable type is the non-integral {@code boolean} type then a 1420 * logical AND is performed instead of a bitwise AND. 1421 * 1422 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1423 * 1424 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAnd} 1425 * must match the access mode type that is the result of calling 1426 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND)} on this 1427 * VarHandle. 1428 * 1429 * @param args the signature-polymorphic parameter list of the form 1430 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1431 * , statically represented using varargs. 1432 * @return the signature-polymorphic result that is the previous value of 1433 * the variable 1434 * , statically represented using {@code Object}. 1435 * @throws UnsupportedOperationException if the access mode is unsupported 1436 * for this VarHandle. 1437 * @throws WrongMethodTypeException if the access mode type does not 1438 * match the caller's symbolic type descriptor. 1439 * @throws ClassCastException if the access mode type matches the caller's 1440 * symbolic type descriptor, but a reference cast fails. 1441 * @see #setVolatile(Object...) 1442 * @see #getVolatile(Object...) 1443 */ 1444 public final native 1445 @MethodHandle.PolymorphicSignature 1446 @IntrinsicCandidate 1447 Object getAndBitwiseAnd(Object... args); 1448 1449 /** 1450 * Atomically sets the value of a variable to the result of 1451 * bitwise AND between the variable's current value and the {@code mask} 1452 * with the memory semantics of {@link #set} and returns the 1453 * variable's previous value, as accessed with the memory semantics of 1454 * {@link #getAcquire}. 1455 * 1456 * <p>If the variable type is the non-integral {@code boolean} type then a 1457 * logical AND is performed instead of a bitwise AND. 1458 * 1459 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1460 * 1461 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndAcquire} 1462 * must match the access mode type that is the result of calling 1463 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)} on this 1464 * VarHandle. 1465 * 1466 * @param args the signature-polymorphic parameter list of the form 1467 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1468 * , statically represented using varargs. 1469 * @return the signature-polymorphic result that is the previous value of 1470 * the variable 1471 * , statically represented using {@code Object}. 1472 * @throws UnsupportedOperationException if the access mode is unsupported 1473 * for this VarHandle. 1474 * @throws WrongMethodTypeException if the access mode type does not 1475 * match the caller's symbolic type descriptor. 1476 * @throws ClassCastException if the access mode type matches the caller's 1477 * symbolic type descriptor, but a reference cast fails. 1478 * @see #set(Object...) 1479 * @see #getAcquire(Object...) 1480 */ 1481 public final native 1482 @MethodHandle.PolymorphicSignature 1483 @IntrinsicCandidate 1484 Object getAndBitwiseAndAcquire(Object... args); 1485 1486 /** 1487 * Atomically sets the value of a variable to the result of 1488 * bitwise AND between the variable's current value and the {@code mask} 1489 * with the memory semantics of {@link #setRelease} and returns the 1490 * variable's previous value, as accessed with the memory semantics of 1491 * {@link #get}. 1492 * 1493 * <p>If the variable type is the non-integral {@code boolean} type then a 1494 * logical AND is performed instead of a bitwise AND. 1495 * 1496 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1497 * 1498 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndRelease} 1499 * must match the access mode type that is the result of calling 1500 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)} on this 1501 * VarHandle. 1502 * 1503 * @param args the signature-polymorphic parameter list of the form 1504 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1505 * , statically represented using varargs. 1506 * @return the signature-polymorphic result that is the previous value of 1507 * the variable 1508 * , statically represented using {@code Object}. 1509 * @throws UnsupportedOperationException if the access mode is unsupported 1510 * for this VarHandle. 1511 * @throws WrongMethodTypeException if the access mode type does not 1512 * match the caller's symbolic type descriptor. 1513 * @throws ClassCastException if the access mode type matches the caller's 1514 * symbolic type descriptor, but a reference cast fails. 1515 * @see #setRelease(Object...) 1516 * @see #get(Object...) 1517 */ 1518 public final native 1519 @MethodHandle.PolymorphicSignature 1520 @IntrinsicCandidate 1521 Object getAndBitwiseAndRelease(Object... args); 1522 1523 /** 1524 * Atomically sets the value of a variable to the result of 1525 * bitwise XOR between the variable's current value and the {@code mask} 1526 * with the memory semantics of {@link #setVolatile} and returns the 1527 * variable's previous value, as accessed with the memory semantics of 1528 * {@link #getVolatile}. 1529 * 1530 * <p>If the variable type is the non-integral {@code boolean} type then a 1531 * logical XOR is performed instead of a bitwise XOR. 1532 * 1533 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1534 * 1535 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXor} 1536 * must match the access mode type that is the result of calling 1537 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR)} on this 1538 * VarHandle. 1539 * 1540 * @param args the signature-polymorphic parameter list of the form 1541 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1542 * , statically represented using varargs. 1543 * @return the signature-polymorphic result that is the previous value of 1544 * the variable 1545 * , statically represented using {@code Object}. 1546 * @throws UnsupportedOperationException if the access mode is unsupported 1547 * for this VarHandle. 1548 * @throws WrongMethodTypeException if the access mode type does not 1549 * match the caller's symbolic type descriptor. 1550 * @throws ClassCastException if the access mode type matches the caller's 1551 * symbolic type descriptor, but a reference cast fails. 1552 * @see #setVolatile(Object...) 1553 * @see #getVolatile(Object...) 1554 */ 1555 public final native 1556 @MethodHandle.PolymorphicSignature 1557 @IntrinsicCandidate 1558 Object getAndBitwiseXor(Object... args); 1559 1560 /** 1561 * Atomically sets the value of a variable to the result of 1562 * bitwise XOR between the variable's current value and the {@code mask} 1563 * with the memory semantics of {@link #set} and returns the 1564 * variable's previous value, as accessed with the memory semantics of 1565 * {@link #getAcquire}. 1566 * 1567 * <p>If the variable type is the non-integral {@code boolean} type then a 1568 * logical XOR is performed instead of a bitwise XOR. 1569 * 1570 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1571 * 1572 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorAcquire} 1573 * must match the access mode type that is the result of calling 1574 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)} on this 1575 * VarHandle. 1576 * 1577 * @param args the signature-polymorphic parameter list of the form 1578 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1579 * , statically represented using varargs. 1580 * @return the signature-polymorphic result that is the previous value of 1581 * the variable 1582 * , statically represented using {@code Object}. 1583 * @throws UnsupportedOperationException if the access mode is unsupported 1584 * for this VarHandle. 1585 * @throws WrongMethodTypeException if the access mode type does not 1586 * match the caller's symbolic type descriptor. 1587 * @throws ClassCastException if the access mode type matches the caller's 1588 * symbolic type descriptor, but a reference cast fails. 1589 * @see #set(Object...) 1590 * @see #getAcquire(Object...) 1591 */ 1592 public final native 1593 @MethodHandle.PolymorphicSignature 1594 @IntrinsicCandidate 1595 Object getAndBitwiseXorAcquire(Object... args); 1596 1597 /** 1598 * Atomically sets the value of a variable to the result of 1599 * bitwise XOR between the variable's current value and the {@code mask} 1600 * with the memory semantics of {@link #setRelease} and returns the 1601 * variable's previous value, as accessed with the memory semantics of 1602 * {@link #get}. 1603 * 1604 * <p>If the variable type is the non-integral {@code boolean} type then a 1605 * logical XOR is performed instead of a bitwise XOR. 1606 * 1607 * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}. 1608 * 1609 * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorRelease} 1610 * must match the access mode type that is the result of calling 1611 * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)} on this 1612 * VarHandle. 1613 * 1614 * @param args the signature-polymorphic parameter list of the form 1615 * {@code (CT1 ct1, ..., CTn ctn, T mask)} 1616 * , statically represented using varargs. 1617 * @return the signature-polymorphic result that is the previous value of 1618 * the variable 1619 * , statically represented using {@code Object}. 1620 * @throws UnsupportedOperationException if the access mode is unsupported 1621 * for this VarHandle. 1622 * @throws WrongMethodTypeException if the access mode type does not 1623 * match the caller's symbolic type descriptor. 1624 * @throws ClassCastException if the access mode type matches the caller's 1625 * symbolic type descriptor, but a reference cast fails. 1626 * @see #setRelease(Object...) 1627 * @see #get(Object...) 1628 */ 1629 public final native 1630 @MethodHandle.PolymorphicSignature 1631 @IntrinsicCandidate 1632 Object getAndBitwiseXorRelease(Object... args); 1633 1634 /** 1635 * Returns a VarHandle, with access to the same variable(s) as this VarHandle, but whose 1636 * invocation behavior of access mode methods is adjusted to 1637 * <a href="#invoke-exact-behavior"><em>invoke-exact behavior</em></a>. 1638 * <p> 1639 * If this VarHandle already has invoke-exact behavior this VarHandle is returned. 1640 * <p> 1641 * Invoking {@link #hasInvokeExactBehavior()} on the returned var handle 1642 * is guaranteed to return {@code true}. 1643 * 1644 * @apiNote 1645 * Invoke-exact behavior guarantees that upon invocation of an access mode method 1646 * the types and arity of the arguments must match the {@link #accessModeType(AccessMode) access mode type}, 1647 * otherwise a {@link WrongMethodTypeException} is thrown. 1648 * 1649 * @see #withInvokeBehavior() 1650 * @see #hasInvokeExactBehavior() 1651 * @return a VarHandle with invoke-exact behavior 1652 * @since 16 1653 */ 1654 public abstract VarHandle withInvokeExactBehavior(); 1655 1656 /** 1657 * Returns a VarHandle, with access to the same variable(s) as this VarHandle, but whose 1658 * invocation behavior of access mode methods is adjusted to 1659 * <a href="#invoke-behavior"><em>invoke behavior</em></a>. 1660 * <p> 1661 * If this VarHandle already has invoke behavior this VarHandle is returned. 1662 * <p> 1663 * Invoking {@link #hasInvokeExactBehavior()} on the returned var handle 1664 * is guaranteed to return {@code false}. 1665 * 1666 * @see #withInvokeExactBehavior() 1667 * @see #hasInvokeExactBehavior() 1668 * @return a VarHandle with invoke behavior 1669 * @since 16 1670 */ 1671 public abstract VarHandle withInvokeBehavior(); 1672 1673 enum AccessType { 1674 GET(Object.class), 1675 SET(void.class), 1676 COMPARE_AND_SET(boolean.class), 1677 COMPARE_AND_EXCHANGE(Object.class), 1678 GET_AND_UPDATE(Object.class); 1679 1680 static final int COUNT = GET_AND_UPDATE.ordinal() + 1; 1681 static { 1682 assert (COUNT == values().length); 1683 } 1684 final Class<?> returnType; 1685 final boolean isMonomorphicInReturnType; 1686 1687 AccessType(Class<?> returnType) { 1688 this.returnType = returnType; 1689 isMonomorphicInReturnType = returnType != Object.class; 1690 } 1691 1692 MethodType accessModeType(Class<?> receiver, Class<?> value, 1693 Class<?>... intermediate) { 1694 Class<?>[] ps; 1695 int i; 1696 switch (this) { 1697 case GET: 1698 ps = allocateParameters(0, receiver, intermediate); 1699 fillParameters(ps, receiver, intermediate); 1700 return MethodType.methodType(value, ps); 1701 case SET: 1702 ps = allocateParameters(1, receiver, intermediate); 1703 i = fillParameters(ps, receiver, intermediate); 1704 ps[i] = value; 1705 return MethodType.methodType(void.class, ps); 1706 case COMPARE_AND_SET: 1707 ps = allocateParameters(2, receiver, intermediate); 1708 i = fillParameters(ps, receiver, intermediate); 1709 ps[i++] = value; 1710 ps[i] = value; 1711 return MethodType.methodType(boolean.class, ps); 1712 case COMPARE_AND_EXCHANGE: 1713 ps = allocateParameters(2, receiver, intermediate); 1714 i = fillParameters(ps, receiver, intermediate); 1715 ps[i++] = value; 1716 ps[i] = value; 1717 return MethodType.methodType(value, ps); 1718 case GET_AND_UPDATE: 1719 ps = allocateParameters(1, receiver, intermediate); 1720 i = fillParameters(ps, receiver, intermediate); 1721 ps[i] = value; 1722 return MethodType.methodType(value, ps); 1723 default: 1724 throw new InternalError("Unknown AccessType"); 1725 } 1726 } 1727 1728 private static Class<?>[] allocateParameters(int values, 1729 Class<?> receiver, Class<?>... intermediate) { 1730 int size = ((receiver != null) ? 1 : 0) + intermediate.length + values; 1731 return new Class<?>[size]; 1732 } 1733 1734 private static int fillParameters(Class<?>[] ps, 1735 Class<?> receiver, Class<?>... intermediate) { 1736 int i = 0; 1737 if (receiver != null) 1738 ps[i++] = receiver; 1739 for (int j = 0; j < intermediate.length; j++) 1740 ps[i++] = intermediate[j]; 1741 return i; 1742 } 1743 } 1744 1745 /** 1746 * The set of access modes that specify how a variable, referenced by a 1747 * VarHandle, is accessed. 1748 */ 1749 public enum AccessMode { 1750 /** 1751 * The access mode whose access is specified by the corresponding 1752 * method 1753 * {@link VarHandle#get VarHandle.get} 1754 */ 1755 GET("get", AccessType.GET), 1756 /** 1757 * The access mode whose access is specified by the corresponding 1758 * method 1759 * {@link VarHandle#set VarHandle.set} 1760 */ 1761 SET("set", AccessType.SET), 1762 /** 1763 * The access mode whose access is specified by the corresponding 1764 * method 1765 * {@link VarHandle#getVolatile VarHandle.getVolatile} 1766 */ 1767 GET_VOLATILE("getVolatile", AccessType.GET), 1768 /** 1769 * The access mode whose access is specified by the corresponding 1770 * method 1771 * {@link VarHandle#setVolatile VarHandle.setVolatile} 1772 */ 1773 SET_VOLATILE("setVolatile", AccessType.SET), 1774 /** 1775 * The access mode whose access is specified by the corresponding 1776 * method 1777 * {@link VarHandle#getAcquire VarHandle.getAcquire} 1778 */ 1779 GET_ACQUIRE("getAcquire", AccessType.GET), 1780 /** 1781 * The access mode whose access is specified by the corresponding 1782 * method 1783 * {@link VarHandle#setRelease VarHandle.setRelease} 1784 */ 1785 SET_RELEASE("setRelease", AccessType.SET), 1786 /** 1787 * The access mode whose access is specified by the corresponding 1788 * method 1789 * {@link VarHandle#getOpaque VarHandle.getOpaque} 1790 */ 1791 GET_OPAQUE("getOpaque", AccessType.GET), 1792 /** 1793 * The access mode whose access is specified by the corresponding 1794 * method 1795 * {@link VarHandle#setOpaque VarHandle.setOpaque} 1796 */ 1797 SET_OPAQUE("setOpaque", AccessType.SET), 1798 /** 1799 * The access mode whose access is specified by the corresponding 1800 * method 1801 * {@link VarHandle#compareAndSet VarHandle.compareAndSet} 1802 */ 1803 COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SET), 1804 /** 1805 * The access mode whose access is specified by the corresponding 1806 * method 1807 * {@link VarHandle#compareAndExchange VarHandle.compareAndExchange} 1808 */ 1809 COMPARE_AND_EXCHANGE("compareAndExchange", AccessType.COMPARE_AND_EXCHANGE), 1810 /** 1811 * The access mode whose access is specified by the corresponding 1812 * method 1813 * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire} 1814 */ 1815 COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE), 1816 /** 1817 * The access mode whose access is specified by the corresponding 1818 * method 1819 * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease} 1820 */ 1821 COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE), 1822 /** 1823 * The access mode whose access is specified by the corresponding 1824 * method 1825 * {@link VarHandle#weakCompareAndSetPlain VarHandle.weakCompareAndSetPlain} 1826 */ 1827 WEAK_COMPARE_AND_SET_PLAIN("weakCompareAndSetPlain", AccessType.COMPARE_AND_SET), 1828 /** 1829 * The access mode whose access is specified by the corresponding 1830 * method 1831 * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet} 1832 */ 1833 WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SET), 1834 /** 1835 * The access mode whose access is specified by the corresponding 1836 * method 1837 * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire} 1838 */ 1839 WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SET), 1840 /** 1841 * The access mode whose access is specified by the corresponding 1842 * method 1843 * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease} 1844 */ 1845 WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SET), 1846 /** 1847 * The access mode whose access is specified by the corresponding 1848 * method 1849 * {@link VarHandle#getAndSet VarHandle.getAndSet} 1850 */ 1851 GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE), 1852 /** 1853 * The access mode whose access is specified by the corresponding 1854 * method 1855 * {@link VarHandle#getAndSetAcquire VarHandle.getAndSetAcquire} 1856 */ 1857 GET_AND_SET_ACQUIRE("getAndSetAcquire", AccessType.GET_AND_UPDATE), 1858 /** 1859 * The access mode whose access is specified by the corresponding 1860 * method 1861 * {@link VarHandle#getAndSetRelease VarHandle.getAndSetRelease} 1862 */ 1863 GET_AND_SET_RELEASE("getAndSetRelease", AccessType.GET_AND_UPDATE), 1864 /** 1865 * The access mode whose access is specified by the corresponding 1866 * method 1867 * {@link VarHandle#getAndAdd VarHandle.getAndAdd} 1868 */ 1869 GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE), 1870 /** 1871 * The access mode whose access is specified by the corresponding 1872 * method 1873 * {@link VarHandle#getAndAddAcquire VarHandle.getAndAddAcquire} 1874 */ 1875 GET_AND_ADD_ACQUIRE("getAndAddAcquire", AccessType.GET_AND_UPDATE), 1876 /** 1877 * The access mode whose access is specified by the corresponding 1878 * method 1879 * {@link VarHandle#getAndAddRelease VarHandle.getAndAddRelease} 1880 */ 1881 GET_AND_ADD_RELEASE("getAndAddRelease", AccessType.GET_AND_UPDATE), 1882 /** 1883 * The access mode whose access is specified by the corresponding 1884 * method 1885 * {@link VarHandle#getAndBitwiseOr VarHandle.getAndBitwiseOr} 1886 */ 1887 GET_AND_BITWISE_OR("getAndBitwiseOr", AccessType.GET_AND_UPDATE), 1888 /** 1889 * The access mode whose access is specified by the corresponding 1890 * method 1891 * {@link VarHandle#getAndBitwiseOrRelease VarHandle.getAndBitwiseOrRelease} 1892 */ 1893 GET_AND_BITWISE_OR_RELEASE("getAndBitwiseOrRelease", AccessType.GET_AND_UPDATE), 1894 /** 1895 * The access mode whose access is specified by the corresponding 1896 * method 1897 * {@link VarHandle#getAndBitwiseOrAcquire VarHandle.getAndBitwiseOrAcquire} 1898 */ 1899 GET_AND_BITWISE_OR_ACQUIRE("getAndBitwiseOrAcquire", AccessType.GET_AND_UPDATE), 1900 /** 1901 * The access mode whose access is specified by the corresponding 1902 * method 1903 * {@link VarHandle#getAndBitwiseAnd VarHandle.getAndBitwiseAnd} 1904 */ 1905 GET_AND_BITWISE_AND("getAndBitwiseAnd", AccessType.GET_AND_UPDATE), 1906 /** 1907 * The access mode whose access is specified by the corresponding 1908 * method 1909 * {@link VarHandle#getAndBitwiseAndRelease VarHandle.getAndBitwiseAndRelease} 1910 */ 1911 GET_AND_BITWISE_AND_RELEASE("getAndBitwiseAndRelease", AccessType.GET_AND_UPDATE), 1912 /** 1913 * The access mode whose access is specified by the corresponding 1914 * method 1915 * {@link VarHandle#getAndBitwiseAndAcquire VarHandle.getAndBitwiseAndAcquire} 1916 */ 1917 GET_AND_BITWISE_AND_ACQUIRE("getAndBitwiseAndAcquire", AccessType.GET_AND_UPDATE), 1918 /** 1919 * The access mode whose access is specified by the corresponding 1920 * method 1921 * {@link VarHandle#getAndBitwiseXor VarHandle.getAndBitwiseXor} 1922 */ 1923 GET_AND_BITWISE_XOR("getAndBitwiseXor", AccessType.GET_AND_UPDATE), 1924 /** 1925 * The access mode whose access is specified by the corresponding 1926 * method 1927 * {@link VarHandle#getAndBitwiseXorRelease VarHandle.getAndBitwiseXorRelease} 1928 */ 1929 GET_AND_BITWISE_XOR_RELEASE("getAndBitwiseXorRelease", AccessType.GET_AND_UPDATE), 1930 /** 1931 * The access mode whose access is specified by the corresponding 1932 * method 1933 * {@link VarHandle#getAndBitwiseXorAcquire VarHandle.getAndBitwiseXorAcquire} 1934 */ 1935 GET_AND_BITWISE_XOR_ACQUIRE("getAndBitwiseXorAcquire", AccessType.GET_AND_UPDATE), 1936 ; 1937 1938 static final int COUNT = GET_AND_BITWISE_XOR_ACQUIRE.ordinal() + 1; 1939 static { 1940 assert (COUNT == values().length); 1941 } 1942 final String methodName; 1943 final AccessType at; 1944 1945 AccessMode(final String methodName, AccessType at) { 1946 this.methodName = methodName; 1947 this.at = at; 1948 } 1949 1950 /** 1951 * Returns the {@code VarHandle} signature-polymorphic method name 1952 * associated with this {@code AccessMode} value. 1953 * 1954 * @return the signature-polymorphic method name 1955 * @see #valueFromMethodName 1956 */ 1957 public String methodName() { 1958 return methodName; 1959 } 1960 1961 /** 1962 * Returns the {@code AccessMode} value associated with the specified 1963 * {@code VarHandle} signature-polymorphic method name. 1964 * 1965 * @param methodName the signature-polymorphic method name 1966 * @return the {@code AccessMode} value 1967 * @throws IllegalArgumentException if there is no {@code AccessMode} 1968 * value associated with method name (indicating the method 1969 * name does not correspond to a {@code VarHandle} 1970 * signature-polymorphic method name). 1971 * @see #methodName() 1972 */ 1973 public static AccessMode valueFromMethodName(String methodName) { 1974 return switch (methodName) { 1975 case "get" -> GET; 1976 case "set" -> SET; 1977 case "getVolatile" -> GET_VOLATILE; 1978 case "setVolatile" -> SET_VOLATILE; 1979 case "getAcquire" -> GET_ACQUIRE; 1980 case "setRelease" -> SET_RELEASE; 1981 case "getOpaque" -> GET_OPAQUE; 1982 case "setOpaque" -> SET_OPAQUE; 1983 case "compareAndSet" -> COMPARE_AND_SET; 1984 case "compareAndExchange" -> COMPARE_AND_EXCHANGE; 1985 case "compareAndExchangeAcquire" -> COMPARE_AND_EXCHANGE_ACQUIRE; 1986 case "compareAndExchangeRelease" -> COMPARE_AND_EXCHANGE_RELEASE; 1987 case "weakCompareAndSet" -> WEAK_COMPARE_AND_SET; 1988 case "weakCompareAndSetPlain" -> WEAK_COMPARE_AND_SET_PLAIN; 1989 case "weakCompareAndSetAcquire" -> WEAK_COMPARE_AND_SET_ACQUIRE; 1990 case "weakCompareAndSetRelease" -> WEAK_COMPARE_AND_SET_RELEASE; 1991 case "getAndSet" -> GET_AND_SET; 1992 case "getAndSetAcquire" -> GET_AND_SET_ACQUIRE; 1993 case "getAndSetRelease" -> GET_AND_SET_RELEASE; 1994 case "getAndAdd" -> GET_AND_ADD; 1995 case "getAndAddAcquire" -> GET_AND_ADD_ACQUIRE; 1996 case "getAndAddRelease" -> GET_AND_ADD_RELEASE; 1997 case "getAndBitwiseOr" -> GET_AND_BITWISE_OR; 1998 case "getAndBitwiseOrRelease" -> GET_AND_BITWISE_OR_RELEASE; 1999 case "getAndBitwiseOrAcquire" -> GET_AND_BITWISE_OR_ACQUIRE; 2000 case "getAndBitwiseAnd" -> GET_AND_BITWISE_AND; 2001 case "getAndBitwiseAndRelease" -> GET_AND_BITWISE_AND_RELEASE; 2002 case "getAndBitwiseAndAcquire" -> GET_AND_BITWISE_AND_ACQUIRE; 2003 case "getAndBitwiseXor" -> GET_AND_BITWISE_XOR; 2004 case "getAndBitwiseXorRelease" -> GET_AND_BITWISE_XOR_RELEASE; 2005 case "getAndBitwiseXorAcquire" -> GET_AND_BITWISE_XOR_ACQUIRE; 2006 default -> throw new IllegalArgumentException("No AccessMode value for method name " + methodName); 2007 }; 2008 } 2009 2010 private static final @Stable AccessMode[] VALUES = values(); 2011 static AccessMode valueFromOrdinal(int mode) { 2012 return VALUES[mode]; 2013 } 2014 } 2015 2016 static final class AccessDescriptor { 2017 final MethodType symbolicMethodTypeExact; 2018 final MethodType symbolicMethodTypeErased; 2019 final MethodType symbolicMethodTypeInvoker; 2020 final Class<?> returnType; 2021 final int type; 2022 final int mode; 2023 2024 public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) { 2025 this.symbolicMethodTypeExact = symbolicMethodType; 2026 this.symbolicMethodTypeErased = symbolicMethodType.erase(); 2027 this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class); 2028 this.returnType = symbolicMethodType.returnType(); 2029 this.type = type; 2030 this.mode = mode; 2031 } 2032 } 2033 2034 /** 2035 * Returns a compact textual description of this {@linkplain VarHandle}, 2036 * including the type of variable described, and a description of its coordinates. 2037 * 2038 * @return A compact textual description of this {@linkplain VarHandle} 2039 */ 2040 @Override 2041 public final String toString() { 2042 return String.format("VarHandle[varType=%s, coord=%s]", 2043 varType().getName(), 2044 coordinateTypes()); 2045 } 2046 2047 /** 2048 * Returns the variable type of variables referenced by this VarHandle. 2049 * 2050 * @return the variable type of variables referenced by this VarHandle 2051 */ 2052 public Class<?> varType() { 2053 MethodType typeSet = accessModeType(AccessMode.SET); 2054 return typeSet.parameterType(typeSet.parameterCount() - 1); 2055 } 2056 2057 /** 2058 * Returns the coordinate types for this VarHandle. 2059 * 2060 * @return the coordinate types for this VarHandle. The returned 2061 * list is unmodifiable 2062 */ 2063 public List<Class<?>> coordinateTypes() { 2064 MethodType typeGet = accessModeType(AccessMode.GET); 2065 return typeGet.parameterList(); 2066 } 2067 2068 /** 2069 * Obtains the access mode type for this VarHandle and a given access mode. 2070 * 2071 * <p>The access mode type's parameter types will consist of a prefix that 2072 * is the coordinate types of this VarHandle followed by further 2073 * types as defined by the access mode method. 2074 * The access mode type's return type is defined by the return type of the 2075 * access mode method. 2076 * 2077 * @param accessMode the access mode, corresponding to the 2078 * signature-polymorphic method of the same name 2079 * @return the access mode type for the given access mode 2080 */ 2081 public final MethodType accessModeType(AccessMode accessMode) { 2082 return accessModeType(accessMode.at.ordinal()); 2083 } 2084 2085 /** 2086 * Validates that the given access descriptors method type matches up with 2087 * the access mode of this VarHandle, then returns if this is direct. 2088 * These operations were grouped together to slightly 2089 * improve efficiency during startup/warmup. 2090 * 2091 * A direct VarHandle's VarForm has implementation MemberNames that can 2092 * be linked directly. If a VarHandle is indirect, it must override 2093 * {@link #isAccessModeSupported} and {@link #getMethodHandleUncached} 2094 * which access MemberNames. 2095 * 2096 * @return true if this is a direct VarHandle, false if it's an indirect 2097 * VarHandle. 2098 * @throws WrongMethodTypeException if there's an access type mismatch 2099 * @see #asDirect() 2100 */ 2101 @ForceInline 2102 boolean checkAccessModeThenIsDirect(VarHandle.AccessDescriptor ad) { 2103 if (exact && accessModeType(ad.type) != ad.symbolicMethodTypeExact) { 2104 throwWrongMethodTypeException(ad); 2105 } 2106 // return true unless overridden in an IndirectVarHandle 2107 return true; 2108 } 2109 2110 @DontInline 2111 private final void throwWrongMethodTypeException(VarHandle.AccessDescriptor ad) { 2112 throw new WrongMethodTypeException("handle's method type " + accessModeType(ad.type) 2113 + " but found " + ad.symbolicMethodTypeExact); 2114 } 2115 2116 @ForceInline 2117 final MethodType accessModeType(int accessTypeOrdinal) { 2118 MethodType[] mtTable = methodTypeTable; 2119 if (mtTable == null) { 2120 mtTable = methodTypeTable = new MethodType[VarHandle.AccessType.COUNT]; 2121 } 2122 MethodType mt = mtTable[accessTypeOrdinal]; 2123 if (mt == null) { 2124 mt = mtTable[accessTypeOrdinal] = 2125 accessModeTypeUncached(accessTypeOrdinal); 2126 } 2127 return mt; 2128 } 2129 2130 final MethodType accessModeTypeUncached(int accessTypeOrdinal) { 2131 return accessModeTypeUncached(AccessType.values()[accessTypeOrdinal]); 2132 } 2133 2134 abstract MethodType accessModeTypeUncached(AccessType accessMode); 2135 2136 /** 2137 * Returns {@code true} if the given access mode is supported, otherwise 2138 * {@code false}. 2139 * 2140 * <p>The return of a {@code false} value for a given access mode indicates 2141 * that an {@code UnsupportedOperationException} is thrown on invocation 2142 * of the corresponding access mode method. 2143 * 2144 * @param accessMode the access mode, corresponding to the 2145 * signature-polymorphic method of the same name 2146 * @return {@code true} if the given access mode is supported, otherwise 2147 * {@code false}. 2148 */ 2149 public boolean isAccessModeSupported(AccessMode accessMode) { 2150 return vform.getMemberNameOrNull(accessMode.ordinal()) != null; 2151 } 2152 2153 /** 2154 * Obtains a method handle bound to this VarHandle and the given access 2155 * mode. 2156 * 2157 * @apiNote This method, for a VarHandle {@code vh} and access mode 2158 * {@code {access-mode}}, returns a method handle that is equivalent to 2159 * method handle {@code bmh} in the following code (though it may be more 2160 * efficient): 2161 * <pre>{@code 2162 * MethodHandle mh = MethodHandles.varHandleExactInvoker( 2163 * vh.accessModeType(VarHandle.AccessMode.{access-mode})); 2164 * 2165 * MethodHandle bmh = mh.bindTo(vh); 2166 * }</pre> 2167 * 2168 * @param accessMode the access mode, corresponding to the 2169 * signature-polymorphic method of the same name 2170 * @return a method handle bound to this VarHandle and the given access mode 2171 */ 2172 public MethodHandle toMethodHandle(AccessMode accessMode) { 2173 if (isAccessModeSupported(accessMode)) { 2174 MethodHandle mh = getMethodHandle(accessMode.ordinal()); 2175 return mh.bindTo(asDirect()); 2176 } 2177 else { 2178 // Ensure an UnsupportedOperationException is thrown 2179 return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)). 2180 bindTo(this); 2181 } 2182 } 2183 2184 /** 2185 * Return a nominal descriptor for this instance, if one can be 2186 * constructed, or an empty {@link Optional} if one cannot be. 2187 * 2188 * @return An {@link Optional} containing the resulting nominal descriptor, 2189 * or an empty {@link Optional} if one cannot be constructed. 2190 * @since 12 2191 */ 2192 @Override 2193 public Optional<VarHandleDesc> describeConstable() { 2194 // partial function for field and array only 2195 return Optional.empty(); 2196 } 2197 2198 @Stable 2199 MethodType[] methodTypeTable; 2200 2201 @Stable 2202 MethodHandle[] methodHandleTable; 2203 2204 @ForceInline 2205 final MethodHandle getMethodHandle(int mode) { 2206 MethodHandle[] mhTable = methodHandleTable; 2207 if (mhTable == null) { 2208 mhTable = methodHandleTable = new MethodHandle[AccessMode.COUNT]; 2209 } 2210 MethodHandle mh = mhTable[mode]; 2211 if (mh == null) { 2212 mh = mhTable[mode] = getMethodHandleUncached(mode); 2213 } 2214 return mh; 2215 } 2216 2217 /** 2218 * Computes a method handle that can be passed the {@linkplain #asDirect() direct} 2219 * var handle of this var handle with the given access mode. Pre/postprocessing 2220 * such as argument or return value filtering should be done by the returned 2221 * method handle. 2222 * 2223 * @throws UnsupportedOperationException if the access mode is not supported 2224 */ 2225 MethodHandle getMethodHandleUncached(int mode) { 2226 MethodType mt = accessModeType(AccessMode.valueFromOrdinal(mode)). 2227 insertParameterTypes(0, VarHandle.class); 2228 MemberName mn = vform.getMemberName(mode); 2229 DirectMethodHandle dmh = DirectMethodHandle.make(mn); 2230 // Such a method handle must not be publicly exposed directly 2231 // otherwise it can be cracked, it must be transformed or rebound 2232 // before exposure 2233 MethodHandle mh = dmh.copyWith(mt, dmh.form); 2234 assert mh.type().erase() == mn.getMethodType().erase(); 2235 return mh; 2236 } 2237 2238 2239 /*non-public*/ 2240 final void updateVarForm(VarForm newVForm) { 2241 if (vform == newVForm) return; 2242 UNSAFE.putReference(this, VFORM_OFFSET, newVForm); 2243 UNSAFE.fullFence(); 2244 } 2245 2246 private static final long VFORM_OFFSET; 2247 2248 static { 2249 VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "vform"); 2250 2251 // The VarHandleGuards must be initialized to ensure correct 2252 // compilation of the guard methods 2253 UNSAFE.ensureClassInitialized(VarHandleGuards.class); 2254 } 2255 2256 2257 // Fence methods 2258 2259 /** 2260 * Ensures that loads and stores before the fence will not be reordered 2261 * with 2262 * loads and stores after the fence. 2263 * 2264 * @apiNote Ignoring the many semantic differences from C and C++, this 2265 * method has memory ordering effects compatible with 2266 * {@code atomic_thread_fence(memory_order_seq_cst)} 2267 */ 2268 @ForceInline 2269 public static void fullFence() { 2270 UNSAFE.fullFence(); 2271 } 2272 2273 /** 2274 * Ensures that loads before the fence will not be reordered with loads and 2275 * stores after the fence. 2276 * 2277 * @apiNote Ignoring the many semantic differences from C and C++, this 2278 * method has memory ordering effects compatible with 2279 * {@code atomic_thread_fence(memory_order_acquire)} 2280 */ 2281 @ForceInline 2282 public static void acquireFence() { 2283 UNSAFE.loadFence(); 2284 } 2285 2286 /** 2287 * Ensures that loads and stores before the fence will not be 2288 * reordered with stores after the fence. 2289 * 2290 * @apiNote Ignoring the many semantic differences from C and C++, this 2291 * method has memory ordering effects compatible with 2292 * {@code atomic_thread_fence(memory_order_release)} 2293 */ 2294 @ForceInline 2295 public static void releaseFence() { 2296 UNSAFE.storeFence(); 2297 } 2298 2299 /** 2300 * Ensures that loads before the fence will not be reordered with 2301 * loads after the fence. 2302 */ 2303 @ForceInline 2304 public static void loadLoadFence() { 2305 UNSAFE.loadLoadFence(); 2306 } 2307 2308 /** 2309 * Ensures that stores before the fence will not be reordered with 2310 * stores after the fence. 2311 */ 2312 @ForceInline 2313 public static void storeStoreFence() { 2314 UNSAFE.storeStoreFence(); 2315 } 2316 2317 /** 2318 * A <a href="{@docRoot}/java.base/java/lang/constant/package-summary.html#nominal">nominal descriptor</a> for a 2319 * {@link VarHandle} constant. 2320 * 2321 * @since 12 2322 */ 2323 public static final class VarHandleDesc extends DynamicConstantDesc<VarHandle> { 2324 2325 /** 2326 * Kinds of variable handle descs 2327 */ 2328 private enum Kind { 2329 FIELD(ConstantDescs.BSM_VARHANDLE_FIELD), 2330 STATIC_FIELD(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD), 2331 ARRAY(ConstantDescs.BSM_VARHANDLE_ARRAY); 2332 2333 final DirectMethodHandleDesc bootstrapMethod; 2334 2335 Kind(DirectMethodHandleDesc bootstrapMethod) { 2336 this.bootstrapMethod = bootstrapMethod; 2337 } 2338 2339 ConstantDesc[] toBSMArgs(ClassDesc declaringClass, ClassDesc varType) { 2340 return switch (this) { 2341 case FIELD, STATIC_FIELD -> new ConstantDesc[]{declaringClass, varType}; 2342 case ARRAY -> new ConstantDesc[]{declaringClass}; 2343 default -> throw new InternalError("Cannot reach here"); 2344 }; 2345 } 2346 } 2347 2348 private final Kind kind; 2349 private final ClassDesc declaringClass; 2350 private final ClassDesc varType; 2351 2352 /** 2353 * Construct a {@linkplain VarHandleDesc} given a kind, name, and declaring 2354 * class. 2355 * 2356 * @param kind the kind of the var handle 2357 * @param name the unqualified name of the field, for field var handles; otherwise ignored 2358 * @param declaringClass a {@link ClassDesc} describing the declaring class, 2359 * for field var handles 2360 * @param varType a {@link ClassDesc} describing the type of the variable 2361 * @throws NullPointerException if any required argument is null 2362 * @jvms 4.2.2 Unqualified Names 2363 */ 2364 private VarHandleDesc(Kind kind, String name, ClassDesc declaringClass, ClassDesc varType) { 2365 super(kind.bootstrapMethod, name, 2366 ConstantDescs.CD_VarHandle, 2367 kind.toBSMArgs(declaringClass, varType)); 2368 this.kind = kind; 2369 this.declaringClass = declaringClass; 2370 this.varType = varType; 2371 } 2372 2373 /** 2374 * Returns a {@linkplain VarHandleDesc} corresponding to a {@link VarHandle} 2375 * for an instance field. 2376 * 2377 * @param declaringClass a {@link ClassDesc} describing the declaring class, 2378 * for field var handles 2379 * @param name the unqualified name of the field 2380 * @param fieldType a {@link ClassDesc} describing the type of the field 2381 * @return the {@linkplain VarHandleDesc} 2382 * @throws NullPointerException if any of the arguments are null 2383 * @jvms 4.2.2 Unqualified Names 2384 */ 2385 public static VarHandleDesc ofField(ClassDesc declaringClass, String name, ClassDesc fieldType) { 2386 Objects.requireNonNull(declaringClass); 2387 Objects.requireNonNull(name); 2388 Objects.requireNonNull(fieldType); 2389 return new VarHandleDesc(Kind.FIELD, name, declaringClass, fieldType); 2390 } 2391 2392 /** 2393 * Returns a {@linkplain VarHandleDesc} corresponding to a {@link VarHandle} 2394 * for a static field. 2395 * 2396 * @param declaringClass a {@link ClassDesc} describing the declaring class, 2397 * for field var handles 2398 * @param name the unqualified name of the field 2399 * @param fieldType a {@link ClassDesc} describing the type of the field 2400 * @return the {@linkplain VarHandleDesc} 2401 * @throws NullPointerException if any of the arguments are null 2402 * @jvms 4.2.2 Unqualified Names 2403 */ 2404 public static VarHandleDesc ofStaticField(ClassDesc declaringClass, String name, ClassDesc fieldType) { 2405 Objects.requireNonNull(declaringClass); 2406 Objects.requireNonNull(name); 2407 Objects.requireNonNull(fieldType); 2408 return new VarHandleDesc(Kind.STATIC_FIELD, name, declaringClass, fieldType); 2409 } 2410 2411 /** 2412 * Returns a {@linkplain VarHandleDesc} corresponding to a {@link VarHandle} 2413 * for an array type. 2414 * 2415 * @param arrayClass a {@link ClassDesc} describing the type of the array 2416 * @return the {@linkplain VarHandleDesc} 2417 * @throws NullPointerException if any of the arguments are null 2418 */ 2419 public static VarHandleDesc ofArray(ClassDesc arrayClass) { 2420 Objects.requireNonNull(arrayClass); 2421 if (!arrayClass.isArray()) 2422 throw new IllegalArgumentException("Array class argument not an array: " + arrayClass); 2423 return new VarHandleDesc(Kind.ARRAY, ConstantDescs.DEFAULT_NAME, arrayClass, arrayClass.componentType()); 2424 } 2425 2426 /** 2427 * Returns a {@link ClassDesc} describing the type of the variable described 2428 * by this descriptor. 2429 * 2430 * @return the variable type 2431 */ 2432 public ClassDesc varType() { 2433 return varType; 2434 } 2435 2436 @Override 2437 public VarHandle resolveConstantDesc(MethodHandles.Lookup lookup) 2438 throws ReflectiveOperationException { 2439 return switch (kind) { 2440 case FIELD -> lookup.findVarHandle(declaringClass.resolveConstantDesc(lookup), 2441 constantName(), 2442 varType.resolveConstantDesc(lookup)); 2443 case STATIC_FIELD -> lookup.findStaticVarHandle(declaringClass.resolveConstantDesc(lookup), 2444 constantName(), 2445 varType.resolveConstantDesc(lookup)); 2446 case ARRAY -> MethodHandles.arrayElementVarHandle(declaringClass.resolveConstantDesc(lookup)); 2447 default -> throw new InternalError("Cannot reach here"); 2448 }; 2449 } 2450 2451 /** 2452 * Returns a compact textual description of this constant description. 2453 * For a field {@linkplain VarHandle}, includes the owner, name, and type 2454 * of the field, and whether it is static; for an array {@linkplain VarHandle}, 2455 * the name of the component type. 2456 * 2457 * @return A compact textual description of this descriptor 2458 */ 2459 @Override 2460 public String toString() { 2461 return switch (kind) { 2462 case FIELD, STATIC_FIELD -> String.format("VarHandleDesc[%s%s.%s:%s]", 2463 (kind == Kind.STATIC_FIELD) ? "static " : "", 2464 declaringClass.displayName(), constantName(), varType.displayName()); 2465 case ARRAY -> String.format("VarHandleDesc[%s[]]", declaringClass.displayName()); 2466 default -> throw new InternalError("Cannot reach here"); 2467 }; 2468 } 2469 } 2470 2471 }