8291065: Creating a VarHandle for a static field triggers class initialization

Reviewed-by: mchung, psandoz
This commit is contained in:
Chen Liang 2023-07-18 00:58:25 +00:00 committed by Mandy Chung
parent a53345ad03
commit 201e3bcf52
10 changed files with 744 additions and 160 deletions

View file

@ -68,6 +68,7 @@ import java.util.function.BiFunction;
}
@Override
@ForceInline
VarHandle asDirect() {
return directTarget;
}
@ -75,8 +76,8 @@ import java.util.function.BiFunction;
@Override
public VarHandle withInvokeExactBehavior() {
return hasInvokeExactBehavior()
? this
: new IndirectVarHandle(target, value, coordinates, handleFactory, vform, true);
? this
: new IndirectVarHandle(target, value, coordinates, handleFactory, vform, true);
}
@Override
@ -86,6 +87,7 @@ import java.util.function.BiFunction;
: new IndirectVarHandle(target, value, coordinates, handleFactory, vform, false);
}
@Override
@ForceInline
boolean checkAccessModeThenIsDirect(VarHandle.AccessDescriptor ad) {
super.checkAccessModeThenIsDirect(ad);
@ -103,9 +105,4 @@ import java.util.function.BiFunction;
MethodHandle targetHandle = target.getMethodHandle(mode); // might throw UOE of access mode is not supported, which is ok
return handleFactory.apply(AccessMode.values()[mode], targetHandle);
}
@Override
public MethodHandle toMethodHandle(AccessMode accessMode) {
return getMethodHandle(accessMode.ordinal()).bindTo(directTarget);
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package java.lang.invoke;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;
import java.util.Optional;
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
import static java.lang.invoke.MethodHandleStatics.uncaughtException;
/**
* A lazy initializing var handle. It lazily initializes the referenced class before
* any invocation of the target var handle to prevent reading uninitialized static
* field values.
*/
final class LazyInitializingVarHandle extends VarHandle {
// Implementation notes:
// We put a barrier on both target() (for VH form impl direct invocation)
// and on getMethodHandle() (for indirect VH invocation, toMethodHandle)
private final VarHandle target;
private final Class<?> refc;
private @Stable boolean initialized;
LazyInitializingVarHandle(VarHandle target, Class<?> refc) {
super(target.vform, target.exact);
this.target = target;
this.refc = refc;
}
@Override
MethodType accessModeTypeUncached(AccessType at) {
return target.accessModeType(at.ordinal());
}
@Override
@ForceInline
VarHandle asDirect() {
return target;
}
@Override
@ForceInline
VarHandle target() {
ensureInitialized();
return target;
}
@Override
public VarHandle withInvokeExactBehavior() {
if (!initialized && hasInvokeExactBehavior())
return this;
var exactTarget = target.withInvokeExactBehavior();
return initialized ? exactTarget : new LazyInitializingVarHandle(exactTarget, refc);
}
@Override
public VarHandle withInvokeBehavior() {
if (!initialized && !hasInvokeExactBehavior())
return this;
var nonExactTarget = target.withInvokeBehavior();
return initialized ? nonExactTarget : new LazyInitializingVarHandle(nonExactTarget, refc);
}
@Override
public Optional<VarHandleDesc> describeConstable() {
return target.describeConstable();
}
@Override
public MethodHandle getMethodHandleUncached(int accessMode) {
var mh = target.getMethodHandle(accessMode);
if (this.initialized)
return mh;
return MethodHandles.collectArguments(mh, 0, ensureInitializedMh()).bindTo(this);
}
@ForceInline
private void ensureInitialized() {
if (this.initialized)
return;
initialize();
}
private void initialize() {
UNSAFE.ensureClassInitialized(refc);
this.initialized = true;
this.methodHandleTable = target.methodHandleTable;
}
private static @Stable MethodHandle MH_ensureInitialized;
private static MethodHandle ensureInitializedMh() {
var mh = MH_ensureInitialized;
if (mh != null)
return mh;
try {
return MH_ensureInitialized = MethodHandles.lookup().findVirtual(
LazyInitializingVarHandle.class,
"ensureInitialized",
MethodType.methodType(void.class));
} catch (Throwable ex) {
throw uncaughtException(ex);
}
}
}

View file

@ -4201,7 +4201,7 @@ return mh1;
}
refc = lookupClass();
}
return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(),
return VarHandles.makeFieldHandle(getField, refc,
this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
}
/** Check access and get the requested constructor. */

View file

