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