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