@ -472,7 +472,8 @@ import static java.lang.invoke.MethodHandleStatics.UNSAFE;
* @since 9
*/
public abstract sealed class VarHandle implements Constable
permits IndirectVarHandle, VarHandleSegmentViewBase,
permits IndirectVarHandle, LazyInitializingVarHandle,
VarHandleSegmentViewBase,
VarHandleByteArrayAsChars.ByteArrayViewVarHandle,
VarHandleByteArrayAsDoubles.ByteArrayViewVarHandle,
VarHandleByteArrayAsFloats.ByteArrayViewVarHandle,
@ -518,10 +519,23 @@ public abstract sealed class VarHandle implements Constable
this.exact = exact;
}
RuntimeException unsupported() {
return new UnsupportedOperationException();
/**
* Returns the target VarHandle. Subclasses may override this method to implement
* additional logic for example lazily initializing the declaring class of a static field var handle.
*/
@ForceInline
VarHandle target() {
return asDirect();
}
/**
* Returns the direct target VarHandle. Indirect VarHandle subclasses should implement
* this method.
*
* @see #getMethodHandle(int)
* @see #checkAccessModeThenIsDirect(AccessDescriptor)
*/
@ForceInline
VarHandle asDirect() {
return this;
}
@ -2062,13 +2076,19 @@ public abstract sealed class VarHandle implements Constable
/**
* Validates that the given access descriptors method type matches up with
* the access mode of this VarHandle, then returns if this is a direct
* method handle. These operations were grouped together to slightly
* the access mode of this VarHandle, then returns if this is direct.
* These operations were grouped together to slightly
* improve efficiency during startup/warmup.
*
* A direct VarHandle's VarForm has implementation MemberNames that can
* be linked directly. If a VarHandle is indirect, it must override
* {@link #isAccessModeSupported} and {@link #getMethodHandleUncached}
* which access MemberNames.
*
* @return true if this is a direct VarHandle, false if it's an indirect
* VarHandle.
* @throws WrongMethodTypeException if there's an access type mismatch
* @see #asDirect()
*/
@ForceInline
boolean checkAccessModeThenIsDirect(VarHandle.AccessDescriptor ad) {
@ -2144,7 +2164,7 @@ public abstract sealed class VarHandle implements Constable
public MethodHandle toMethodHandle(AccessMode accessMode) {
if (isAccessModeSupported(accessMode)) {
MethodHandle mh = getMethodHandle(accessMode.ordinal());
return mh.bindTo(this);
return mh.bindTo(asDirect());
}
else {
// Ensure an UnsupportedOperationException is thrown
@ -2186,6 +2206,14 @@ public abstract sealed class VarHandle implements Constable
return mh;
}
/**
* Computes a method handle that can be passed the {@linkplain #asDirect() direct}
* var handle of this var handle with the given access mode. Pre/postprocessing
* such as argument or return value filtering should be done by the returned
* method handle.
*
* @throws UnsupportedOperationException if the access mode is not supported
*/
MethodHandle getMethodHandleUncached(int mode) {
MethodType mt = accessModeType(AccessMode.values()[mode]).
insertParameterTypes(0, VarHandle.class);
@ -2401,13 +2429,13 @@ public abstract sealed class VarHandle implements Constable
public VarHandle resolveConstantDesc(MethodHandles.Lookup lookup)
throws ReflectiveOperationException {
return switch (kind) {
case FIELD -> lookup.findVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
case FIELD -> lookup.findVarHandle(declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case STATIC_FIELD -> lookup.findStaticVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
varType.resolveConstantDesc(lookup));
case STATIC_FIELD -> lookup.findStaticVarHandle(declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case ARRAY -> MethodHandles.arrayElementVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup));
varType.resolveConstantDesc(lookup));
case ARRAY -> MethodHandles.arrayElementVarHandle(declaringClass.resolveConstantDesc(lookup));
default -> throw new InternalError("Cannot reach here");
};
}

View file

@ -53,9 +53,10 @@ final class VarHandles {
}
};
static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
static VarHandle makeFieldHandle(MemberName f, Class<?> refc, boolean isWriteAllowedOnFinalFields) {
if (!f.isStatic()) {
long foffset = MethodHandleNatives.objectFieldOffset(f);
Class<?> type = f.getFieldType();
if (!type.isPrimitive()) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
@ -106,66 +107,65 @@ final class VarHandles {
}
}
else {
// TODO This is not lazy on first invocation
// and might cause some circular initialization issues
// Replace with something similar to direct method handles
// where a barrier is used then elided after use
if (UNSAFE.shouldBeInitialized(refc))
UNSAFE.ensureClassInitialized(refc);
Class<?> decl = f.getDeclaringClass();
Object base = MethodHandleNatives.staticFieldBase(f);
long foffset = MethodHandleNatives.staticFieldOffset(f);
if (!type.isPrimitive()) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type)
: new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type));
}
else if (type == boolean.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == byte.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == short.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == char.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == int.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleInts.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleInts.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == long.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleLongs.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleLongs.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == float.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleFloats.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleFloats.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == double.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleDoubles.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleDoubles.FieldStaticReadWrite(decl, base, foffset));
}
else {
throw new UnsupportedOperationException();
}
var vh = makeStaticFieldVarHandle(decl, f, isWriteAllowedOnFinalFields);
return maybeAdapt(UNSAFE.shouldBeInitialized(decl)
? new LazyInitializingVarHandle(vh, decl)
: vh);
}
}
static VarHandle makeStaticFieldVarHandle(Class<?> decl, MemberName f, boolean isWriteAllowedOnFinalFields) {
Object base = MethodHandleNatives.staticFieldBase(f);
long foffset = MethodHandleNatives.staticFieldOffset(f);
Class<?> type = f.getFieldType();
if (!type.isPrimitive()) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type)
: new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type));
}
else if (type == boolean.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == byte.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == short.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == char.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == int.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleInts.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleInts.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == long.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleLongs.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleLongs.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == float.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleFloats.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleFloats.FieldStaticReadWrite(decl, base, foffset));
}
else if (type == double.class) {
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
? new VarHandleDoubles.FieldStaticReadOnly(decl, base, foffset)
: new VarHandleDoubles.FieldStaticReadWrite(decl, base, foffset));
}
else {
throw new UnsupportedOperationException();
}
}
@ -731,16 +731,7 @@ final class VarHandles {
// Object getAndUpdate(Object value);
// }
//
// static class HandleType {
// final Class<?> receiver;
// final Class<?>[] intermediates;
// final Class<?> value;
//
// HandleType(Class<?> receiver, Class<?> value, Class<?>... intermediates) {
// this.receiver = receiver;
// this.intermediates = intermediates;
// this.value = value;
// }
// record HandleType(Class<?> receiver, Class<?> value, Class<?>... intermediates) {
// }
//
// /**
@ -816,10 +807,8 @@ final class VarHandles {
// List<Class<?>> params = new ArrayList<>();
// if (receiver != null)
// params.add(receiver);
// for (int i = 0; i < intermediates.length; i++) {
// params.add(intermediates[i]);
// }
// for (Parameter p : m.getParameters()) {
// java.util.Collections.addAll(params, intermediates);
// for (var p : m.getParameters()) {
// params.add(value);
// }
// return MethodType.methodType(returnType, params);
@ -828,7 +817,7 @@ final class VarHandles {
// static String generateMethod(MethodType mt) {
// Class<?> returnType = mt.returnType();
//
// LinkedHashMap<String, Class<?>> params = new LinkedHashMap<>();
// var params = new java.util.LinkedHashMap<String, Class<?>>();
// params.put("handle", VarHandle.class);
// for (int i = 0; i < mt.parameterCount(); i++) {
// params.put("arg" + i, mt.parameterType(i));
@ -841,7 +830,7 @@ final class VarHandles {
// String SIGNATURE = getSignature(mt);
// String PARAMS = params.entrySet().stream().
// map(e -> className(e.getValue()) + " " + e.getKey()).
// collect(joining(", "));
// collect(java.util.stream.Collectors.joining(", "));
// String METHOD = GUARD_METHOD_SIG_TEMPLATE.
// replace("<RETURN>", RETURN).
// replace("<NAME>", NAME).
@ -851,12 +840,10 @@ final class VarHandles {
// // Generate method
// params.remove("ad");
//
// List<String> LINK_TO_STATIC_ARGS = params.keySet().stream().
// collect(toList());
// List<String> LINK_TO_STATIC_ARGS = new ArrayList<>(params.keySet());
// LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)");
//
// List<String> LINK_TO_INVOKER_ARGS = params.keySet().stream().
// collect(toList());
// List<String> LINK_TO_INVOKER_ARGS = new ArrayList<>(params.keySet());
// LINK_TO_INVOKER_ARGS.set(0, LINK_TO_INVOKER_ARGS.get(0) + ".asDirect()");
//
// RETURN = returnType == void.class
@ -884,10 +871,8 @@ final class VarHandles {
// replaceAll("<RETURN>", RETURN).
// replace("<RESULT_ERASED>", RESULT_ERASED).
// replace("<RETURN_ERASED>", RETURN_ERASED).
// replaceAll("<LINK_TO_STATIC_ARGS>", LINK_TO_STATIC_ARGS.stream().
// collect(joining(", "))).
// replace("<LINK_TO_INVOKER_ARGS>", LINK_TO_INVOKER_ARGS.stream().
// collect(joining(", ")))
// replaceAll("<LINK_TO_STATIC_ARGS>", String.join(", ", LINK_TO_STATIC_ARGS)).
// replace("<LINK_TO_INVOKER_ARGS>", String.join(", ", LINK_TO_INVOKER_ARGS))
// .indent(4);
// }
//
@ -916,30 +901,7 @@ final class VarHandles {
// }
//
// static char getCharType(Class<?> pt) {
// if (pt == void.class) {
// return 'V';
// }
// else if (!pt.isPrimitive()) {
// return 'L';
// }
// else if (pt == boolean.class) {
// return 'Z';
// }
// else if (pt == int.class) {
// return 'I';
// }
// else if (pt == long.class) {
// return 'J';
// }
// else if (pt == float.class) {
// return 'F';
// }
// else if (pt == double.class) {
// return 'D';
// }
// else {
// throw new IllegalStateException(pt.getName());
// }
// return Wrapper.forBasicType(pt).basicTypeChar();
// }
// }
}

View file

@ -440,28 +440,28 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ get(VarHandle ob) {
FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
return UNSAFE.get$Type$(handle.base,
handle.fieldOffset);
}
@ForceInline
static $type$ getVolatile(VarHandle ob) {
FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
return UNSAFE.get$Type$Volatile(handle.base,
handle.fieldOffset);
}
@ForceInline
static $type$ getOpaque(VarHandle ob) {
FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
return UNSAFE.get$Type$Opaque(handle.base,
handle.fieldOffset);
}
@ForceInline
static $type$ getAcquire(VarHandle ob) {
FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
return UNSAFE.get$Type$Acquire(handle.base,
handle.fieldOffset);
}
@ -496,7 +496,7 @@ final class VarHandle$Type$s {
@ForceInline
static void set(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
UNSAFE.put$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -504,7 +504,7 @@ final class VarHandle$Type$s {
@ForceInline
static void setVolatile(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
UNSAFE.put$Type$Volatile(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -512,7 +512,7 @@ final class VarHandle$Type$s {
@ForceInline
static void setOpaque(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
UNSAFE.put$Type$Opaque(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -520,7 +520,7 @@ final class VarHandle$Type$s {
@ForceInline
static void setRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
UNSAFE.put$Type$Release(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -529,7 +529,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean compareAndSet(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.compareAndSet$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -539,7 +539,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ compareAndExchange(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.compareAndExchange$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -548,7 +548,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ compareAndExchangeAcquire(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -557,7 +557,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ compareAndExchangeRelease(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.compareAndExchange$Type$Release(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -566,7 +566,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetPlain(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.weakCompareAndSet$Type$Plain(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -575,7 +575,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSet(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.weakCompareAndSet$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -584,7 +584,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetAcquire(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.weakCompareAndSet$Type$Acquire(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -593,7 +593,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetRelease(VarHandle ob, $type$ expected, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.weakCompareAndSet$Type$Release(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
@ -602,7 +602,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndSet(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndSet$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -610,7 +610,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndSetAcquire(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndSet$Type$Acquire(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -618,7 +618,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndSetRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndSet$Type$Release(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(value):value});
@ -628,7 +628,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndAdd(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndAdd$Type$(handle.base,
handle.fieldOffset,
value);
@ -636,7 +636,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndAddAcquire(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndAdd$Type$Acquire(handle.base,
handle.fieldOffset,
value);
@ -644,7 +644,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndAddRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndAdd$Type$Release(handle.base,
handle.fieldOffset,
value);
@ -654,7 +654,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseOr(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseOr$Type$(handle.base,
handle.fieldOffset,
value);
@ -662,7 +662,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseOrRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseOr$Type$Release(handle.base,
handle.fieldOffset,
value);
@ -670,7 +670,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseOrAcquire(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseOr$Type$Acquire(handle.base,
handle.fieldOffset,
value);
@ -678,7 +678,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseAnd(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseAnd$Type$(handle.base,
handle.fieldOffset,
value);
@ -686,7 +686,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseAndRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseAnd$Type$Release(handle.base,
handle.fieldOffset,
value);
@ -694,7 +694,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseAndAcquire(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseAnd$Type$Acquire(handle.base,
handle.fieldOffset,
value);
@ -702,7 +702,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseXor(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseXor$Type$(handle.base,
handle.fieldOffset,
value);
@ -710,7 +710,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseXorRelease(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseXor$Type$Release(handle.base,
handle.fieldOffset,
value);
@ -718,7 +718,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ getAndBitwiseXorAcquire(VarHandle ob, $type$ value) {
FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
return UNSAFE.getAndBitwiseXor$Type$Acquire(handle.base,
handle.fieldOffset,
value);