8149644: Integrate VarHandles
Reviewed-by: coffeys, mhaupt, vlivanov
Contributed-by: paul.sandoz@oracle.com, aleksey.shipilev@oracle.com
--- a/jdk/make/gensrc/Gensrc-java.base.gmk Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk Thu Mar 24 11:21:21 2016 +0100
@@ -33,6 +33,7 @@
include GensrcCharsetCoder.gmk
include GensrcBuffer.gmk
include GensrcExceptions.gmk
+include GensrcVarHandles.gmk
################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/GensrcVarHandles.gmk Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,160 @@
+#
+# Copyright (c) 2015, 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.
+#
+
+GENSRC_VARHANDLES :=
+
+VARHANDLES_GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/lang/invoke
+VARHANDLES_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/classes/java/lang/invoke
+
+################################################################################
+# Setup a rule for generating a VarHandle java class
+# Param 1 - Variable declaration prefix
+# Param 2 - Type with first letter capitalized
+define GenerateVarHandle
+
+ $1_Type := $2
+
+ $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandle$$($1_Type)s.java
+
+ ifneq ($$(findstring $$($1_Type), Object Int Long), )
+ $1_ARGS += -KCAS
+ endif
+
+ ifneq ($$(findstring $$($1_Type), Int Long), )
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandle.java.template $(BUILD_TOOLS_JDK)
+ ifeq ($$($1_Type), Object)
+ $$(eval $1_type := $$($1_Type))
+ else
+ $$(eval $1_type := $$(shell $(TR) '[:upper:]' '[:lower:]' <<< $$($1_Type)))
+ endif
+ $(MKDIR) -p $$(@D)
+ $(TOOL_SPP) -nel -K$$($1_type) -Dtype=$$($1_type) -DType=$$($1_Type) \
+ $$($1_ARGS) < $$< > $$@
+
+ GENSRC_VARHANDLES += $$($1_FILENAME)
+endef
+
+################################################################################
+
+################################################################################
+# Setup a rule for generating a VarHandleByteArray java class
+# Param 1 - Variable declaration prefix
+# Param 2 - Type with first letter capitalized
+define GenerateVarHandleByteArray
+
+ $1_Type := $2
+
+ $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandleByteArrayAs$$($1_Type)s.java
+
+ ifeq ($$($1_Type), Short)
+ $1_type := short
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+ endif
+
+ ifeq ($$($1_Type), Char)
+ $1_type := char
+ $1_BoxType := Character
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+ endif
+
+ ifeq ($$($1_Type), Int)
+ $1_type := int
+ $1_BoxType := Integer
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ ifeq ($$($1_Type), Long)
+ $1_type := long
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ ifeq ($$($1_Type), Float)
+ $1_type := float
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := int
+ $1_RawType := Int
+ $1_RawBoxType := Integer
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KfloatingPoint
+ endif
+
+ ifeq ($$($1_Type), Double)
+ $1_type := double
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := long
+ $1_RawType := Long
+ $1_RawBoxType := Long
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KfloatingPoint
+ endif
+
+ $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandleByteArrayView.java.template $(BUILD_TOOLS_JDK)
+ $(MKDIR) -p $$(@D)
+ $(TOOL_SPP) -nel -K$$($1_type) \
+ -Dtype=$$($1_type) -DType=$$($1_Type) -DBoxType=$$($1_BoxType) \
+ -DrawType=$$($1_rawType) -DRawType=$$($1_RawType) -DRawBoxType=$$($1_RawBoxType) \
+ $$($1_ARGS) < $$< > $$@
+
+ GENSRC_VARHANDLES += $$($1_FILENAME)
+endef
+
+################################################################################
+
+# List the types to generate source for, with capitalized first letter
+VARHANDLES_TYPES := Boolean Byte Short Char Int Long Float Double Object
+$(foreach t, $(VARHANDLES_TYPES), $(eval $(call GenerateVarHandle,VAR_HANDLE_$t,$t)))
+
+# List the types to generate source for, with capitalized first letter
+VARHANDLES_BYTE_ARRAY_TYPES := Short Char Int Long Float Double
+$(foreach t, $(VARHANDLES_BYTE_ARRAY_TYPES), $(eval $(call GenerateVarHandleByteArray,VAR_HANDLE_BYTE_ARRAY_$t,$t)))
+
+GENSRC_JAVA_BASE += $(GENSRC_VARHANDLES)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java Thu Mar 24 11:21:21 2016 +0100
@@ -41,7 +41,7 @@
private final int referenceKind;
InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
- assert(member.isResolved() || member.isMethodHandleInvoke());
+ assert(member.isResolved() || member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke());
assert(member.referenceKindIsConsistentWith(referenceKind));
this.member = member;
this.referenceKind = referenceKind;
@@ -79,7 +79,8 @@
@Override
public <T extends Member> T reflectAs(Class<T> expected, Lookup lookup) {
- if (member.isMethodHandleInvoke() && !member.isVarargs()) {
+ if ((member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke())
+ && !member.isVarargs()) {
// This member is an instance of a signature-polymorphic method, which cannot be reflected
// A method handle invoker can come in either of two forms:
// A generic placeholder (present in the source code, and varargs)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu Mar 24 11:21:21 2016 +0100
@@ -93,6 +93,16 @@
return setCachedInvoker(INV_BASIC, invoker);
}
+ /*non-public*/ MethodHandle varHandleMethodInvoker(VarHandle.AccessMode ak) {
+ // TODO cache invoker
+ return makeVarHandleMethodInvoker(ak);
+ }
+
+ /*non-public*/ MethodHandle varHandleMethodExactInvoker(VarHandle.AccessMode ak) {
+ // TODO cache invoker
+ return makeVarHandleMethodExactInvoker(ak);
+ }
+
private MethodHandle cachedInvoker(int idx) {
return invokers[idx];
}
@@ -117,6 +127,36 @@
return invoker;
}
+ private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak) {
+ MethodType mtype = targetType;
+ MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
+
+ LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.name(), mtype);
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
+
+ invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
+ assert(checkVarHandleInvoker(invoker));
+
+ maybeCompileToBytecode(invoker);
+ return invoker;
+ }
+
+ private MethodHandle makeVarHandleMethodExactInvoker(VarHandle.AccessMode ak) {
+ MethodType mtype = targetType;
+ MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
+
+ LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.name(), mtype);
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
+
+ invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
+ assert(checkVarHandleInvoker(invoker));
+
+ maybeCompileToBytecode(invoker);
+ return invoker;
+ }
+
/** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */
private void maybeCompileToBytecode(MethodHandle invoker) {
final int EAGER_COMPILE_ARITY_LIMIT = 10;
@@ -146,6 +186,16 @@
return true;
}
+ private boolean checkVarHandleInvoker(MethodHandle invoker) {
+ MethodType invokerType = targetType.insertParameterTypes(0, VarHandle.class);
+ assert(invokerType.equals(invoker.type()))
+ : java.util.Arrays.asList(targetType, invokerType, invoker);
+ assert(invoker.internalMemberName() == null ||
+ invoker.internalMemberName().getMethodType().equals(targetType));
+ assert(!invoker.isVarargsCollector());
+ return true;
+ }
+
/**
* Find or create an invoker which passes unchanged a given number of arguments
* and spreads the rest from a trailing array argument.
@@ -193,9 +243,9 @@
Object[] appendixResult) {
int which;
switch (name) {
- case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break;
- case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break;
- default: throw new InternalError("not invoker: "+name);
+ case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break;
+ case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break;
+ default: throw new InternalError("not invoker: "+name);
}
LambdaForm lform;
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
@@ -296,6 +346,199 @@
return lform;
}
+
+ static MemberName varHandleInvokeLinkerMethod(String name,
+ MethodType mtype) {
+ LambdaForm lform;
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
+ lform = varHandleMethodGenericLinkerHandleForm(name, mtype);
+ } else {
+ // TODO
+ throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
+ }
+ return lform.vmentry;
+ }
+
+ private static LambdaForm varHandleMethodGenericLinkerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_VH = 0;
+ final int ARG_BASE = THIS_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
+ final int LINKER_CALL = nameCursor++;
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_VH] = argument(THIS_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+ names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class));
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[THIS_VH], names[VAD_ARG]);
+
+ Object[] outArgs = new Object[ARG_LIMIT + 1];
+ outArgs[0] = names[CHECK_TYPE];
+ for (int i = 0; i < ARG_LIMIT; i++) {
+ outArgs[i + 1] = names[i];
+ }
+
+ if (CHECK_CUSTOM != -1) {
+ names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
+ }
+
+ MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType();
+ names[LINKER_CALL] = new Name(outCallType, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT + 1, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ private static LambdaForm varHandleMethodExactInvokerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_MH = 0;
+ final int CALL_VH = THIS_MH + 1;
+ final int ARG_BASE = CALL_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int GET_MEMBER = nameCursor++;
+ final int LINKER_CALL = nameCursor++;
+
+ MethodType invokerFormType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType()
+ .appendParameterTypes(MemberName.class);
+
+ MemberName linker = new MemberName(MethodHandle.class, "linkToStatic", invokerFormType, REF_invokeStatic);
+ try {
+ linker = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
+ names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+
+ BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
+ names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
+
+ NamedFunction getter = speciesData.getterFunction(0);
+ names[VAD_ARG] = new Name(getter, names[THIS_MH]);
+
+ Object[] outArgs = Arrays.copyOfRange(names, CALL_VH, ARG_LIMIT + 1, Object[].class);
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]);
+
+ names[GET_MEMBER] = new Name(NF_getVarHandleMemberName, names[CALL_VH], names[VAD_ARG]);
+ outArgs[outArgs.length - 1] = names[GET_MEMBER];
+
+ names[LINKER_CALL] = new Name(linker, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ private static LambdaForm varHandleMethodGenericInvokerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_MH = 0;
+ final int CALL_VH = THIS_MH + 1;
+ final int ARG_BASE = CALL_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int LINKER_CALL = nameCursor++;
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
+ names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+
+ BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
+ names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
+
+ NamedFunction getter = speciesData.getterFunction(0);
+ names[VAD_ARG] = new Name(getter, names[THIS_MH]);
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]);
+
+ Object[] outArgs = new Object[ARG_LIMIT];
+ outArgs[0] = names[CHECK_TYPE];
+ for (int i = 1; i < ARG_LIMIT; i++) {
+ outArgs[i] = names[i];
+ }
+
+ MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType();
+ names[LINKER_CALL] = new Name(outCallType, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_invoker" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MethodType expected = vad.symbolicMethodType;
+ MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
+
+ MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+ if (mn == null)
+ throw vh.unsupported();
+ // TODO the following MH is not constant, cache in stable field array
+ // on VarForm?
+ MethodHandle mh = DirectMethodHandle.make(mn);
+ if (actual == expected) {
+ return mh;
+ }
+ else {
+ // Adapt to the actual (which should never fail since mh's method
+ // type is in the basic form), then to the expected (which my fail
+ // if the symbolic type descriptor does not match)
+ // TODO optimize for the case of actual.erased() == expected.erased()
+ return mh.asType(actual.insertParameterTypes(0, VarHandle.class)).
+ asType(expected.insertParameterTypes(0, VarHandle.class));
+ }
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MethodType expected = vad.symbolicMethodType;
+ MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
+ if (actual != expected)
+ throw newWrongMethodTypeException(expected, actual);
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+ if (mn == null) {
+ throw vh.unsupported();
+ }
+ return mn;
+ }
+
/*non-public*/ static
WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
// FIXME: merge with JVM logic for throwing WMTE
@@ -415,7 +658,10 @@
NF_checkExactType,
NF_checkGenericType,
NF_getCallSiteTarget,
- NF_checkCustomized;
+ NF_checkCustomized,
+ NF_checkVarHandleGenericType,
+ NF_checkVarHandleExactType,
+ NF_getVarHandleMemberName;
static {
try {
NamedFunction nfs[] = {
@@ -426,7 +672,13 @@
NF_getCallSiteTarget = new NamedFunction(Invokers.class
.getDeclaredMethod("getCallSiteTarget", CallSite.class)),
NF_checkCustomized = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkCustomized", MethodHandle.class))
+ .getDeclaredMethod("checkCustomized", MethodHandle.class)),
+ NF_checkVarHandleGenericType = new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class)),
+ NF_checkVarHandleExactType = new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class)),
+ NF_getVarHandleMemberName = new NamedFunction(Invokers.class
+ .getDeclaredMethod("getVarHandleMemberName", VarHandle.class, VarHandle.AccessDescriptor.class))
};
// Each nf must be statically invocable or we get tied up in our bootstraps.
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Mar 24 11:21:21 2016 +0100
@@ -362,6 +362,23 @@
return false;
}
}
+ public boolean isVarHandleMethodInvoke() {
+ final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
+ final int negs = Modifier.STATIC;
+ if (testFlags(bits | negs, bits) &&
+ clazz == VarHandle.class) {
+ return isVarHandleMethodInvokeName(name);
+ }
+ return false;
+ }
+ public static boolean isVarHandleMethodInvokeName(String name) {
+ try {
+ VarHandle.AccessMode.valueOf(name);
+ return true;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
/** Utility method to query the modifier flags of this member. */
@@ -536,6 +553,17 @@
if (isMethodHandleInvoke())
return;
}
+ if (m.getDeclaringClass() == VarHandle.class &&
+ isVarHandleMethodInvokeName(m.getName())) {
+ // The JVM did not reify this signature-polymorphic instance.
+ // Need a special case here.
+ // See comments on MethodHandleNatives.linkMethod.
+ MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
+ int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual);
+ init(VarHandle.class, m.getName(), type, flags);
+ if (isVarHandleMethodInvoke())
+ return;
+ }
throw new LinkageError(m.toString());
}
assert(isResolved() && this.clazz != null);
@@ -664,6 +692,16 @@
return mem;
}
+ static MemberName makeVarHandleMethodInvoke(String name, MethodType type) {
+ return makeVarHandleMethodInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC);
+ }
+ static MemberName makeVarHandleMethodInvoke(String name, MethodType type, int mods) {
+ MemberName mem = new MemberName(VarHandle.class, name, type, REF_invokeVirtual);
+ mem.flags |= mods; // it's not resolved, but add these modifiers anyway
+ assert(mem.isVarHandleMethodInvoke()) : mem;
+ return mem;
+ }
+
// bare-bones constructor; the JVM will fill it in
MemberName() { }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Mar 24 11:21:21 2016 +0100
@@ -26,9 +26,11 @@
package java.lang.invoke;
-import java.util.*;
import jdk.internal.HotSpotIntrinsicCandidate;
+import java.util.Arrays;
+import java.util.Objects;
+
import static java.lang.invoke.MethodHandleStatics.*;
/**
@@ -92,14 +94,16 @@
* and {@code invoke} compile to an {@code invokevirtual} instruction.
* More unusually, the compiler must record the actual argument types,
* and may not perform method invocation conversions on the arguments.
- * Instead, it must push them on the stack according to their own unconverted types.
- * The method handle object itself is pushed on the stack before the arguments.
- * The compiler then calls the method handle with a symbolic type descriptor which
- * describes the argument and return types.
+ * Instead, it must generate instructions that push them on the stack according
+ * to their own unconverted types. The method handle object itself is pushed on
+ * the stack before the arguments.
+ * The compiler then generates an {@code invokevirtual} instruction that invokes
+ * the method handle with a symbolic type descriptor which describes the argument
+ * and return types.
* <p>
* To issue a complete symbolic type descriptor, the compiler must also determine
* the return type. This is based on a cast on the method invocation expression,
- * if there is one, or else {@code Object} if the invocation is an expression
+ * if there is one, or else {@code Object} if the invocation is an expression,
* or else {@code void} if the invocation is a statement.
* The cast may be to a primitive type (but not {@code void}).
* <p>
@@ -109,12 +113,12 @@
* {@code Void} except the null reference.
*
* <h1>Method handle invocation</h1>
- * The first time a {@code invokevirtual} instruction is executed
- * it is linked, by symbolically resolving the names in the instruction
+ * The first time an {@code invokevirtual} instruction is executed
+ * it is linked by symbolically resolving the names in the instruction
* and verifying that the method call is statically legal.
- * This is true of calls to {@code invokeExact} and {@code invoke}.
+ * This also holds for calls to {@code invokeExact} and {@code invoke}.
* In this case, the symbolic type descriptor emitted by the compiler is checked for
- * correct syntax and names it contains are resolved.
+ * correct syntax, and names it contains are resolved.
* Thus, an {@code invokevirtual} instruction which invokes
* a method handle will always link, as long
* as the symbolic type descriptor is syntactically well-formed
@@ -163,7 +167,7 @@
* in a program which uses method handles.
* <p>
* Because method types contain "live" {@code Class} objects,
- * method type matching takes into account both types names and class loaders.
+ * method type matching takes into account both type names and class loaders.
* Thus, even if a method handle {@code M} is created in one
* class loader {@code L1} and used in another {@code L2},
* method handle calls are type-safe, because the caller's symbolic type
@@ -174,7 +178,7 @@
* and its type is assigned, while the resolution in {@code L2} happens
* when the {@code invokevirtual} instruction is linked.
* <p>
- * Apart from the checking of type descriptors,
+ * Apart from type descriptor checks,
* a method handle's capability to call its underlying method is unrestricted.
* If a method handle is formed on a non-public method by a class
* that has access to that method, the resulting handle can be used
@@ -196,7 +200,7 @@
* Java code can create a method handle that directly accesses
* any method, constructor, or field that is accessible to that code.
* This is done via a reflective, capability-based API called
- * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
+ * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}.
* For example, a static method handle can be obtained
* from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
* There are also conversion methods from Core Reflection API objects,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Mar 24 11:21:21 2016 +0100
@@ -1060,6 +1060,19 @@
FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
return mh;
}
+ static MethodHandle fakeVarHandleInvoke(MemberName method) {
+ // TODO caching, is it necessary?
+ MethodType type = MethodType.methodType(method.getReturnType(), UnsupportedOperationException.class,
+ VarHandle.class, Object[].class);
+ MethodHandle mh = throwException(type);
+ mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke VarHandle"));
+ if (!method.getInvocationType().equals(mh.type()))
+ throw new InternalError(method.toString());
+ mh = mh.withInternalMemberName(method, false);
+ mh = mh.asVarargsCollector(Object[].class);
+ assert(method.isVarargs());
+ return mh;
+ }
/**
* Create an alias for the method handle which, when called,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Mar 24 11:21:21 2016 +0100
@@ -25,12 +25,15 @@
package java.lang.invoke;
+import jdk.internal.ref.CleanerFactory;
+import sun.invoke.util.Wrapper;
+
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
+
import static java.lang.invoke.MethodHandleNatives.Constants.*;
-import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-import jdk.internal.ref.CleanerFactory;
/**
* The JVM interface for the method handles package is all here.
@@ -367,8 +370,14 @@
Class<?> defc, String name, Object type,
Object[] appendixResult) {
try {
- if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
- return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+ if (refKind == REF_invokeVirtual) {
+ if (defc == MethodHandle.class) {
+ return Invokers.methodHandleInvokeLinkerMethod(
+ name, fixMethodType(callerClass, type), appendixResult);
+ } else if (defc == VarHandle.class) {
+ return varHandleOperationLinkerMethod(
+ name, fixMethodType(callerClass, type), appendixResult);
+ }
}
} catch (Throwable ex) {
if (ex instanceof LinkageError)
@@ -400,6 +409,80 @@
}
}
+ /**
+ * Obtain the method to link to the VarHandle operation.
+ * This method is located here and not in Invokers to avoid
+ * intializing that and other classes early on in VM bootup.
+ */
+ private static MemberName varHandleOperationLinkerMethod(String name,
+ MethodType mtype,
+ Object[] appendixResult) {
+ // Get the signature method type
+ MethodType sigType = mtype.basicType();
+
+ // Get the access kind from the method name
+ VarHandle.AccessMode ak;
+ try {
+ ak = VarHandle.AccessMode.valueOf(name);
+ } catch (IllegalArgumentException e) {
+ throw MethodHandleStatics.newInternalError(e);
+ }
+
+ // If not polymorphic in the return type, such as the compareAndSet
+ // methods that return boolean
+ if (ak.isPolyMorphicInReturnType) {
+ if (ak.returnType != mtype.returnType()) {
+ // The caller contains a different return type than that
+ // defined by the method
+ throw newNoSuchMethodErrorOnVarHandle(name, mtype);
+ }
+ // Adjust the return type of the signature method type
+ sigType = sigType.changeReturnType(ak.returnType);
+ }
+
+ // Get the guard method type for linking
+ MethodType guardType = sigType
+ // VarHandle at start
+ .insertParameterTypes(0, VarHandle.class)
+ // Access descriptor at end
+ .appendParameterTypes(VarHandle.AccessDescriptor.class);
+
+ // Create the appendix descriptor constant
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ appendixResult[0] = ad;
+
+ if (MethodHandleStatics.VAR_HANDLE_GUARDS) {
+ MemberName linker = new MemberName(
+ VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType),
+ guardType, REF_invokeStatic);
+ try {
+ return MemberName.getFactory().resolveOrFail(
+ REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class);
+ } catch (ReflectiveOperationException ex) {
+ // Fall back to lambda form linkage if guard method is not available
+ // TODO Optionally log fallback ?
+ }
+ }
+ return Invokers.varHandleInvokeLinkerMethod(name, mtype);
+ }
+ static String getVarHandleMethodSignature(MethodType mt) {
+ StringBuilder sb = new StringBuilder(mt.parameterCount() + 1);
+
+ for (int i = 0; i < mt.parameterCount(); i++) {
+ Class<?> pt = mt.parameterType(i);
+ sb.append(getCharType(pt));
+ }
+
+ sb.append('_').append(getCharType(mt.returnType()));
+
+ return sb.toString();
+ }
+ static char getCharType(Class<?> pt) {
+ return Wrapper.forBasicType(pt).basicTypeChar();
+ }
+ static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
+ return new NoSuchMethodError("VarHandle." + name + mtype);
+ }
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Mar 24 11:21:21 2016 +0100
@@ -50,9 +50,10 @@
static final int PROFILE_LEVEL;
static final boolean PROFILE_GWT;
static final int CUSTOMIZE_THRESHOLD;
+ static final boolean VAR_HANDLE_GUARDS;
static {
- final Object[] values = new Object[9];
+ final Object[] values = new Object[10];
AccessController.doPrivileged(new PrivilegedAction<>() {
public Void run() {
values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
@@ -64,6 +65,7 @@
values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
+ values[9] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
return null;
}
});
@@ -76,6 +78,7 @@
PROFILE_LEVEL = (Integer) values[6];
PROFILE_GWT = (Boolean) values[7];
CUSTOMIZE_THRESHOLD = (Integer) values[8];
+ VAR_HANDLE_GUARDS = (Boolean) values[9];
if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Mar 24 11:21:21 2016 +0100
@@ -44,6 +44,10 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+
/**
* This class consists exclusively of static methods that operate on or return
* method handles. They fall into several categories:
@@ -829,7 +833,14 @@
* {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
* {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
* with the same {@code type} argument.
- *
+ * <p>
+ * If the class is {@code VarHandle} and the name string corresponds to
+ * the name of a signature-polymorphic access mode method, the resulting
+ * method handle is equivalent to one produced by
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker} with
+ * the access mode corresponding to the name string and with the same
+ * {@code type} arguments.
+ * <p>
* <b>Example:</b>
* <blockquote><pre>{@code
import static java.lang.invoke.MethodHandles.*;
@@ -876,6 +887,9 @@
if (refc == MethodHandle.class) {
MethodHandle mh = findVirtualForMH(name, type);
if (mh != null) return mh;
+ } else if (refc == VarHandle.class) {
+ MethodHandle mh = findVirtualForVH(name, type);
+ if (mh != null) return mh;
}
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
MemberName method = resolveOrFail(refKind, refc, name, type);
@@ -892,6 +906,13 @@
assert(!MemberName.isMethodHandleInvokeName(name));
return null;
}
+ private MethodHandle findVirtualForVH(String name, MethodType type) {
+ try {
+ return varHandleInvoker(VarHandle.AccessMode.valueOf(name), type);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
/**
* Produces a method handle which creates an object and initializes it, using
@@ -1091,6 +1112,7 @@
* @exception SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null
+ * @see #findVarHandle(Class, String, Class)
*/
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_getField, refc, name, type);
@@ -1113,6 +1135,7 @@
* @exception SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws NullPointerException if any argument is null
+ * @see #findVarHandle(Class, String, Class)
*/
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_putField, refc, name, type);
@@ -1120,6 +1143,53 @@
}
/**
+ * Produces a VarHandle giving access to non-static fields of type
+ * {@code T} declared by a receiver class of type {@code R}, supporting
+ * shape {@code (R : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param recv the receiver class, of type {@code R}, that declares the
+ * non-static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to non-static fields.
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ * @since 9
+ */
+ public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName getField = resolveOrFail(REF_getField, recv, name, type);
+ MemberName putField = resolveOrFail(REF_putField, recv, name, type);
+ return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
+ }
+
+ /**
* Produces a method handle giving read access to a static field.
* The type of the method handle will have a return type of the field's
* value type.
@@ -1168,6 +1238,55 @@
}
/**
+ * Produces a VarHandle giving access to a static field of type
+ * {@code T} declared by a given declaring class, supporting shape
+ * {@code ((empty) : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * If the returned VarHandle is operated on, the declaring class will be
+ * initialized, if it has not already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param decl the class that declares the static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to a static field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ * @since 9
+ */
+ public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName getField = resolveOrFail(REF_getStatic, decl, name, type);
+ MemberName putField = resolveOrFail(REF_putStatic, decl, name, type);
+ return getFieldVarHandle(REF_getStatic, REF_putStatic, decl, getField, putField);
+ }
+
+ /**
* Produces an early-bound method handle for a non-static method.
* The receiver must have a supertype {@code defc} in which a method
* of the given name and type is accessible to the lookup class.
@@ -1253,6 +1372,10 @@
MethodHandle mh = unreflectForMH(m);
if (mh != null) return mh;
}
+ if (m.getDeclaringClass() == VarHandle.class) {
+ MethodHandle mh = unreflectForVH(m);
+ if (mh != null) return mh;
+ }
MemberName method = new MemberName(m);
byte refKind = method.getReferenceKind();
if (refKind == REF_invokeSpecial)
@@ -1267,6 +1390,12 @@
return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
return null;
}
+ private MethodHandle unreflectForVH(Method m) {
+ // these names require special lookups because they throw UnsupportedOperationException
+ if (MemberName.isVarHandleMethodInvokeName(m.getName()))
+ return MethodHandleImpl.fakeVarHandleInvoke(new MemberName(m));
+ return null;
+ }
/**
* Produces a method handle for a reflected method.
@@ -1391,6 +1520,57 @@
}
/**
+ * Produces a VarHandle that accesses fields of type {@code T} declared
+ * by a class of type {@code R}, as described by the given reflected
+ * field.
+ * If the field is non-static the VarHandle supports a shape of
+ * {@code (R : T)}, otherwise supports a shape of {@code ((empty) : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class, regardless of the value of the field's {@code accessible}
+ * flag.
+ * <p>
+ * If the field is static, and if the returned VarHandle is operated
+ * on, the field's declaring class will be initialized, if it has not
+ * already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param f the reflected field, with a field of type {@code T}, and
+ * a declaring class of type {@code R}
+ * @return a VarHandle giving access to non-static fields or a static
+ * field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ * @since 9
+ */
+ public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
+ MemberName getField = new MemberName(f, false);
+ MemberName putField = new MemberName(f, true);
+ return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(),
+ f.getDeclaringClass(), getField, putField);
+ }
+
+ /**
* Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
* created by this lookup object or a similar one.
* Security and access checks are performed to ensure that this lookup object
@@ -1410,7 +1590,9 @@
*/
public MethodHandleInfo revealDirect(MethodHandle target) {
MemberName member = target.internalMemberName();
- if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke()))
+ if (member == null || (!member.isResolved() &&
+ !member.isMethodHandleInvoke() &&
+ !member.isVarHandleMethodInvoke()))
throw newIllegalArgumentException("not a direct method handle");
Class<?> defc = member.getDeclaringClass();
byte refKind = member.getReferenceKind();
@@ -1787,6 +1969,52 @@
return restrictReceiver(field, dmh, lookupClass());
return dmh;
}
+ private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField)
+ throws IllegalAccessException {
+ final boolean checkSecurity = true;
+ return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
+ }
+ private VarHandle getFieldVarHandleNoSecurityManager(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField)
+ throws IllegalAccessException {
+ final boolean checkSecurity = false;
+ return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
+ }
+ private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField,
+ boolean checkSecurity) throws IllegalAccessException {
+ assert getField.isStatic() == putField.isStatic();
+ assert getField.isGetter() && putField.isSetter();
+ assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind);
+ assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind);
+
+ checkField(getRefKind, refc, getField);
+ if (checkSecurity)
+ checkSecurityManager(refc, getField);
+
+ if (!putField.isFinal()) {
+ // A VarHandle does not support updates to final fields, any
+ // such VarHandle to a final field will be read-only and
+ // therefore the following write-based accessibility checks are
+ // only required for non-final fields
+ checkField(putRefKind, refc, putField);
+ if (checkSecurity)
+ checkSecurityManager(refc, putField);
+ }
+
+ boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
+ restrictProtectedReceiver(getField));
+ if (doRestrict) {
+ assert !getField.isStatic();
+ // receiver type of VarHandle is too wide; narrow to caller
+ if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
+ throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
+ }
+ refc = lookupClass();
+ }
+ return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), this.allowedModes == TRUSTED);
+ }
/** Check access and get the requested constructor. */
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
final boolean checkSecurity = true;
@@ -1921,6 +2149,205 @@
return MethodHandleImpl.makeArrayElementAccessor(arrayClass, true);
}
+ /**
+ *
+ * Produces a VarHandle giving access to elements of an array type
+ * {@code T[]}, supporting shape {@code (T[], int : T)}.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the component type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the component type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * @param arrayClass the class of an array, of type {@code T[]}
+ * @return a VarHandle giving access to elements of an array
+ * @throws NullPointerException if the arrayClass is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ * @since 9
+ */
+ public static
+ VarHandle arrayElementVarHandle(Class<?> arrayClass) throws IllegalArgumentException {
+ return VarHandles.makeArrayElementHandle(arrayClass);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if it were a different primitive array type, such as
+ * {@code int[]} or {@code long[]}. The shape of the resulting VarHandle is
+ * {@code (byte[], int : T)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index in a {@code byte[]} array,
+ * and {@code T} is the component type of the given view array class. The
+ * returned VarHandle accesses bytes at an index in a {@code byte[]} array,
+ * composing bytes to or from a value of {@code T} according to the given
+ * endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code byte[]} array length minus the size (in bytes)
+ * of {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the array and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T};
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for {@code byte[]} arrays without operating on a specific array. Given
+ * an {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, misalignment may be determined as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
+ * alignmentOffset(0, sizeOfT);
+ * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ *
+ * @implNote
+ * The variable types {@code float} and {@code double} are supported as if
+ * by transformation to and access with the variable types {@code int} and
+ * {@code long} respectively. For example, the transformation of a
+ * {@code double} value to a long value is performed as if using
+ * {@link Double#doubleToRawLongBits(double)}, and the reverse
+ * transformation is performed as if using
+ * {@link Double#longBitsToDouble(long)}.
+ *
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param bigEndian true if the endianness of the view array elements, as
+ * stored in the underlying {@code byte} array, is big endian, otherwise
+ * little endian
+ * @return a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ */
+ public static
+ VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
+ boolean bigEndian) throws IllegalArgumentException {
+ return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if it were an array of elements of a different primitive
+ * component type to that of {@code byte}, such as {@code int[]} or
+ * {@code long[]}. The shape of the resulting VarHandle is
+ * {@code (ByteBuffer, int : T)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index in a {@code ByteBuffer}, and
+ * {@code T} is the component type of the given view array class. The
+ * returned VarHandle accesses bytes at an index in a {@code ByteBuffer},
+ * composing bytes to or from a value of {@code T} according to the given
+ * endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access will result in a {@code ReadOnlyBufferException} for anything
+ * other than the read access modes if the {@code ByteBuffer} is read-only.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
+ * {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the {@code ByteBuffer} and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T};
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an
+ * {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * ByteBuffer bb = ...
+ * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ *
+ * @implNote
+ * The variable types {@code float} and {@code double} are supported as if
+ * by transformation to and access with the variable types {@code int} and
+ * {@code long} respectively. For example, the transformation of a
+ * {@code double} value to a long value is performed as if using
+ * {@link Double#doubleToRawLongBits(double)}, and the reverse
+ * transformation is performed as if using
+ * {@link Double#longBitsToDouble(long)}.
+ *
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param bigEndian true if the endianness of the view array elements, as
+ * stored in the underlying {@code ByteBuffer}, is big endian, otherwise
+ * little endian (Note this overrides the endianness of a
+ * {@code ByteBuffer})
+ * @return a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ */
+ public static
+ VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
+ boolean bigEndian) throws IllegalArgumentException {
+ return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian);
+ }
+
+
/// method handle invocation (reflective style)
/**
@@ -2056,6 +2483,54 @@
return type.invokers().genericInvoker();
}
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is of the given type.
+ * @since 9
+ */
+ static public
+ MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return type.invokers().varHandleMethodExactInvoker(accessMode);
+ }
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ * <p>
+ * Before invoking its target, if the access mode type differs from the
+ * desired given type, the invoker will apply reference casts as necessary
+ * and box, unbox, or widen primitive values, as if by
+ * {@link MethodHandle#asType asType}. Similarly, the return value will be
+ * converted as necessary.
+ * <p>
+ * This method is equivalent to the following code (though it may be more
+ * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)}
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is convertible to the given
+ * type.
+ * @since 9
+ */
+ static public
+ MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return type.invokers().varHandleMethodInvoker(accessMode);
+ }
+
static /*non-public*/
MethodHandle basicInvoker(MethodType type) {
return type.invokers().basicInvoker();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Mar 24 11:21:21 2016 +0100
@@ -95,7 +95,7 @@
// The rtype and ptypes fields define the structural identity of the method type:
private final Class<?> rtype;
- private final Class<?>[] ptypes;
+ private final @Stable Class<?>[] ptypes;
// The remaining fields are caches of various sorts:
private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 2015, 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 java.lang.invoke.VarHandle.AccessMode;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
+
+/**
+ * A var handle form containing a set of member name, one for each operation.
+ * Each member characterizes a static method.
+ */
+class VarForm {
+
+ // Holds VarForm for VarHandle implementation classes
+ private static final ClassValue<VarForm> VFORMS
+ = new ClassValue<VarForm>() {
+ @Override
+ protected VarForm computeValue(Class<?> impl) {
+ return new VarForm(link(staticMethodLinker(impl)));
+ }
+ };
+
+ final MemberName mbGet;
+ final MemberName mbSet;
+ final MemberName mbGetVolatile;
+ final MemberName mbSetVolatile;
+ final MemberName mbGetAcquire;
+ final MemberName mbSetRelease;
+ final MemberName mbCompareAndSet;
+ final MemberName mbCompareAndExchangeVolatile;
+ final MemberName mbCompareAndExchangeAcquire;
+ final MemberName mbCompareAndExchangeRelease;
+ final MemberName mbWeakCompareAndSet;
+ final MemberName mbWeakCompareAndSetAcquire;
+ final MemberName mbWeakCompareAndSetRelease;
+ final MemberName mbGetAndSet;
+ final MemberName mbGetAndAdd;
+ final MemberName mbAddAndGet;
+ final MemberName mbGetOpaque;
+ final MemberName mbSetOpaque;
+
+ VarForm(Map<AccessMode, MemberName> linkMap) {
+ mbGet = linkMap.get(AccessMode.get);
+ mbSet = linkMap.get(AccessMode.set);
+ mbGetVolatile = linkMap.get(AccessMode.getVolatile);
+ mbSetVolatile = linkMap.get(AccessMode.setVolatile);
+ mbGetOpaque = linkMap.get(AccessMode.getOpaque);
+ mbSetOpaque = linkMap.get(AccessMode.setOpaque);
+ mbGetAcquire = linkMap.get(AccessMode.getAcquire);
+ mbSetRelease = linkMap.get(AccessMode.setRelease);
+ mbCompareAndSet = linkMap.get(AccessMode.compareAndSet);
+ mbCompareAndExchangeVolatile = linkMap.get(AccessMode.compareAndExchangeVolatile);
+ mbCompareAndExchangeAcquire = linkMap.get(AccessMode.compareAndExchangeAcquire);
+ mbCompareAndExchangeRelease = linkMap.get(AccessMode.compareAndExchangeRelease);
+ mbWeakCompareAndSet = linkMap.get(AccessMode.weakCompareAndSet);
+ mbWeakCompareAndSetAcquire = linkMap.get(AccessMode.weakCompareAndSetAcquire);
+ mbWeakCompareAndSetRelease = linkMap.get(AccessMode.weakCompareAndSetRelease);
+ mbGetAndSet = linkMap.get(AccessMode.getAndSet);
+ mbGetAndAdd = linkMap.get(AccessMode.getAndAdd);
+ mbAddAndGet = linkMap.get(AccessMode.addAndGet);
+ }
+
+ /**
+ * Creates a var form given an VarHandle implementation class.
+ * Each signature polymorphic method is linked to a static method of the
+ * same name on the implementation class or a super class.
+ */
+ static VarForm createFromStatic(Class<? extends VarHandle> impl) {
+ return VFORMS.get(impl);
+ }
+
+ /**
+ * Link all signature polymorphic methods.
+ */
+ private static Map<AccessMode, MemberName> link(Function<AccessMode, MemberName> linker) {
+ Map<AccessMode, MemberName> links = new HashMap<>();
+ for (AccessMode ak : AccessMode.values()) {
+ links.put(ak, linker.apply(ak));
+ }
+ return links;
+ }
+
+
+ /**
+ * Returns a function that associates an AccessMode with a MemberName that
+ * is a static concrete method implementation for the access operation of
+ * the implementing class.
+ */
+ private static Function<AccessMode, MemberName> staticMethodLinker(Class<?> implClass) {
+ // Find all declared static methods on the implementation class and
+ // all super classes up to but not including VarHandle
+ List<Method> staticMethods = new ArrayList<>(AccessMode.values().length);
+ for (Class<?> c = implClass; c != VarHandle.class; c = c.getSuperclass()) {
+ for (Method m : c.getDeclaredMethods()) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ staticMethods.add(m);
+ }
+ }
+ }
+
+ // This needs to be an anonymous inner class and not a lambda expression
+ // The latter will cause the intialization of classes in java.lang.invoke
+ // resulting in circular dependencies if VarHandles are utilized early
+ // in the start up process. For example, if ConcurrentHashMap
+ // is modified to use VarHandles.
+ return new Function<>() {
+ @Override
+ public MemberName apply(AccessMode ak) {
+ Method m = null;
+ for (Method to_m : staticMethods) {
+ if (to_m.getName().equals(ak.name()) &&
+ Modifier.isStatic(to_m.getModifiers())) {
+ assert m == null : String.format(
+ "Two or more static methods named %s are present on " +
+ "class %s or a super class", ak.name(), implClass.getName());
+ m = to_m;
+ }
+ }
+
+ if (m == null)
+ return null;
+
+ MemberName linkedMethod = new MemberName(m);
+ try {
+ return MemberName.getFactory().resolveOrFail(
+ REF_invokeStatic, linkedMethod, m.getDeclaringClass(), NoSuchMethodException.class);
+ }
+ catch (ReflectiveOperationException e) {
+ throw new InternalError(e);
+ }
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,1416 @@
+/*
+ * Copyright (c) 2014, 2015, 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.HotSpotIntrinsicCandidate;
+import jdk.internal.vm.annotation.ForceInline;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+import static java.lang.invoke.MethodHandleStatics.newInternalError;
+
+/**
+ * A VarHandle is a dynamically typed reference to a variable, or to a
+ * parametrically-defined family of variables, including static fields,
+ * non-static fields, array elements, or components of an off-heap data
+ * structure. Access to such variables is supported under various
+ * <em>access modes</em>, including plain read/write access, volatile
+ * read/write access, and compare-and-swap.
+ *
+ * <p>VarHandles are immutable and have no visible state. VarHandles cannot be
+ * subclassed by the user.
+ *
+ * <p>A VarHandle has:
+ * <ul>
+ * <li>a {@link #varType variable type}, referred to as {@code T}, which is the
+ * type of variable(s) referenced by this VarHandle;
+ * <li>a list of {@link #coordinateTypes coordinate types}, referred to as
+ * {@code CT}, where the types (primitive and reference) are represented by
+ * {@link Class} objects). A list of arguments corresponding to instances of
+ * the coordinate types uniquely locates a variable referenced by this
+ * VarHandle; and
+ * <li>a <em>shape</em>, that combines the variable type and coordinate types,
+ * and is declared with the notation {@code (CT : T)}. An empty list of
+ * coordinate types is declared as {@code (empty)}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the supported variable type, coordinate
+ * types, and shape.
+ *
+ * For example, a VarHandle referencing a non-static field will declare a shape
+ * of {@code (R : T)}, where {@code R} is the receiver type and
+ * {@code T} is the field type, and where the VarHandle and an instance of the
+ * receiver type can be utilized to access the field variable.
+ * A VarHandle referencing array elements will declare a shape of
+ * {@code (T[], int : T)}, where {@code T[]} is the array type and {@code T}
+ * its component type, and where the VarHandle, an instance of the array type,
+ * and an {@code int} index can be utilized to access an array element variable.
+ *
+ * <p>Each access mode is associated with a
+ * <a href="MethodHandle.html#sigpoly">signature polymorphic</a> method of the
+ * same name, where the VarHandle shape and access mode uniquely determine the
+ * canonical {@link #accessModeType(AccessMode) access mode type},
+ * which in turn determines the matching constraints on a valid symbolic
+ * type descriptor at the call site of an access mode's method
+ * <a href="VarHandle.html#invoke">invocation</a>.
+ *
+ * As such, VarHandles are dynamically and strongly typed. Their arity,
+ * argument types, and return type of an access mode method invocation are not
+ * statically checked. If they, and associated values, do not match the arity
+ * and types of the access mode's type, an exception will be thrown.
+ *
+ * The parameter types of an access mode method type will consist of those that
+ * are the VarHandles's coordinate types (in order), followed by access mode
+ * parameter types specific to the access mode.
+ *
+ * <p>An access mode's method documents the form of its method signature, which
+ * is derived from the access mode parameter types. The form is declared with
+ * the notation {@code (CT, P1 p1, P2 p2, ..., PN pn)R}, where {@code CT} is the
+ * coordinate types (as documented by a VarHandle factory method), {@code P1},
+ * {@code P2} and {@code PN} are the first, second and the n'th access mode
+ * parameters named {@code p1}, {@code p2} and {@code pn} respectively, and
+ * {@code R} is the return type.
+ *
+ * For example, for the generic shape of {@code (CT : T)} the
+ * {@link #compareAndSet} access mode method documents that its method
+ * signature is of the form {@code (CT, T expectedValue, T newValue)boolean},
+ * where the parameter types named {@code extendedValue} and {@code newValue}
+ * are the access mode parameter types. If the VarHandle accesses array
+ * elements with a shape of say {@code (T[], int : T)} then the access mode
+ * method type is {@code (T[], int, T, T)boolean}.
+ *
+ * <p>Access modes are grouped into the following categories:
+ * <ul>
+ * <li>read access modes that get the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #get get},
+ * {@link #getVolatile getVolatile},
+ * {@link #getAcquire getAcquire},
+ * {@link #getOpaque getOpaque}.
+ * <li>write access modes that set the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #set set},
+ * {@link #setVolatile setVolatile},
+ * {@link #setRelease setRelease},
+ * {@link #setOpaque setOpaque}.
+ * <li>atomic update access modes that, for example, atomically compare and set
+ * the value of a variable under specified memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #compareAndSet compareAndSet},
+ * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
+ * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
+ * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
+ * {@link #compareAndExchangeVolatile compareAndExchangeVolatile},
+ * {@link #compareAndExchangeRelease compareAndExchangeRelease},
+ * {@link #getAndSet getAndSet}.
+ * <li>numeric atomic update access modes that, for example, atomically get and
+ * set with addition the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndAdd getAndAdd},
+ * {@link #addAndGet addAndGet}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the set of access modes that are
+ * supported, which may also include documenting restrictions based on the
+ * variable type and whether a variable is read-only. If an access mode is not
+ * supported then the corresponding signature-polymorphic method will on
+ * invocation throw an {@code UnsupportedOperationException}.
+ * The {@link #get get} access mode is supported for all
+ * VarHandle instances and the corresponding method never throws
+ * {@code UnsupportedOperationException}.
+ * If a VarHandle references a read-only variable (for example a {@code final}
+ * field) then write, atomic update and numeric atomic update access modes are
+ * not supported and corresponding methods throw
+ * {@code UnsupportedOperationException}.
+ * Read/write access modes (if supported), with the exception of
+ * {@code get} and {@code set}, provide atomic access for
+ * reference types and all primitive types.
+ * Unless stated otherwise in the documentation of a factory method, the access
+ * modes {@code get} and {@code set} (if supported) provide atomic access for
+ * reference types and all primitives types, with the exception of {@code long}
+ * and {@code double} on 32-bit platforms
+ *
+ * <p>Access modes will override any memory ordering effects specified at
+ * the declaration site of a variable. For example, a VarHandle accessing a
+ * a field using the {@code get} access mode will access the field as
+ * specified <em>by its access mode</em> even if that field is declared
+ * {@code volatile}. When mixed access is performed extreme care should be
+ * taken since the Java Memory Model may permit surprising results.
+ *
+ * <p>In addition to supporting access to variables under various access modes,
+ * a set of static methods, referred to as memory fence methods, is also
+ * provided for fine-grained control of memory ordering.
+ *
+ * The Java Language Specification permits other threads to observe operations
+ * as if they were executed in orders different than are apparent in program
+ * source code, subject to constraints arising, for example, from the use of
+ * locks, {@code volatile} fields or VarHandles. The static methods,
+ * {@link #fullFence fullFence}, {@link #acquireFence acquireFence},
+ * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and
+ * {@link #storeStoreFence storeStoreFence}, can also be used to impose
+ * constraints. Their specifications, as is the case for certain access modes,
+ * are phrased in terms of the lack of "reorderings" -- observable ordering
+ * effects that might otherwise occur if the fence was not present. More
+ * precise phrasing of the specification of access mode methods and memory fence
+ * methods may accompany future updates of the Java Language Specification.
+ *
+ * <h1>Compilation of an access mode's method</h1>
+ * A Java method call expression naming an access mode method can invoke a
+ * VarHandle from Java source code. From the viewpoint of source code, these
+ * methods can take any arguments and their polymorphic result (if expressed)
+ * can be cast to any return type. Formally this is accomplished by giving the
+ * access mode methods variable arity {@code Object} arguments and
+ * {@code Object} return types (if the return type is polymorphic), but they
+ * have an additional quality called <em>signature polymorphism</em> which
+ * connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to access mode methods
+ * compile to an {@code invokevirtual} instruction. More unusually, the
+ * compiler must record the actual argument types, and may not perform method
+ * invocation conversions on the arguments. Instead, it must generate
+ * instructions to push them on the stack according to their own unconverted
+ * types. The VarHandle object itself will be pushed on the stack before the
+ * arguments. The compiler then generates an {@code invokevirtual} instruction
+ * that invokes the access mode method with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also
+ * determine the return type (if polymorphic). This is based on a cast on the
+ * method invocation expression, if there is one, or else {@code Object} if the
+ * invocation is an expression, or else {@code void} if the invocation is a
+ * statement. The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given a symbolic type
+ * descriptor of {@code java.lang.Void}. The ambiguity with the type
+ * {@code Void} is harmless, since there are no references of type {@code Void}
+ * except the null reference.
+ *
+ *
+ * <h1><a name="invoke">Invocation of an access mode's method</a></h1>
+ * The first time an {@code invokevirtual} instruction is executed it is linked
+ * by symbolically resolving the names in the instruction and verifying that
+ * the method call is statically legal. This also holds for calls to access mode
+ * methods. In this case, the symbolic type descriptor emitted by the compiler
+ * is checked for correct syntax, and names it contains are resolved. Thus, an
+ * {@code invokevirtual} instruction which invokes an access mode method will
+ * always link, as long as the symbolic type descriptor is syntactically
+ * well-formed and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking, the receiving
+ * VarHandle's access mode type is first checked by the JVM to ensure that it
+ * matches the symbolic type descriptor. If the type
+ * match fails, it means that the access mode method which the caller is
+ * invoking is not present on the individual VarHandle being invoked.
+ *
+ * <p>
+ * Invocation of an access mode's signature-polymorphic method behaves as if an
+ * invocation of {@link MethodHandle#invoke}, where the receiving method handle
+ * is bound to a VarHandle instance and the access mode. More specifically, the
+ * following:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
+ * }</pre>
+ * behaves as if (modulo the access mode methods do not declare throwing of
+ * {@code Throwable}):
+ * <pre> {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * VarHandle.AccessMode.{access-mode},
+ * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * mh = mh.bindTo(vh);
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * or, more concisely, behaves as if:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = vh.toMethodHandle(VarHandle.AccessMode.{access-mode});
+ *
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * In terms of equivalent {@code invokevirtual} bytecode behaviour an access
+ * mode method invocation is equivalent to:
+ * <pre> {@code
+ * MethodHandle mh = MethodHandles.lookup().findVirtual(
+ * VarHandle.class,
+ * VarHandle.AccessMode.{access-mode}.name(),
+ * MethodType.methodType(R, p1, p2, ..., pN));
+ *
+ * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
+ * }</pre>
+ * where the desired method type is the symbolic type descriptor and a
+ * {@link MethodHandle#invokeExact} is performed, since before invocation of the
+ * target, the handle will apply reference casts as necessary and box, unbox, or
+ * widen primitive values, as if by {@link MethodHandle#asType asType} (see also
+ * {@link MethodHandles#varHandleInvoker}).
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, VarHandle access mode type matching will usually
+ * succeed. But if a match fails, the JVM will throw a
+ * {@link WrongMethodTypeException}.
+ * <p>
+ * Thus, an access mode type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as a dynamic
+ * {@code WrongMethodTypeException} in a program which uses VarHandles.
+ * <p>
+ * Because access mode types contain "live" {@code Class} objects, method type
+ * matching takes into account both type names and class loaders.
+ * Thus, even if a VarHandle {@code VH} is created in one class loader
+ * {@code L1} and used in another {@code L2}, VarHandle access mode method
+ * calls are type-safe, because the caller's symbolic type descriptor, as
+ * resolved in {@code L2}, is matched against the original callee method's
+ * symbolic type descriptor, as resolved in {@code L1}. The resolution in
+ * {@code L1} happens when {@code VH} is created and its access mode types are
+ * assigned, while the resolution in {@code L2} happens when the
+ * {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from type descriptor checks, a VarHandles's capability to
+ * access it's variables is unrestricted.
+ * If a VarHandle is formed on a non-public variable by a class that has access
+ * to that variable, the resulting VarHandle can be used in any place by any
+ * caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time a
+ * reflective method is invoked, VarHandle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the VarHandle is
+ * created</a>.
+ * Thus, VarHandles to non-public variables, or to variables in non-public
+ * classes, should generally be kept secret. They should not be passed to
+ * untrusted code unless their use from the untrusted code would be harmless.
+ *
+ *
+ * <h1>VarHandle creation</h1>
+ * Java code can create a VarHandle that directly accesses any field that is
+ * accessible to that code. This is done via a reflective, capability-based
+ * API called {@link java.lang.invoke.MethodHandles.Lookup
+ * MethodHandles.Lookup}.
+ * For example, a VarHandle for a non-static field can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle
+ * Lookup.findVarHandle}.
+ * There is also a conversion method from Core Reflection API objects,
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * <p>
+ * Access to protected field members is restricted to receivers only of the
+ * accessing class, or one of its subclasses, and the accessing class must in
+ * turn be a subclass (or package sibling) of the protected member's defining
+ * class. If a VarHandle refers to a protected non-static field of a declaring
+ * class outside the current package, the receiver argument will be narrowed to
+ * the type of the accessing class.
+ *
+ * <h1>Interoperation between VarHandles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup
+ * Lookup} API, any field represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent VarHandle.
+ * For example, a reflective {@link java.lang.reflect.Field Field} can
+ * be converted to a VarHandle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * The resulting VarHandles generally provide more direct and efficient
+ * access to the underlying fields.
+ * <p>
+ * As a special case, when the Core Reflection API is used to view the
+ * signature polymorphic access mode methods in this class, they appear as
+ * ordinary non-polymorphic methods. Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers
+ * Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs}
+ * bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be invoked
+ * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke},
+ * via JNI, or indirectly via
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * However, such reflective calls do not result in access mode method
+ * invocations. Such a call, if passed the required argument (a single one, of
+ * type {@code Object[]}), will ignore the argument and will throw an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively invoke VarHandle
+ * access mode methods under any symbolic type descriptor, this reflective view
+ * conflicts with the normal presentation of these methods via bytecodes.
+ * Thus, these native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular access mode type,
+ * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. The
+ * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle to call an access mode method for
+ * any specified access mode type and is equivalent in behaviour to
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
+ *
+ * <h1>Interoperation between VarHandles and Java generics</h1>
+ * A VarHandle can be obtained for a variable, such as a a field, which is
+ * declared with Java generic types. As with the Core Reflection API, the
+ * VarHandle's variable type will be constructed from the erasure of the
+ * source-level type. When a VarHandle access mode method is invoked, the
+ * types
+ * of its arguments or the return value cast type may be generic types or type
+ * instances. If this occurs, the compiler will replace those types by their
+ * erasures when it constructs the symbolic type descriptor for the
+ * {@code invokevirtual} instruction.
+ *
+ * @see MethodHandle
+ * @see MethodHandles
+ * @see MethodType
+ * @since 9
+ */
+public abstract class VarHandle {
+ // Use explicit final fields rather than an @Stable array as
+ // this can reduce the memory per handle
+ // e.g. by 24 bytes on 64 bit architectures
+ final MethodType typeGet;
+ final MethodType typeSet;
+ final MethodType typeCompareSwap;
+ final MethodType typeCompareExchange;
+ final MethodType typeGetAndUpdate;
+
+ final VarForm vform;
+
+ VarHandle(VarForm vform, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+ this.vform = vform;
+
+ // (Receiver, <Intermediates>)
+ List<Class<?>> l = new ArrayList<>();
+ if (receiver != null)
+ l.add(receiver);
+ l.addAll(Arrays.asList(intermediate));
+
+ // (Receiver, <Intermediates>)Value
+ this.typeGet = MethodType.methodType(value, l);
+
+ // (Receiver, <Intermediates>, Value)void
+ l.add(value);
+ this.typeSet = MethodType.methodType(void.class, l);
+
+ // (Receiver, <Intermediates>, Value)Value
+ this.typeGetAndUpdate = MethodType.methodType(value, l);
+
+ // (Receiver, <Intermediates>, Value, Value)boolean
+ l.add(value);
+ this.typeCompareSwap = MethodType.methodType(boolean.class, l);
+
+ // (Receiver, <Intermediates>, Value, Value)Value
+ this.typeCompareExchange = MethodType.methodType(value, l);
+ }
+
+ RuntimeException unsupported() {
+ return new UnsupportedOperationException();
+ }
+
+ // Plain accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as
+ * if the variable was declared non-{@code volatile}. Commonly referred to
+ * as plain read access.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code get}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle.
+ *
+ * <p>This access mode is supported by all VarHandle instances and never
+ * throws {@code UnsupportedOperationException}.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object get(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared non-{@code volatile}
+ * and non-{@code final}. Commonly referred to as plain write access.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}
+ *
+ * <p>The symbolic type descriptor at the call site of {@code set}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void set(Object... args);
+
+
+ // Volatile accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as if
+ * the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getVolatile(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_seq_cst}.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setVolatile(Object... args);
+
+
+ /**
+ * Returns the value of a variable, accessed in program order, but with no
+ * assurance of memory ordering effects with respect to other threads.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getOpaque(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, in program order,
+ * but with no assurance of memory ordering effects with respect to other
+ * threads.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setOpaque(Object... args);
+
+
+ // Lazy accessors
+
+ /**
+ * Returns the value of a variable, and ensures that subsequent loads and
+ * stores are not reordered before this access.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_acquire} ordering.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAcquire(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, and ensures that
+ * prior loads and stores are not reordered after this access.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_release} ordering.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setRelease(Object... args);
+
+
+ // Compare and set accessors
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndSet} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean compareAndSet(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeVolatile(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setRelease} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeRelease(Object... args);
+
+ // Weak (spurious failures allowed)
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSet} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSet(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetAcquire(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #setRelease} if the variable's current
+ * value, referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetRelease(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndSet}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAndSet(Object... args);
+
+
+ // Primitive adders
+ // Throw UnsupportedOperationException for refs
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setVolatile}, and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAndAdd(Object... args);
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setVolatile}, and returns the variable's
+ * current (updated) value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code addAndGet}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the current value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object addAndGet(Object... args);
+
+ enum AccessType {
+ get, // 0
+ set, // 1
+ compareAndSwap, // 2
+ compareAndExchange, // 3
+ getAndUpdate; // 4
+
+ MethodType getMethodType(VarHandle vh) {
+ return getMethodType(this.ordinal(), vh);
+ }
+
+ @ForceInline
+ static MethodType getMethodType(int ordinal, VarHandle vh) {
+ if (ordinal == 0) {
+ return vh.typeGet;
+ }
+ else if (ordinal == 1) {
+ return vh.typeSet;
+ }
+ else if (ordinal == 2) {
+ return vh.typeCompareSwap;
+ }
+ else if (ordinal == 3) {
+ return vh.typeCompareExchange;
+ }
+ else if (ordinal == 4) {
+ return vh.typeGetAndUpdate;
+ }
+ else {
+ throw new IllegalStateException("Illegal access type: " + ordinal);
+ }
+ }
+ }
+
+ /**
+ * The set of access modes that specify how a variable, referenced by a
+ * VarHandle, is accessed.
+ */
+ public enum AccessMode {
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#get VarHandle.get}
+ */
+ get(AccessType.get, Object.class), // 0
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#set VarHandle.set}
+ */
+ set(AccessType.set, void.class), // 1
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getVolatile VarHandle.getVolatile}
+ */
+ getVolatile(AccessType.get, Object.class), // 2
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setVolatile VarHandle.setVolatile}
+ */
+ setVolatile(AccessType.set, void.class), // 3
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAcquire VarHandle.getAcquire}
+ */
+ getAcquire(AccessType.get, Object.class), // 4
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setRelease VarHandle.setRelease}
+ */
+ setRelease(AccessType.set, void.class), // 5
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getOpaque VarHandle.getOpaque}
+ */
+ getOpaque(AccessType.get, Object.class), // 6
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setOpaque VarHandle.setOpaque}
+ */
+ setOpaque(AccessType.set, void.class), // 7
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
+ */
+ compareAndSet(AccessType.compareAndSwap, boolean.class), // 8
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
+ */
+ compareAndExchangeVolatile(AccessType.compareAndExchange, Object.class), // 9
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
+ */
+ compareAndExchangeAcquire(AccessType.compareAndExchange, Object.class), // 10
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
+ */
+ compareAndExchangeRelease(AccessType.compareAndExchange, Object.class), // 11
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
+ */
+ weakCompareAndSet(AccessType.compareAndSwap, boolean.class), // 12
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
+ */
+ weakCompareAndSetAcquire(AccessType.compareAndSwap, boolean.class), // 13
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
+ */
+ weakCompareAndSetRelease(AccessType.compareAndSwap, boolean.class), // 14
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndSet VarHandle.getAndSet}
+ */
+ getAndSet(AccessType.getAndUpdate, Object.class), // 15
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
+ */
+ getAndAdd(AccessType.getAndUpdate, Object.class), // 16
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#addAndGet VarHandle.addAndGet}
+ */
+ addAndGet(AccessType.getAndUpdate, Object.class), // 17
+ ;
+
+ final AccessType at;
+ final boolean isPolyMorphicInReturnType;
+ final Class<?> returnType;
+
+ AccessMode(AccessType at, Class<?> returnType) {
+ this.at = at;
+
+ // Assert that return type is correct
+ // Otherwise, when disabled avoid using reflection
+ assert returnType == getReturnType(name());
+
+ this.returnType = returnType;
+ isPolyMorphicInReturnType = returnType != Object.class;
+ }
+
+ private static Class<?> getReturnType(String name) {
+ try {
+ Method m = VarHandle.class.getMethod(name, Object[].class);
+ return m.getReturnType();
+ }
+ catch (Exception e) {
+ throw newInternalError(e);
+ }
+ }
+
+ @ForceInline
+ static MemberName getMemberName(int ordinal, VarForm vform) {
+ if (ordinal == 0) {
+ return vform.mbGet;
+ }
+ else if (ordinal == 1) {
+ return vform.mbSet;
+ }
+ else if (ordinal == 2) {
+ return vform.mbGetVolatile;
+ }
+ else if (ordinal == 3) {
+ return vform.mbSetVolatile;
+ }
+ else if (ordinal == 4) {
+ return vform.mbGetAcquire;
+ }
+ else if (ordinal == 5) {
+ return vform.mbSetRelease;
+ }
+ else if (ordinal == 6) {
+ return vform.mbGetOpaque;
+ }
+ else if (ordinal == 7) {
+ return vform.mbSetOpaque;
+ }
+ else if (ordinal == 8) {
+ return vform.mbCompareAndSet;
+ }
+ else if (ordinal == 9) {
+ return vform.mbCompareAndExchangeVolatile;
+ }
+ else if (ordinal == 10) {
+ return vform.mbCompareAndExchangeAcquire;
+ }
+ else if (ordinal == 11) {
+ return vform.mbCompareAndExchangeRelease;
+ }
+ else if (ordinal == 12) {
+ return vform.mbWeakCompareAndSet;
+ }
+ else if (ordinal == 13) {
+ return vform.mbWeakCompareAndSetAcquire;
+ }
+ else if (ordinal == 14) {
+ return vform.mbWeakCompareAndSetRelease;
+ }
+ else if (ordinal == 15) {
+ return vform.mbGetAndSet;
+ }
+ else if (ordinal == 16) {
+ return vform.mbGetAndAdd;
+ }
+ else if (ordinal == 17) {
+ return vform.mbAddAndGet;
+ }
+ else {
+ throw new IllegalStateException("Illegal access mode: " + ordinal);
+ }
+ }
+ }
+
+ static final class AccessDescriptor {
+ final MethodType symbolicMethodType;
+ final int type;
+ final int mode;
+
+ public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
+ this.symbolicMethodType = symbolicMethodType;
+ this.type = type;
+ this.mode = mode;
+ }
+ }
+
+ /**
+ * Returns the variable type of variables referenced by this VarHandle.
+ *
+ * @return the variable type of variables referenced by this VarHandle
+ */
+ public final Class<?> varType() {
+ return typeSet.parameterType(typeSet.parameterCount() - 1);
+ }
+
+ /**
+ * Returns the coordinate types for this VarHandle.
+ *
+ * @return the coordinate types for this VarHandle. The returned
+ * list is unmodifiable
+ */
+ public final List<Class<?>> coordinateTypes() {
+ return typeGet.parameterList();
+ }
+
+ /**
+ * Obtains the canonical access mode type for this VarHandle and a given
+ * access mode.
+ *
+ * <p>The access mode type's parameter types will consist of a prefix that
+ * is the coordinate types of this VarHandle followed by further
+ * types as defined by the access mode's method.
+ * The access mode type's return type is defined by the return type of the
+ * access mode's method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return the access mode type for the given access mode
+ */
+ public final MethodType accessModeType(AccessMode accessMode) {
+ return accessMode.at.getMethodType(this);
+ }
+
+
+ /**
+ * Returns {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ *
+ * <p>The return of a {@code false} value for a given access mode indicates
+ * that an {@code UnsupportedOperationException} is thrown on invocation
+ * of the corresponding access mode's signature-polymorphic method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ */
+ public final boolean isAccessModeSupported(AccessMode accessMode) {
+ return AccessMode.getMemberName(accessMode.ordinal(), vform) != null;
+ }
+
+ /**
+ * Obtains a method handle bound to this VarHandle and the given access
+ * mode.
+ *
+ * @apiNote This method, for a VarHandle {@code vh} and access mode
+ * {@code {access-mode}}, returns a method handle that is equivalent to
+ * method handle {@code bhm} in the following code (though it may be more
+ * efficient):
+ * <pre>{@code
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * MethodHandle bmh = mh.bindTo(vh);
+ * }</pre>
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return a method handle bound to this VarHandle and the given access mode
+ */
+ public final MethodHandle toMethodHandle(AccessMode accessMode) {
+ MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
+ if (mn != null) {
+ return DirectMethodHandle.make(mn).
+ bindTo(this).
+ asType(accessMode.at.getMethodType(this));
+ }
+ else {
+ // Ensure an UnsupportedOperationException is thrown
+ return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
+ bindTo(this);
+ }
+ }
+
+ /*non-public*/
+ final void updateVarForm(VarForm newVForm) {
+ if (vform == newVForm) return;
+ UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
+ UNSAFE.fullFence();
+ }
+
+ static final BiFunction<Integer, Integer, ArrayIndexOutOfBoundsException> AIOOBE_SUPPLIER = new BiFunction<>() {
+ @Override
+ public ArrayIndexOutOfBoundsException apply(Integer a, Integer b) {
+ return new ArrayIndexOutOfBoundsException(a, b);
+ }
+ };
+
+ private static final long VFORM_OFFSET;
+
+ static {
+ try {
+ VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
+ }
+ catch (ReflectiveOperationException e) {
+ throw newInternalError(e);
+ }
+ }
+
+
+ // Fence methods
+
+ /**
+ * Ensures that loads and stores before the fence will not be reordered
+ * with
+ * loads and stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_seq_cst)}
+ */
+ @ForceInline
+ public static void fullFence() {
+ UNSAFE.fullFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with loads and
+ * stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_acquire)}
+ */
+ @ForceInline
+ public static void acquireFence() {
+ UNSAFE.loadFence();
+ }
+
+ /**
+ * Ensures that loads and stores before the fence will not be
+ * reordered with stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_release)}
+ */
+ @ForceInline
+ public static void releaseFence() {
+ UNSAFE.storeFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with
+ * loads after the fence.
+ */
+ @ForceInline
+ public static void loadLoadFence() {
+ UNSAFE.loadLoadFence();
+ }
+
+ /**
+ * Ensures that stores before the fence will not be reordered with
+ * stores after the fence.
+ */
+ @ForceInline
+ public static void storeStoreFence() {
+ UNSAFE.storeStoreFence();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, 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 java.nio.Buffer;
+import java.nio.ByteBuffer;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+/**
+ * The base class for generated byte array and byte buffer view
+ * implementations
+ */
+abstract class VarHandleByteArrayBase {
+ // Buffer.address
+ static final long BUFFER_ADDRESS;
+ // Buffer.limit
+ static final long BUFFER_LIMIT;
+ // ByteBuffer.hb
+ static final long BYTE_BUFFER_HB;
+ // ByteBuffer.isReadOnly
+ static final long BYTE_BUFFER_IS_READ_ONLY;
+
+ static {
+ try {
+ BUFFER_ADDRESS = UNSAFE.objectFieldOffset(
+ Buffer.class.getDeclaredField("address"));
+
+ BUFFER_LIMIT = UNSAFE.objectFieldOffset(
+ Buffer.class.getDeclaredField("limit"));
+
+ BYTE_BUFFER_HB = UNSAFE.objectFieldOffset(
+ ByteBuffer.class.getDeclaredField("hb"));
+
+ BYTE_BUFFER_IS_READ_ONLY = UNSAFE.objectFieldOffset(
+ ByteBuffer.class.getDeclaredField("isReadOnly"));
+ }
+ catch (ReflectiveOperationException e) {
+ throw new Error(e);
+ }
+ }
+
+ static final boolean BE = UNSAFE.isBigEndian();
+
+ static IllegalStateException newIllegalStateExceptionForMisalignedAccess(int index) {
+ return new IllegalStateException("Misaligned access at index: " + index);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,1391 @@
+/*
+ * Copyright (c) 2014, 2016, 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;
+
+// This class is auto-generated by java.lang.invoke.VarHandles$GuardMethodGenerator. Do not edit.
+final class VarHandleGuards {
+
+ @ForceInline
+ final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
+ MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);
+ if (mn == null) {
+ throw handle.unsupported();
+ }
+ return mn;
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2014, 2016, 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 static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+final class VarHandles {
+
+ static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
+ if (!f.isStatic()) {
+ long foffset = MethodHandleNatives.objectFieldOffset(f);
+ if (!type.isPrimitive()) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleObjects.FieldInstanceReadOnly(refc, foffset, type)
+ : new VarHandleObjects.FieldInstanceReadWrite(refc, foffset, type);
+ }
+ else if (type == boolean.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == byte.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == short.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == char.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleChars.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == int.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleInts.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleInts.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == long.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleLongs.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleLongs.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == float.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleFloats.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleFloats.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == double.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleDoubles.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ 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);
+
+ Object base = MethodHandleNatives.staticFieldBase(f);
+ long foffset = MethodHandleNatives.staticFieldOffset(f);
+ if (!type.isPrimitive()) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleObjects.FieldStaticReadOnly(base, foffset, type)
+ : new VarHandleObjects.FieldStaticReadWrite(base, foffset, type);
+ }
+ else if (type == boolean.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
+ : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == byte.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
+ : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == short.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
+ : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == char.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
+ : new VarHandleChars.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == int.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleInts.FieldStaticReadOnly(base, foffset)
+ : new VarHandleInts.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == long.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleLongs.FieldStaticReadOnly(base, foffset)
+ : new VarHandleLongs.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == float.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleFloats.FieldStaticReadOnly(base, foffset)
+ : new VarHandleFloats.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == double.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleDoubles.FieldStaticReadOnly(base, foffset)
+ : new VarHandleDoubles.FieldStaticReadWrite(base, foffset);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
+ if (!arrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + arrayClass);
+
+ Class<?> componentType = arrayClass.getComponentType();
+
+ int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
+ int ascale = UNSAFE.arrayIndexScale(arrayClass);
+ int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
+
+ if (!componentType.isPrimitive()) {
+ return new VarHandleObjects.Array(aoffset, ashift, arrayClass);
+ }
+ else if (componentType == boolean.class) {
+ return new VarHandleBooleans.Array(aoffset, ashift);
+ }
+ else if (componentType == byte.class) {
+ return new VarHandleBytes.Array(aoffset, ashift);
+ }
+ else if (componentType == short.class) {
+ return new VarHandleShorts.Array(aoffset, ashift);
+ }
+ else if (componentType == char.class) {
+ return new VarHandleChars.Array(aoffset, ashift);
+ }
+ else if (componentType == int.class) {
+ return new VarHandleInts.Array(aoffset, ashift);
+ }
+ else if (componentType == long.class) {
+ return new VarHandleLongs.Array(aoffset, ashift);
+ }
+ else if (componentType == float.class) {
+ return new VarHandleFloats.Array(aoffset, ashift);
+ }
+ else if (componentType == double.class) {
+ return new VarHandleDoubles.Array(aoffset, ashift);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static VarHandle byteArrayViewHandle(Class<?> viewArrayClass,
+ boolean be) {
+ if (!viewArrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + viewArrayClass);
+
+ Class<?> viewComponentType = viewArrayClass.getComponentType();
+
+ if (viewComponentType == long.class) {
+ return new VarHandleByteArrayAsLongs.ArrayHandle(be);
+ }
+ else if (viewComponentType == int.class) {
+ return new VarHandleByteArrayAsInts.ArrayHandle(be);
+ }
+ else if (viewComponentType == short.class) {
+ return new VarHandleByteArrayAsShorts.ArrayHandle(be);
+ }
+ else if (viewComponentType == char.class) {
+ return new VarHandleByteArrayAsChars.ArrayHandle(be);
+ }
+ else if (viewComponentType == double.class) {
+ return new VarHandleByteArrayAsDoubles.ArrayHandle(be);
+ }
+ else if (viewComponentType == float.class) {
+ return new VarHandleByteArrayAsFloats.ArrayHandle(be);
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
+ static VarHandle makeByteBufferViewHandle(Class<?> viewArrayClass,
+ boolean be) {
+ if (!viewArrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + viewArrayClass);
+
+ Class<?> viewComponentType = viewArrayClass.getComponentType();
+
+ if (viewComponentType == long.class) {
+ return new VarHandleByteArrayAsLongs.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == int.class) {
+ return new VarHandleByteArrayAsInts.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == short.class) {
+ return new VarHandleByteArrayAsShorts.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == char.class) {
+ return new VarHandleByteArrayAsChars.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == double.class) {
+ return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == float.class) {
+ return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
+// /**
+// * A helper program to generate the VarHandleGuards class with a set of
+// * static guard methods each of which corresponds to a particular shape and
+// * performs a type check of the symbolic type descriptor with the VarHandle
+// * type descriptor before linking/invoking to the underlying operation as
+// * characterized by the operation member name on the VarForm of the
+// * VarHandle.
+// * <p>
+// * The generated class essentially encapsulates pre-compiled LambdaForms,
+// * one for each method, for the most set of common method signatures.
+// * This reduces static initialization costs, footprint costs, and circular
+// * dependencies that may arise if a class is generated per LambdaForm.
+// * <p>
+// * A maximum of L*T*S methods will be generated where L is the number of
+// * access modes kinds (or unique operation signatures) and T is the number
+// * of variable types and S is the number of shapes (such as instance field,
+// * static field, or array access).
+// * If there are 4 unique operation signatures, 5 basic types (Object, int,
+// * long, float, double), and 3 shapes then a maximum of 60 methods will be
+// * generated. However, the number is likely to be less since there
+// * be duplicate signatures.
+// * <p>
+// * Each method is annotated with @LambdaForm.Compiled to inform the runtime
+// * that such methods should be treated as if a method of a class that is the
+// * result of compiling a LambdaForm. Annotation of such methods is
+// * important for correct evaluation of certain assertions and method return
+// * type profiling in HotSpot.
+// */
+// public static class GuardMethodGenerator {
+//
+// static final String GUARD_METHOD_SIG_TEMPLATE = "<RETURN> <NAME>_<SIGNATURE>(<PARAMS>)";
+//
+// static final String GUARD_METHOD_TEMPLATE =
+// "@ForceInline\n" +
+// "@LambdaForm.Compiled\n" +
+// "final static <METHOD> throws Throwable {\n" +
+// " MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" +
+// " MethodType symbolic = ad.symbolicMethodType;\n" +
+// " if (target == symbolic) {\n" +
+// " <RETURN>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
+// " }\n" +
+// " else if (target.erase() == symbolic.erase()) {\n" +
+// " <RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>\n" +
+// " }\n" +
+// " else {\n" +
+// " MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" +
+// " <RETURN>vh_invoker.invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+// " }\n" +
+// "}";
+//
+// static final String GET_MEMBER_NAME_METHOD =
+// "@ForceInline\n" +
+// "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" +
+// " MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" +
+// " if (mn == null) {\n" +
+// " throw handle.unsupported();\n" +
+// " }\n" +
+// " return mn;\n" +
+// "}";
+//
+// // A template for deriving the operations
+// // could be supported by annotating VarHandle directly with the
+// // operation kind and shape
+// interface VarHandleTemplate {
+// Object get();
+//
+// void set(Object value);
+//
+// boolean compareAndSwap(Object actualValue, Object expectedValue);
+//
+// Object compareAndExchange(Object actualValue, Object expectedValue);
+//
+// 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;
+// }
+// }
+//
+// /**
+// * @param args parameters
+// */
+// public static void main(String[] args) {
+// System.out.println("package java.lang.invoke;");
+// System.out.println();
+// System.out.println("import jdk.internal.vm.annotation.ForceInline;");
+// System.out.println();
+// System.out.println("// This class is auto-generated by " +
+// GuardMethodGenerator.class.getName() +
+// ". Do not edit.");
+// System.out.println("final class VarHandleGuards {");
+//
+// System.out.println();
+// System.out.println(GET_MEMBER_NAME_METHOD);
+// System.out.println();
+//
+// // Declare the stream of shapes
+// Stream<HandleType> hts = Stream.of(
+// // Object->Object
+// new HandleType(Object.class, Object.class),
+// // Object->int
+// new HandleType(Object.class, int.class),
+// // Object->long
+// new HandleType(Object.class, long.class),
+// // Object->float
+// new HandleType(Object.class, float.class),
+// // Object->double
+// new HandleType(Object.class, double.class),
+//
+// // <static>->Object
+// new HandleType(null, Object.class),
+// // <static>->int
+// new HandleType(null, int.class),
+// // <static>->long
+// new HandleType(null, long.class),
+// // <static>->float
+// new HandleType(null, float.class),
+// // <static>->double
+// new HandleType(null, double.class),
+//
+// // Array[int]->Object
+// new HandleType(Object.class, Object.class, int.class),
+// // Array[int]->int
+// new HandleType(Object.class, int.class, int.class),
+// // Array[int]->long
+// new HandleType(Object.class, long.class, int.class),
+// // Array[int]->float
+// new HandleType(Object.class, float.class, int.class),
+// // Array[int]->double
+// new HandleType(Object.class, double.class, int.class),
+//
+// // Array[long]->int
+// new HandleType(Object.class, int.class, long.class),
+// // Array[long]->long
+// new HandleType(Object.class, long.class, long.class)
+// );
+//
+// hts.flatMap(ht -> Stream.of(VarHandleTemplate.class.getMethods()).
+// map(m -> generateMethodType(m, ht.receiver, ht.value, ht.intermediates))).
+// distinct().
+// map(mt -> generateMethod(mt)).
+// forEach(s -> {
+// System.out.println(s);
+// System.out.println();
+// });
+//
+// System.out.println("}");
+// }
+//
+// static MethodType generateMethodType(Method m, Class<?> receiver, Class<?> value, Class<?>... intermediates) {
+// Class<?> returnType = m.getReturnType() == Object.class
+// ? value : m.getReturnType();
+//
+// 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()) {
+// params.add(value);
+// }
+// return MethodType.methodType(returnType, params);
+// }
+//
+// static String generateMethod(MethodType mt) {
+// Class<?> returnType = mt.returnType();
+//
+// LinkedHashMap<String, Class<?>> params = new LinkedHashMap<>();
+// params.put("handle", VarHandle.class);
+// for (int i = 0; i < mt.parameterCount(); i++) {
+// params.put("arg" + i, mt.parameterType(i));
+// }
+// params.put("ad", VarHandle.AccessDescriptor.class);
+//
+// // Generate method signature line
+// String RETURN = className(returnType);
+// String NAME = "guard";
+// String SIGNATURE = getSignature(mt);
+// String PARAMS = params.entrySet().stream().
+// map(e -> className(e.getValue()) + " " + e.getKey()).
+// collect(joining(", "));
+// String METHOD = GUARD_METHOD_SIG_TEMPLATE.
+// replace("<RETURN>", RETURN).
+// replace("<NAME>", NAME).
+// replace("<SIGNATURE>", SIGNATURE).
+// replace("<PARAMS>", PARAMS);
+//
+// // Generate method
+// params.remove("ad");
+//
+// List<String> LINK_TO_STATIC_ARGS = params.keySet().stream().
+// collect(toList());
+// LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)");
+//
+// List<String> LINK_TO_INVOKER_ARGS = params.keySet().stream().
+// collect(toList());
+//
+// RETURN = returnType == void.class
+// ? ""
+// : returnType == Object.class
+// ? "return "
+// : "return (" + returnType.getName() + ") ";
+//
+// String RESULT_ERASED = returnType == void.class
+// ? ""
+// : returnType != Object.class
+// ? "return (" + returnType.getName() + ") "
+// : "Object r = ";
+//
+// String RETURN_ERASED = returnType != Object.class
+// ? ""
+// : " return symbolic.returnType().cast(r);";
+//
+// return GUARD_METHOD_TEMPLATE.
+// replace("<METHOD>", METHOD).
+// replace("<NAME>", NAME).
+// 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(", ")))
+// ;
+// }
+//
+// static String className(Class<?> c) {
+// String n = c.getName();
+// if (n.startsWith("java.lang.")) {
+// n = n.replace("java.lang.", "");
+// if (n.startsWith("invoke.")) {
+// n = n.replace("invoke.", "");
+// }
+// }
+// return n.replace('$', '.');
+// }
+//
+// static String getSignature(MethodType m) {
+// StringBuilder sb = new StringBuilder(m.parameterCount() + 1);
+//
+// for (int i = 0; i < m.parameterCount(); i++) {
+// Class<?> pt = m.parameterType(i);
+// sb.append(getCharType(pt));
+// }
+//
+// sb.append('_').append(getCharType(m.returnType()));
+//
+// return sb.toString();
+// }
+//
+// 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());
+// }
+// }
+// }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.util.Objects;
+import jdk.internal.vm.annotation.ForceInline;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+#warn
+
+final class VarHandle$Type$s {
+
+ static class FieldInstanceReadOnly extends VarHandle {
+ final long fieldOffset;
+ final Class<?> receiverType;
+#if[Object]
+ final Class<?> fieldType;
+#end[Object]
+
+ FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class);
+ }
+
+ protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
+ Class<? extends FieldInstanceReadOnly> handle) {
+ super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class});
+ this.fieldOffset = fieldOffset;
+ this.receiverType = receiverType;
+#if[Object]
+ this.fieldType = fieldType;
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getVolatile(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getOpaque(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getAcquire(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+ }
+
+ static class FieldInstanceReadWrite extends FieldInstanceReadOnly {
+
+ FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class);
+ }
+
+ @ForceInline
+ static void set(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setVolatile(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setOpaque(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setRelease(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static class FieldStaticReadOnly extends VarHandle {
+ final Object base;
+ final long fieldOffset;
+#if[Object]
+ final Class<?> fieldType;
+#end[Object]
+
+ FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class);
+ }
+
+ protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
+ Class<? extends FieldStaticReadOnly> handle) {
+ super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class});
+ this.base = base;
+ this.fieldOffset = fieldOffset;
+#if[Object]
+ this.fieldType = fieldType;
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getVolatile(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Volatile(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getOpaque(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Opaque(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getAcquire(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Acquire(handle.base,
+ handle.fieldOffset);
+ }
+ }
+
+ static class FieldStaticReadWrite extends FieldStaticReadOnly {
+
+ FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class);
+ }
+
+ @ForceInline
+ static void set(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setVolatile(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Volatile(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setOpaque(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Opaque(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setRelease(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndSwap$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Volatile(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndSet$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(handle.base,
+ handle.fieldOffset,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(handle.base,
+ handle.fieldOffset,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static final class Array extends VarHandle {
+ final int abase;
+ final int ashift;
+#if[Object]
+ final Class<{#if[Object]??:$type$[]}> arrayType;
+ final Class<?> componentType;
+#end[Object]
+
+ Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
+ super(VarForm.createFromStatic(Array.class),
+ {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+ this.abase = abase;
+ this.ashift = ashift;
+#if[Object]
+ this.arrayType = {#if[Object]?arrayType:$type$[].class};
+ this.componentType = arrayType.getComponentType();
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return array[index];
+ }
+
+ @ForceInline
+ static void set(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ array[index] = {#if[Object]?handle.componentType.cast(value):value};
+ }
+
+ @ForceInline
+ static $type$ getVolatile(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setVolatile(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getOpaque(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Opaque(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setOpaque(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Opaque(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAcquire(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setRelease(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndSwap$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndSet$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndAdd$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndAdd$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2015, 2016, 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.misc.Unsafe;
+import jdk.internal.vm.annotation.ForceInline;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.Objects;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+#warn
+
+final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
+
+ static final int ALIGN = $BoxType$.BYTES - 1;
+
+#if[floatingPoint]
+ @ForceInline
+ static $rawType$ convEndian(boolean big, $type$ v) {
+ $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v);
+ return big == BE ? rv : $RawBoxType$.reverseBytes(rv);
+ }
+
+ @ForceInline
+ static $type$ convEndian(boolean big, $rawType$ rv) {
+ rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv);
+ return $Type$.$rawType$BitsTo$Type$(rv);
+ }
+#else[floatingPoint]
+ @ForceInline
+ static $type$ convEndian(boolean big, $type$ n) {
+ return big == BE ? n : $BoxType$.reverseBytes(n);
+ }
+#end[floatingPoint]
+
+
+ private static class ByteArrayViewVarHandle extends VarHandle {
+ final boolean be;
+
+ ByteArrayViewVarHandle(Class<? extends ByteArrayViewVarHandle> implSubType,
+ Class<?> arrayType, Class<?> component, boolean be) {
+ super(VarForm.createFromStatic(implSubType),
+ arrayType, component, int.class);
+ this.be = be;
+ }
+ }
+
+ static final class ArrayHandle extends ByteArrayViewVarHandle {
+
+ ArrayHandle(boolean be) {
+ super(ArrayHandle.class, byte[].class, $type$.class, be);
+ }
+
+ @ForceInline
+ static int index(byte[] ba, int index) {
+ return Objects.checkIndex(index, ba.length - ALIGN, null);
+ }
+
+ @ForceInline
+ static long address(byte[] ba, int index) {
+ long address = ((long) index) + Unsafe.ARRAY_BYTE_BASE_OFFSET;
+ if ((address & ALIGN) != 0)
+ throw newIllegalStateExceptionForMisalignedAccess(index);
+ return address;
+ }
+
+ @ForceInline
+ static $type$ get(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+#if[floatingPoint]
+ $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ handle.be);
+ return $Type$.$rawType$BitsTo$Type$(rawValue);
+#else[floatingPoint]
+ return UNSAFE.get$Type$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static void set(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+#if[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ $Type$.$type$ToRaw$RawType$Bits(value),
+ handle.be);
+#else[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ value,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static $type$ getVolatile(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setVolatile(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAcquire(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getOpaque(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Opaque(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setOpaque(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Opaque(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.compareAndSwap$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAndSet(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.getAndSet$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value)));
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ addAndGet(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be, UNSAFE.getAndAdd$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value))) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static final class ByteBufferHandle extends ByteArrayViewVarHandle {
+
+ ByteBufferHandle(boolean be) {
+ super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be);
+ }
+
+ @ForceInline
+ static int index(ByteBuffer bb, int index) {
+ return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ }
+
+ @ForceInline
+ static int indexRO(ByteBuffer bb, int index) {
+ if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY))
+ throw new ReadOnlyBufferException();
+ return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ }
+
+ @ForceInline
+ static long address(ByteBuffer bb, int index) {
+ long address = ((long) index) + UNSAFE.getLong(bb, BUFFER_ADDRESS);
+ if ((address & ALIGN) != 0)
+ throw newIllegalStateExceptionForMisalignedAccess(index);
+ return address;
+ }
+
+ @ForceInline
+ static $type$ get(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+#if[floatingPoint]
+ $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ handle.be);
+ return $Type$.$rawType$BitsTo$Type$(rawValue);
+#else[floatingPoint]
+ return UNSAFE.get$Type$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static void set(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+#if[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ $Type$.$type$ToRaw$RawType$Bits(value),
+ handle.be);
+#else[floatingPoint]
+ UNSAFE.put$Type$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ value,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static $type$ getVolatile(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setVolatile(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAcquire(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getOpaque(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Opaque(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setOpaque(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Opaque(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.compareAndSwap$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAndSet(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndSet$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value)));
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ addAndGet(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value))) + value;
+ }
+#end[AtomicAdd]
+ }
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Thu Mar 24 11:21:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Thu Mar 24 11:21:21 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -32,7 +32,8 @@
* certain types in this package have special relations to dynamic
* language support in the virtual machine:
* <ul>
- * <li>The class {@link java.lang.invoke.MethodHandle MethodHandle} contains
+ * <li>The classes {@link java.lang.invoke.MethodHandle MethodHandle}
+ * {@link java.lang.invoke.VarHandle VarHandle} contain
* <a href="MethodHandle.html#sigpoly">signature polymorphic methods</a>
* which can be linked regardless of their type descriptor.
* Normally, method linkage requires exact matching of type descriptors.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Function;
+
+public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest {
+
+ enum MemoryMode {
+ ALIGNED(0, false), UNALIGNED(0, true),
+ BIG_ENDIAN(1, false), LITTLE_ENDIAN(1, true),
+ READ_WRITE(2, false), READ_ONLY(2, true),;
+
+ final int bit;
+ final int value;
+
+ MemoryMode(int bit, boolean value) {
+ this.bit = bit;
+ this.value = value ? 1 << bit : 0;
+ }
+
+ boolean isSet(int bitSet) {
+ return (bitSet & (1 << bit)) == value;
+ }
+
+ static int bitSet(MemoryMode... modes) {
+ if (modes == null) return 0;
+
+ int set = 0;
+ for (MemoryMode m : modes) {
+ set = (set & ~(1 << m.bit)) | m.value;
+ }
+ return set;
+ }
+
+ static EnumSet<MemoryMode> enumSet(int bitSet) {
+ EnumSet<MemoryMode> es = EnumSet.noneOf(MemoryMode.class);
+ for (MemoryMode m : values()) {
+ if (m.isSet(bitSet)) {
+ es.add(m);
+ }
+ }
+ return es;
+ }
+ }
+
+ static class Source<T> {
+ final T s;
+ final int memoryModes;
+
+ public Source(T s, MemoryMode... modes) {
+ this.s = s;
+ memoryModes = MemoryMode.bitSet(modes);
+ }
+
+ @Override
+ public String toString() {
+ return s.getClass().getCanonicalName() + " " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static abstract class ByteArrayViewSource<T> extends Source<T> {
+ public ByteArrayViewSource(T t, MemoryMode... modes) {
+ super(t, modes);
+ }
+
+ abstract void fill(byte value);
+
+ abstract void fill(byte[] values);
+ }
+
+ static class ByteArraySource extends ByteArrayViewSource<byte[]> {
+ public ByteArraySource(byte[] bytes, MemoryMode... modes) {
+ super(bytes, modes);
+ }
+
+ void fill(byte value) {
+ Arrays.fill(s, value);
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < s.length; i++) {
+ s[i] = values[i % values.length];
+ }
+ }
+ }
+
+ static class ByteBufferSource extends ByteArrayViewSource<ByteBuffer> {
+ public ByteBufferSource(ByteBuffer buffer, MemoryMode... modes) {
+ super(buffer, modes);
+ }
+
+ void fill(byte value) {
+ for (int i = 0; i < s.limit(); i++) {
+ s.put(i, value);
+ }
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < s.limit(); i++) {
+ s.put(i, values[i % values.length]);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return s + " " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static class ByteBufferReadOnlySource extends ByteBufferSource {
+ final ByteBuffer rwSource;
+
+ public ByteBufferReadOnlySource(ByteBuffer roBuffer, ByteBuffer rwSource, MemoryMode... modes) {
+ super(roBuffer, modes);
+ this.rwSource = rwSource;
+ }
+
+ void fill(byte value) {
+ for (int i = 0; i < rwSource.limit(); i++) {
+ rwSource.put(i, value);
+ }
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < rwSource.limit(); i++) {
+ rwSource.put(i, values[i % values.length]);
+ }
+ }
+ }
+
+ static class VarHandleSource extends Source<VarHandle> {
+ VarHandleSource(VarHandle vh, MemoryMode... modes) {
+ super(vh, modes);
+ }
+
+ boolean matches(ByteArrayViewSource<?> bav) {
+ return s.coordinateTypes().get(0).isAssignableFrom(bav.s.getClass());
+ }
+
+ @Override
+ public String toString() {
+ return " VarHandle " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static class VarHandleSourceAccessTestCase extends AccessTestCase<VarHandleSource> {
+ final ByteArrayViewSource<?> bs;
+ final VarHandleSource vhs;
+
+ VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource<?> bs, VarHandleSource vhs, AccessTestAction<VarHandleSource> ata) {
+ this(desc, bs, vhs, ata, true);
+ }
+
+ VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource<?> bs, VarHandleSource vhs, AccessTestAction<VarHandleSource> ata, boolean loop) {
+ super(vhs + " -> " + bs + " " + desc, ata, loop);
+ this.bs = bs;
+ this.vhs = vhs;
+ }
+
+ @Override
+ VarHandleSource get() {
+ return vhs;
+ }
+ }
+
+
+ static double rotateLeft(double i, int distance) {
+ return Double.longBitsToDouble(
+ Long.rotateLeft(Double.doubleToRawLongBits(i), distance));
+ }
+
+ static double rotateRight(double i, int distance) {
+ return Double.longBitsToDouble(
+ Long.rotateRight(Double.doubleToRawLongBits(i), distance));
+ }
+
+ static float rotateLeft(float i, int distance) {
+ return Float.intBitsToFloat(
+ Integer.rotateLeft(Float.floatToRawIntBits(i), distance));
+ }
+
+ static float rotateRight(float i, int distance) {
+ return Float.intBitsToFloat(
+ Integer.rotateRight(Float.floatToRawIntBits(i), distance));
+ }
+
+ static long rotateLeft(long i, int distance) {
+ return Long.rotateLeft(i, distance);
+ }
+
+ static long rotateRight(long i, int distance) {
+ return Long.rotateRight(i, distance);
+ }
+
+ static int rotateLeft(int i, int distance) {
+ return Integer.rotateLeft(i, distance);
+ }
+
+ static int rotateRight(int i, int distance) {
+ return Integer.rotateRight(i, distance);
+ }
+
+ static short rotateLeft(short i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateLeft(v, distance);
+ return (short) v;
+ }
+
+ static short rotateRight(short i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateRight(v, distance);
+ return (short) v;
+ }
+
+ static char rotateLeft(char i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateLeft(v, distance);
+ return (char) v;
+ }
+
+ static char rotateRight(char i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateRight(v, distance);
+ return (char) v;
+ }
+
+ static final int LENGTH_BYTES = 32;
+
+ byte[] array;
+
+ List<ByteArrayViewSource<?>> bavss;
+
+ List<VarHandleSource> vhss;
+
+ public void setupByteSources() {
+ array = new byte[LENGTH_BYTES];
+
+ // Native endianess
+ MemoryMode ne = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN
+ ? MemoryMode.BIG_ENDIAN : MemoryMode.LITTLE_ENDIAN;
+
+ bavss = new ArrayList<>();
+
+ // byte[] source
+ ByteArraySource a =
+ new ByteArraySource(array,
+ ne, MemoryMode.READ_WRITE);
+ bavss.add(a);
+
+
+ // Combinations of ByteBuffer sources
+ ByteBufferSource hbb =
+ new ByteBufferSource(ByteBuffer.wrap(array),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb);
+ ByteBufferReadOnlySource hbb_ro =
+ new ByteBufferReadOnlySource(hbb.s.asReadOnlyBuffer(), hbb.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_ro);
+
+ ByteBufferSource hbb_offset_aligned =
+ new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4, array.length / 2).slice(),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb_offset_aligned);
+ ByteBufferReadOnlySource hbb_offset_aligned_ro =
+ new ByteBufferReadOnlySource(hbb_offset_aligned.s.asReadOnlyBuffer(), hbb_offset_aligned.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_offset_aligned_ro);
+
+ ByteBufferSource hbb_offset_unaligned =
+ new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4 - 1, array.length / 2).slice(),
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb_offset_unaligned);
+ ByteBufferReadOnlySource hbb_offset_unaligned_ro =
+ new ByteBufferReadOnlySource(hbb_offset_unaligned.s.asReadOnlyBuffer(), hbb_offset_unaligned.s,
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_offset_unaligned_ro);
+
+
+ ByteBufferSource dbb =
+ new ByteBufferSource(ByteBuffer.allocateDirect(array.length),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb);
+ ByteBufferReadOnlySource dbb_ro =
+ new ByteBufferReadOnlySource(dbb.s.asReadOnlyBuffer(), dbb.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_ro);
+
+ ByteBufferSource dbb_offset_aligned =
+ new ByteBufferSource(dbb.s.slice().position(array.length / 4).limit(array.length / 4 + array.length / 2).slice(),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb_offset_aligned);
+ ByteBufferReadOnlySource dbb_offset_aligned_ro =
+ new ByteBufferReadOnlySource(dbb_offset_aligned.s.asReadOnlyBuffer(), dbb_offset_aligned.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_offset_aligned_ro);
+
+ ByteBufferSource dbb_offset_unaligned =
+ new ByteBufferSource(dbb.s.slice().position(array.length / 4 - 1).limit(array.length / 4 - 1 + array.length / 2).slice(),
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb_offset_unaligned);
+ ByteBufferReadOnlySource dbb_offset_unaligned_ro =
+ new ByteBufferReadOnlySource(dbb_offset_unaligned.s.asReadOnlyBuffer(), dbb_offset_unaligned.s,
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_offset_unaligned_ro);
+ }
+
+ @BeforeClass
+ public void setup() {
+ setupByteSources();
+ setupVarHandleSources();
+ }
+
+ abstract void setupVarHandleSources();
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ return vhss.stream().map(cvh -> new Object[]{cvh}).toArray(Object[][]::new);
+ }
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<java.lang.Class<?>> aepts = Arrays.asList(byte[].class, int.class);
+ List<java.lang.Class<?>> bbpts = Arrays.asList(ByteBuffer.class, int.class);
+
+ Function<VarHandle, List<Class<?>>> vhToPts = vh ->
+ vh.coordinateTypes().get(0) == byte[].class ? aepts : bbpts;
+
+ return vhss.stream().map(vh -> new Object[]{vh.s, vhToPts.apply(vh.s)}).toArray(Object[][]::new);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.reflect.Method;
+import java.nio.ReadOnlyBufferException;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
+import static org.testng.Assert.*;
+
+abstract class VarHandleBaseTest {
+ static final int ITERS = Integer.getInteger("iters", 1);
+
+ interface ThrowingRunnable {
+ void run() throws Throwable;
+ }
+
+ static void checkUOE(ThrowingRunnable r) {
+ checkWithThrowable(UnsupportedOperationException.class, null, r);
+ }
+
+ static void checkUOE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(UnsupportedOperationException.class, message, r);
+ }
+
+ static void checkROBE(ThrowingRunnable r) {
+ checkWithThrowable(ReadOnlyBufferException.class, null, r);
+ }
+
+ static void checkROBE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(ReadOnlyBufferException.class, message, r);
+ }
+
+ static void checkIOOBE(ThrowingRunnable r) {
+ checkWithThrowable(IndexOutOfBoundsException.class, null, r);
+ }
+
+ static void checkIOOBE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IndexOutOfBoundsException.class, message, r);
+ }
+
+ static void checkISE(ThrowingRunnable r) {
+ checkWithThrowable(IllegalStateException.class, null, r);
+ }
+
+ static void checkISE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IllegalStateException.class, message, r);
+ }
+
+ static void checkIAE(ThrowingRunnable r) {
+ checkWithThrowable(IllegalAccessException.class, null, r);
+ }
+
+ static void checkIAE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IllegalAccessException.class, message, r);
+ }
+
+ static void checkWMTE(ThrowingRunnable r) {
+ checkWithThrowable(WrongMethodTypeException.class, null, r);
+ }
+
+ static void checkWMTE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(WrongMethodTypeException.class, message, r);
+ }
+
+ static void checkCCE(ThrowingRunnable r) {
+ checkWithThrowable(ClassCastException.class, null, r);
+ }
+
+ static void checkCCE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(ClassCastException.class, message, r);
+ }
+
+ static void checkNPE(ThrowingRunnable r) {
+ checkWithThrowable(NullPointerException.class, null, r);
+ }
+
+ static void checkNPE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(NullPointerException.class, message, r);
+ }
+
+ static void checkWithThrowable(Class<? extends Throwable> re,
+ Object message,
+ ThrowingRunnable r) {
+ Throwable _e = null;
+ try {
+ r.run();
+ }
+ catch (Throwable e) {
+ _e = e;
+ }
+ message = message == null ? "" : message + ". ";
+ assertNotNull(_e, String.format("%sNo throwable thrown. Expected %s", message, re));
+ assertTrue(re.isInstance(_e), String.format("%sIncorrect throwable thrown, %s. Expected %s", message, _e, re));
+ }
+
+
+ enum TestAccessType {
+ get,
+ set,
+ compareAndSet,
+ compareAndExchange,
+ getAndSet,
+ getAndAdd;
+ }
+
+ enum TestAccessMode {
+ get(TestAccessType.get),
+ set(TestAccessType.set),
+ getVolatile(TestAccessType.get),
+ setVolatile(TestAccessType.set),
+ getAcquire(TestAccessType.get),
+ setRelease(TestAccessType.set),
+ getOpaque(TestAccessType.get),
+ setOpaque(TestAccessType.set),
+ compareAndSet(TestAccessType.compareAndSet),
+ compareAndExchangeVolatile(TestAccessType.compareAndExchange),
+ compareAndExchangeAcquire(TestAccessType.compareAndExchange),
+ compareAndExchangeRelease(TestAccessType.compareAndExchange),
+ weakCompareAndSet(TestAccessType.compareAndSet),
+ weakCompareAndSetAcquire(TestAccessType.compareAndSet),
+ weakCompareAndSetRelease(TestAccessType.compareAndSet),
+ getAndSet(TestAccessType.getAndSet),
+ getAndAdd(TestAccessType.getAndAdd),
+ addAndGet(TestAccessType.getAndAdd),;
+
+ final TestAccessType at;
+ final boolean isPolyMorphicInReturnType;
+ final Class<?> returnType;
+
+ TestAccessMode(TestAccessType at) {
+ this.at = at;
+
+ try {
+ Method m = VarHandle.class.getMethod(name(), Object[].class);
+ this.returnType = m.getReturnType();
+ isPolyMorphicInReturnType = returnType != Object.class;
+ }
+ catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ boolean isOfType(TestAccessType at) {
+ return this.at == at;
+ }
+
+ VarHandle.AccessMode toAccessMode() {
+ return VarHandle.AccessMode.valueOf(name());
+ }
+ }
+
+ static List<TestAccessMode> testAccessModes() {
+ return Stream.of(TestAccessMode.values()).collect(toList());
+ }
+
+ static List<TestAccessMode> testAccessModesOfType(TestAccessType... ats) {
+ Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
+ for (TestAccessType at : ats) {
+ s = s.filter(e -> e.isOfType(at));
+ }
+ return s.collect(toList());
+ }
+
+ static List<VarHandle.AccessMode> accessModes() {
+ return Stream.of(VarHandle.AccessMode.values()).collect(toList());
+ }
+
+ static List<VarHandle.AccessMode> accessModesOfType(TestAccessType... ats) {
+ Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
+ for (TestAccessType at : ats) {
+ s = s.filter(e -> e.isOfType(at));
+ }
+ return s.map(TestAccessMode::toAccessMode).collect(toList());
+ }
+
+ static MethodHandle toMethodHandle(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ return vh.toMethodHandle(tam.toAccessMode());
+ }
+
+ static MethodHandle findVirtual(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh;
+ try {
+ mh = MethodHandles.publicLookup().
+ findVirtual(VarHandle.class,
+ tam.name(),
+ mt);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleInvokerWithSymbolicTypeDescriptor(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleExactInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ private static MethodHandle bind(VarHandle vh, TestAccessMode testAccessMode, MethodHandle mh, MethodType emt) {
+ assertEquals(mh.type(), emt.insertParameterTypes(0, VarHandle.class),
+ "MethodHandle type differs from access mode type");
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+ assertEquals(info.getMethodType(), emt,
+ "MethodHandleInfo method type differs from access mode type");
+
+ return mh.bindTo(vh);
+ }
+
+ private interface TriFunction<T, U, V, R> {
+ R apply(T t, U u, V v);
+ }
+
+ enum VarHandleToMethodHandle {
+ VAR_HANDLE_TO_METHOD_HANDLE(
+ "VarHandle.toMethodHandle",
+ VarHandleBaseTest::toMethodHandle),
+ METHOD_HANDLES_LOOKUP_FIND_VIRTUAL(
+ "Lookup.findVirtual",
+ VarHandleBaseTest::findVirtual),
+ METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_ACCESS_MODE_TYPE(
+ "MethodHandles.varHandleInvoker(accessModeType)",
+ VarHandleBaseTest::varHandleInvokerWithAccessModeType),
+ METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_SYMBOLIC_TYPE_DESCRIPTOR(
+ "MethodHandles.varHandleInvoker(symbolicTypeDescriptor)",
+ VarHandleBaseTest::varHandleInvokerWithSymbolicTypeDescriptor),
+ METHOD_HANDLES_VAR_HANDLE_EXACT_INVOKER_WITH_ACCESS_MODE_TYPE(
+ "MethodHandles.varHandleExactInvoker(accessModeType)",
+ VarHandleBaseTest::varHandleExactInvokerWithAccessModeType);
+
+ final String desc;
+ final TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f;
+ final boolean exact;
+
+ VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f) {
+ this(desc, f, false);
+ }
+
+ VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f,
+ boolean exact) {
+ this.desc = desc;
+ this.f = f;
+ this.exact = exact;
+ }
+
+ MethodHandle apply(VarHandle vh, TestAccessMode am, MethodType mt) {
+ return f.apply(vh, am, mt);
+ }
+
+ @Override
+ public String toString() {
+ return desc;
+ }
+ }
+
+ static class Handles {
+ static class AccessModeAndType {
+ final TestAccessMode tam;
+ final MethodType t;
+
+ public AccessModeAndType(TestAccessMode tam, MethodType t) {
+ this.tam = tam;
+ this.t = t;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AccessModeAndType x = (AccessModeAndType) o;
+
+ if (tam != x.tam) return false;
+ if (t != null ? !t.equals(x.t) : x.t != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = tam != null ? tam.hashCode() : 0;
+ result = 31 * result + (t != null ? t.hashCode() : 0);
+ return result;
+ }
+ }
+
+ final VarHandle vh;
+ final VarHandleToMethodHandle f;
+ final EnumMap<TestAccessMode, MethodType> amToType;
+ final Map<AccessModeAndType, MethodHandle> amToHandle;
+
+ Handles(VarHandle vh, VarHandleToMethodHandle f) throws Exception {
+ this.vh = vh;
+ this.f = f;
+ this.amToHandle = new HashMap<>();
+
+ amToType = new EnumMap<>(TestAccessMode.class);
+ for (TestAccessMode am : testAccessModes()) {
+ amToType.put(am, vh.accessModeType(am.toAccessMode()));
+ }
+ }
+
+ MethodHandle get(TestAccessMode am) {
+ return get(am, amToType.get(am));
+ }
+
+ MethodHandle get(TestAccessMode am, MethodType mt) {
+ AccessModeAndType amt = new AccessModeAndType(am, mt);
+ return amToHandle.computeIfAbsent(
+ amt, k -> f.apply(vh, am, mt));
+ }
+ }
+
+ interface AccessTestAction<T> {
+ void action(T t) throws Throwable;
+ }
+
+ static abstract class AccessTestCase<T> {
+ final String desc;
+ final AccessTestAction<T> ata;
+ final boolean loop;
+
+ AccessTestCase(String desc, AccessTestAction<T> ata, boolean loop) {
+ this.desc = desc;
+ this.ata = ata;
+ this.loop = loop;
+ }
+
+ boolean requiresLoop() {
+ return loop;
+ }
+
+ abstract T get() throws Exception;
+
+ void testAccess(T t) throws Throwable {
+ ata.action(t);
+ }
+
+ @Override
+ public String toString() {
+ return desc;
+ }
+ }
+
+ static class VarHandleAccessTestCase extends AccessTestCase<VarHandle> {
+ final VarHandle vh;
+
+ VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction<VarHandle> ata) {
+ this(desc, vh, ata, true);
+ }
+
+ VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction<VarHandle> ata, boolean loop) {
+ super("VarHandle -> " + desc, ata, loop);
+ this.vh = vh;
+ }
+
+ @Override
+ VarHandle get() {
+ return vh;
+ }
+ }
+
+ static class MethodHandleAccessTestCase extends AccessTestCase<Handles> {
+ final VarHandle vh;
+ final VarHandleToMethodHandle f;
+
+ MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction<Handles> ata) {
+ this(desc, vh, f, ata, true);
+ }
+
+ MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction<Handles> ata, boolean loop) {
+ super("VarHandle -> " + f.toString() + " -> " + desc, ata, loop);
+ this.vh = vh;
+ this.f = f;
+ }
+
+ @Override
+ Handles get() throws Exception {
+ return new Handles(vh, f);
+ }
+ }
+
+ static void testTypes(VarHandle vh) {
+ List<Class<?>> pts = vh.coordinateTypes();
+
+ for (TestAccessMode accessMode : testAccessModes()) {
+ MethodType amt = vh.accessModeType(accessMode.toAccessMode());
+
+ assertEquals(amt.parameterList().subList(0, pts.size()), pts);
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.get)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterList(), pts);
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.set)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), void.class);
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), boolean.class);
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.getAndSet, TestAccessType.getAndAdd)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v;
+
+ final boolean final_v = true;
+
+ boolean v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessBoolean.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(boolean[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), boolean.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "final_v", boolean.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "v", boolean.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "static_final_v", boolean.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "static_v", boolean.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessBoolean::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessBoolean::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessBoolean::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessBoolean::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ // Plain
+ {
+ boolean x = (boolean) vh.get(recv);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ boolean x = (boolean) vh.getVolatile(recv);
+ assertEquals(x, true, "getVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ boolean x = (boolean) vh.getAcquire(recv);
+ assertEquals(x, true, "getRelease boolean value");
+ }
+
+ // Opaque
+ {
+ boolean x = (boolean) vh.getOpaque(recv);
+ assertEquals(x, true, "getOpaque boolean value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(recv, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(recv, true);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ boolean x = (boolean) vh.get();
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ boolean x = (boolean) vh.getVolatile();
+ assertEquals(x, true, "getVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ boolean x = (boolean) vh.getAcquire();
+ assertEquals(x, true, "getRelease boolean value");
+ }
+
+ // Opaque
+ {
+ boolean x = (boolean) vh.getOpaque();
+ assertEquals(x, true, "getOpaque boolean value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(false);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(false);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(false);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(true);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, true);
+ boolean x = (boolean) vh.get(recv);
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, false);
+ boolean x = (boolean) vh.getVolatile(recv);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, true);
+ boolean x = (boolean) vh.getAcquire(recv);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, false);
+ boolean x = (boolean) vh.getOpaque(recv);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(recv, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(recv, true);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(true);
+ boolean x = (boolean) vh.get();
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(false);
+ boolean x = (boolean) vh.getVolatile();
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(true);
+ boolean x = (boolean) vh.getAcquire();
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(false);
+ boolean x = (boolean) vh.getOpaque();
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(true);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ boolean[] array = new boolean[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, true);
+ boolean x = (boolean) vh.get(array, i);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, false);
+ boolean x = (boolean) vh.getVolatile(array, i);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, true);
+ boolean x = (boolean) vh.getAcquire(array, i);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, false);
+ boolean x = (boolean) vh.getOpaque(array, i);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ boolean[] array = new boolean[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(array, i, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(array, i, true);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, true);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v;
+
+ final byte final_v = (byte)1;
+
+ byte v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(byte[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), byte.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "final_v", byte.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "v", byte.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "static_final_v", byte.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "static_v", byte.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessByte::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessByte::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessByte::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessByte::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessByte recv, VarHandle vh) {
+ // Plain
+ {
+ byte x = (byte) vh.get(recv);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ byte x = (byte) vh.getVolatile(recv);
+ assertEquals(x, (byte)1, "getVolatile byte value");
+ }
+
+ // Lazy
+ {
+ byte x = (byte) vh.getAcquire(recv);
+ assertEquals(x, (byte)1, "getRelease byte value");
+ }
+
+ // Opaque
+ {
+ byte x = (byte) vh.getOpaque(recv);
+ assertEquals(x, (byte)1, "getOpaque byte value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(recv, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(recv, (byte)1);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ byte x = (byte) vh.get();
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ byte x = (byte) vh.getVolatile();
+ assertEquals(x, (byte)1, "getVolatile byte value");
+ }
+
+ // Lazy
+ {
+ byte x = (byte) vh.getAcquire();
+ assertEquals(x, (byte)1, "getRelease byte value");
+ }
+
+ // Opaque
+ {
+ byte x = (byte) vh.getOpaque();
+ assertEquals(x, (byte)1, "getOpaque byte value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque((byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd((byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet((byte)1);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessByte recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, (byte)1);
+ byte x = (byte) vh.get(recv);
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, (byte)2);
+ byte x = (byte) vh.getVolatile(recv);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, (byte)1);
+ byte x = (byte) vh.getAcquire(recv);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, (byte)2);
+ byte x = (byte) vh.getOpaque(recv);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(recv, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(recv, (byte)1);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set((byte)1);
+ byte x = (byte) vh.get();
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile((byte)2);
+ byte x = (byte) vh.getVolatile();
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease((byte)1);
+ byte x = (byte) vh.getAcquire();
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque((byte)2);
+ byte x = (byte) vh.getOpaque();
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd((byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet((byte)1);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ byte[] array = new byte[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, (byte)1);
+ byte x = (byte) vh.get(array, i);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, (byte)2);
+ byte x = (byte) vh.getVolatile(array, i);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, (byte)1);
+ byte x = (byte) vh.getAcquire(array, i);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, (byte)2);
+ byte x = (byte) vh.getOpaque(array, i);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ byte[] array = new byte[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(array, i, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(array, i, (byte)1);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, (byte)1);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v;
+
+ final char final_v = 'a';
+
+ char v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessChar.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(char[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), char.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "final_v", char.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "v", char.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "static_final_v", char.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "static_v", char.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessChar::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessChar::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessChar::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessChar::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessChar::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessChar recv, VarHandle vh) {
+ // Plain
+ {
+ char x = (char) vh.get(recv);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ char x = (char) vh.getVolatile(recv);
+ assertEquals(x, 'a', "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire(recv);
+ assertEquals(x, 'a', "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque(recv);
+ assertEquals(x, 'a', "getOpaque char value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(recv, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(recv, 'a');
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ char x = (char) vh.get();
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ char x = (char) vh.getVolatile();
+ assertEquals(x, 'a', "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire();
+ assertEquals(x, 'a', "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque();
+ assertEquals(x, 'a', "getOpaque char value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set('b');
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile('b');
+ });
+
+ checkUOE(() -> {
+ vh.setRelease('b');
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque('b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd('a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet('a');
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessChar recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 'a');
+ char x = (char) vh.get(recv);
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 'b');
+ char x = (char) vh.getVolatile(recv);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 'a');
+ char x = (char) vh.getAcquire(recv);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 'b');
+ char x = (char) vh.getOpaque(recv);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(recv, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(recv, 'a');
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set('a');
+ char x = (char) vh.get();
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile('b');
+ char x = (char) vh.getVolatile();
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease('a');
+ char x = (char) vh.getAcquire();
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque('b');
+ char x = (char) vh.getOpaque();
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd('a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet('a');
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ char[] array = new char[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 'a');
+ char x = (char) vh.get(array, i);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 'b');
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 'a');
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 'b');
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ char[] array = new char[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, i, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, i, 'a');
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 'a');
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v;
+
+ final double final_v = 1.0d;
+
+ double v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessDouble.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(double[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), double.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "final_v", double.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "v", double.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "static_final_v", double.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "static_v", double.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessDouble::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessDouble::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessDouble::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessDouble::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessDouble::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessDouble recv, VarHandle vh) {
+ // Plain
+ {
+ double x = (double) vh.get(recv);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ double x = (double) vh.getVolatile(recv);
+ assertEquals(x, 1.0d, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire(recv);
+ assertEquals(x, 1.0d, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque(recv);
+ assertEquals(x, 1.0d, "getOpaque double value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(recv, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(recv, 1.0d);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ double x = (double) vh.get();
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ double x = (double) vh.getVolatile();
+ assertEquals(x, 1.0d, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire();
+ assertEquals(x, 1.0d, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque();
+ assertEquals(x, 1.0d, "getOpaque double value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(1.0d);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessDouble recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1.0d);
+ double x = (double) vh.get(recv);
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2.0d);
+ double x = (double) vh.getVolatile(recv);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1.0d);
+ double x = (double) vh.getAcquire(recv);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2.0d);
+ double x = (double) vh.getOpaque(recv);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(recv, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(recv, 1.0d);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1.0d);
+ double x = (double) vh.get();
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2.0d);
+ double x = (double) vh.getVolatile();
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1.0d);
+ double x = (double) vh.getAcquire();
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2.0d);
+ double x = (double) vh.getOpaque();
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(1.0d);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ double[] array = new double[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1.0d);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2.0d);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1.0d);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2.0d);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ double[] array = new double[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, i, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, i, 1.0d);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1.0d);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v;
+
+ final float final_v = 1.0f;
+
+ float v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessFloat.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(float[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), float.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "final_v", float.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "v", float.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "static_final_v", float.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "static_v", float.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessFloat::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessFloat::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessFloat::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessFloat::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessFloat::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessFloat recv, VarHandle vh) {
+ // Plain
+ {
+ float x = (float) vh.get(recv);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ float x = (float) vh.getVolatile(recv);
+ assertEquals(x, 1.0f, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire(recv);
+ assertEquals(x, 1.0f, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque(recv);
+ assertEquals(x, 1.0f, "getOpaque float value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(recv, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(recv, 1.0f);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ float x = (float) vh.get();
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ float x = (float) vh.getVolatile();
+ assertEquals(x, 1.0f, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire();
+ assertEquals(x, 1.0f, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque();
+ assertEquals(x, 1.0f, "getOpaque float value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(1.0f);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessFloat recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1.0f);
+ float x = (float) vh.get(recv);
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2.0f);
+ float x = (float) vh.getVolatile(recv);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1.0f);
+ float x = (float) vh.getAcquire(recv);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2.0f);
+ float x = (float) vh.getOpaque(recv);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(recv, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(recv, 1.0f);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1.0f);
+ float x = (float) vh.get();
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2.0f);
+ float x = (float) vh.getVolatile();
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1.0f);
+ float x = (float) vh.getAcquire();
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2.0f);
+ float x = (float) vh.getOpaque();
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(1.0f);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ float[] array = new float[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1.0f);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2.0f);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1.0f);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2.0f);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ float[] array = new float[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, i, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, i, 1.0f);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1.0f);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v;
+
+ final int final_v = 1;
+
+ int v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessInt.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(int[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), int.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "final_v", int.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "v", int.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "static_final_v", int.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "static_v", int.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessInt::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessInt::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessInt::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessInt::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessInt::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessInt recv, VarHandle vh) {
+ // Plain
+ {
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ int x = (int) vh.getVolatile(recv);
+ assertEquals(x, 1, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire(recv);
+ assertEquals(x, 1, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque(recv);
+ assertEquals(x, 1, "getOpaque int value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2);
+ });
+
+
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ int x = (int) vh.get();
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ int x = (int) vh.getVolatile();
+ assertEquals(x, 1, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire();
+ assertEquals(x, 1, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque();
+ assertEquals(x, 1, "getOpaque int value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2);
+ });
+
+
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessInt recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1);
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2);
+ int x = (int) vh.getVolatile(recv);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1);
+ int x = (int) vh.getAcquire(recv);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2);
+ int x = (int) vh.getOpaque(recv);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(recv, 1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(recv, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(recv, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(recv, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(recv, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(recv, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(recv, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) {
+
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1);
+ int x = (int) vh.get();
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2);
+ int x = (int) vh.getVolatile();
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1);
+ int x = (int) vh.getAcquire();
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2);
+ int x = (int) vh.getOpaque();
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet(1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire(2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet( 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd( 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ }
+
+
+ static void testArray(VarHandle vh) {
+ int[] array = new int[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(array, i, 1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(array, i, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ int[] array = new int[10];
+
+ int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, 3);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, 3);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v;
+
+ final long final_v = 1L;
+
+ long v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessLong.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(long[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), long.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "final_v", long.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "v", long.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "static_final_v", long.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "static_v", long.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessLong::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessLong::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessLong::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessLong::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessLong::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessLong recv, VarHandle vh) {
+ // Plain
+ {
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ long x = (long) vh.getVolatile(recv);
+ assertEquals(x, 1L, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire(recv);
+ assertEquals(x, 1L, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque(recv);
+ assertEquals(x, 1L, "getOpaque long value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2L);
+ });
+
+
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ long x = (long) vh.getVolatile();
+ assertEquals(x, 1L, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire();
+ assertEquals(x, 1L, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque();
+ assertEquals(x, 1L, "getOpaque long value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2L);
+ });
+
+
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessLong recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1L);
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2L);
+ long x = (long) vh.getVolatile(recv);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1L);
+ long x = (long) vh.getAcquire(recv);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2L);
+ long x = (long) vh.getOpaque(recv);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(recv, 1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(recv, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(recv, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(recv, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(recv, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) {
+
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1L);
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2L);
+ long x = (long) vh.getVolatile();
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1L);
+ long x = (long) vh.getAcquire();
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2L);
+ long x = (long) vh.getOpaque();
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet(1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire(2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet( 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd( 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ }
+
+
+ static void testArray(VarHandle vh) {
+ long[] array = new long[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1L);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2L);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1L);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2L);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(array, i, 1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(array, i, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ long[] array = new long[10];
+
+ int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, 3L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, 3L);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v;
+
+ final short final_v = (short)1;
+
+ short v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessShort.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(short[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), short.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "final_v", short.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "v", short.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "static_final_v", short.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "static_v", short.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessShort::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessShort::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessShort::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessShort::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessShort::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessShort recv, VarHandle vh) {
+ // Plain
+ {
+ short x = (short) vh.get(recv);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ short x = (short) vh.getVolatile(recv);
+ assertEquals(x, (short)1, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire(recv);
+ assertEquals(x, (short)1, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque(recv);
+ assertEquals(x, (short)1, "getOpaque short value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(recv, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(recv, (short)1);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ short x = (short) vh.get();
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ short x = (short) vh.getVolatile();
+ assertEquals(x, (short)1, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire();
+ assertEquals(x, (short)1, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque();
+ assertEquals(x, (short)1, "getOpaque short value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque((short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd((short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet((short)1);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessShort recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, (short)1);
+ short x = (short) vh.get(recv);
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, (short)2);
+ short x = (short) vh.getVolatile(recv);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, (short)1);
+ short x = (short) vh.getAcquire(recv);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, (short)2);
+ short x = (short) vh.getOpaque(recv);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(recv, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(recv, (short)1);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set((short)1);
+ short x = (short) vh.get();
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile((short)2);
+ short x = (short) vh.getVolatile();
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease((short)1);
+ short x = (short) vh.getAcquire();
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque((short)2);
+ short x = (short) vh.getOpaque();
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd((short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet((short)1);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ short[] array = new short[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, (short)1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, (short)2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, (short)1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, (short)2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ short[] array = new short[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, i, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, i, (short)1);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, (short)1);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v;
+
+ final String final_v = "foo";
+
+ String v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessString.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(String[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), String.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "final_v", String.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "v", String.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "static_final_v", String.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "static_v", String.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessString::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessString::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessString::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessString::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessString::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessString::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessString::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessString recv, VarHandle vh) {
+ // Plain
+ {
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ String x = (String) vh.getVolatile(recv);
+ assertEquals(x, "foo", "getVolatile String value");
+ }
+
+ // Lazy
+ {
+ String x = (String) vh.getAcquire(recv);
+ assertEquals(x, "foo", "getRelease String value");
+ }
+
+ // Opaque
+ {
+ String x = (String) vh.getOpaque(recv);
+ assertEquals(x, "foo", "getOpaque String value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, "bar");
+ });
+
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(recv, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(recv, "foo");
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ String x = (String) vh.getVolatile();
+ assertEquals(x, "foo", "getVolatile String value");
+ }
+
+ // Lazy
+ {
+ String x = (String) vh.getAcquire();
+ assertEquals(x, "foo", "getRelease String value");
+ }
+
+ // Opaque
+ {
+ String x = (String) vh.getOpaque();
+ assertEquals(x, "foo", "getOpaque String value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setRelease("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque("bar");
+ });
+
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd("foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet("foo");
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessString recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, "foo");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, "bar");
+ String x = (String) vh.getVolatile(recv);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, "foo");
+ String x = (String) vh.getAcquire(recv);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, "bar");
+ String x = (String) vh.getOpaque(recv);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set(recv, "foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet(recv, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(recv, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(recv, "foo");
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set("foo");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile("bar");
+ String x = (String) vh.getVolatile();
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease("foo");
+ String x = (String) vh.getAcquire();
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque("bar");
+ String x = (String) vh.getOpaque();
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set("foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet("foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet("foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire("foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire("foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet("foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire("bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet( "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd("foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet("foo");
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ String[] array = new String[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, "foo");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, "bar");
+ String x = (String) vh.getVolatile(array, i);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, "foo");
+ String x = (String) vh.getAcquire(array, i);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, "bar");
+ String x = (String) vh.getOpaque(array, i);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set(array, i, "foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet(array, i, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ String[] array = new String[10];
+
+ int i = 0;
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(array, i, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(array, i, "foo");
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ String x = (String) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeVolatile(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeAcquire(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeRelease(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ String o = (String) vh.getAndSet(array, ci, "foo");
+ });
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Character.BYTES;
+
+ static final char VALUE_1 = (char)0x0102;
+
+ static final char VALUE_2 = (char)0x1112;
+
+ static final char VALUE_3 = (char)0x2122;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(char[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(char[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), char.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ char x = (char) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get char value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque char value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ char x = (char) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get char value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque char value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putChar(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ char x = (char) vh.get(array, i);
+ assertEquals(x, v, "get char value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque char value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Double.BYTES;
+
+ static final double VALUE_1 = 0x0102030405060708L;
+
+ static final double VALUE_2 = 0x1112131415161718L;
+
+ static final double VALUE_3 = 0x2122232425262728L;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(double[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(double[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), double.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get double value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque double value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet double value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
+ }
+
+ // Compare set and get
+ {
+ double o = (double) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet double value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get double value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque double value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet double value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
+ }
+
+ // Compare set and get
+ {
+ double o = (double) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet double value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putDouble(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ double x = (double) vh.get(array, i);
+ assertEquals(x, v, "get double value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque double value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Float.BYTES;
+
+ static final float VALUE_1 = 0x01020304;
+
+ static final float VALUE_2 = 0x11121314;
+
+ static final float VALUE_3 = 0x21222324;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(float[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(float[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), float.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get float value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque float value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet float value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
+ }
+
+ // Compare set and get
+ {
+ float o = (float) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet float value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get float value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque float value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet float value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
+ }
+
+ // Compare set and get
+ {
+ float o = (float) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet float value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putFloat(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ float x = (float) vh.get(array, i);
+ assertEquals(x, v, "get float value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque float value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,924 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Integer.BYTES;
+
+ static final int VALUE_1 = 0x01020304;
+
+ static final int VALUE_2 = 0x11121314;
+
+ static final int VALUE_3 = 0x21222324;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(int[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(int[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), int.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get int value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value");
+ }
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get int value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value");
+ }
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putInt(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ int v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ int x = (int) vh.get(array, i);
+ assertEquals(x, v, "get int value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque int value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,924 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Long.BYTES;
+
+ static final long VALUE_1 = 0x0102030405060708L;
+
+ static final long VALUE_2 = 0x1112131415161718L;
+
+ static final long VALUE_3 = 0x2122232425262728L;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(long[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(long[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), long.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get long value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
+ }
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get long value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
+ }
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putLong(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ long v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ long x = (long) vh.get(array, i);
+ assertEquals(x, v, "get long value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque long value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Short.BYTES;
+
+ static final short VALUE_1 = (short)0x0102;
+
+ static final short VALUE_2 = (short)0x1112;
+
+ static final short VALUE_3 = (short)0x2122;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(short[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(short[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), short.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get short value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque short value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get short value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque short value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putShort(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ short x = (short) vh.get(array, i);
+ assertEquals(x, v, "get short value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque short value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v;
+
+ final boolean final_v = true;
+
+ boolean v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean o = (boolean) hs.get(am).invokeExact(array, i, true);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ boolean x = (boolean) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, true);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v;
+
+ final byte final_v = (byte)1;
+
+ byte v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact((byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact((byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact((byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact((byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact((byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte o = (byte) hs.get(am).invokeExact(array, i, (byte)1);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ byte x = (byte) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, (byte)1);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v;
+
+ final char final_v = 'a';
+
+ char v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 'a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 'b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 'a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 'b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a');
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact('a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact('b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact('a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact('b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact('a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a');
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 'a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 'b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 'a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 'b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(array, i, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(array, i, 'a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char o = (char) hs.get(am).invokeExact(array, i, 'a');
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ char x = (char) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 'a');
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v;
+
+ final double final_v = 1.0d;
+
+ double v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(array, i, 1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double o = (double) hs.get(am).invokeExact(array, i, 1.0d);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ double x = (double) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1.0d);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v;
+
+ final float final_v = 1.0f;
+
+ float v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(array, i, 1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float o = (float) hs.get(am).invokeExact(array, i, 1.0f);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ float x = (float) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1.0f);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v;
+
+ final int final_v = 1;
+
+ int v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable {
+
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact( 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact( 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ final int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ int x = (int) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1, 2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ int r = (int) hs.get(am).invokeExact(array, ci, 2, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ int o = (int) hs.get(am).invokeExact(array, ci, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ int o = (int) hs.get(am).invokeExact(array, ci, 3);
+ });
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v;
+
+ final long final_v = 1L;
+
+ long v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable {
+
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact( 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact( 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ final int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ long x = (long) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1L, 2L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ long r = (long) hs.get(am).invokeExact(array, ci, 2L, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ long o = (long) hs.get(am).invokeExact(array, ci, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ long o = (long) hs.get(am).invokeExact(array, ci, 3L);
+ });
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v;
+
+ final short final_v = (short)1;
+
+ short v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, (short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, (short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, (short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, (short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact((short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact((short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact((short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact((short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact((short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, (short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, (short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(array, i, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(array, i, (short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short o = (short) hs.get(am).invokeExact(array, i, (short)1);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ short x = (short) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, (short)1);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v;
+
+ final String final_v = "foo";
+
+ String v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, "foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, "bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, "foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, "bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, "foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(recv, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String r = (String) hs.get(am).invokeExact(recv, "foo");
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact("foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact("bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact("foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact("bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact("foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact("foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact("bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact( "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String r = (String) hs.get(am).invokeExact("foo");
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, "foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, "bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, "foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, "bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, "foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ final int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String o = (String) hs.get(am).invokeExact(array, i, "foo");
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ String x = (String) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, "foo");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ String o = (String) hs.get(am).invokeExact(array, ci, "foo");
+ });
+ }
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeBoolean
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v = true;
+
+ final boolean final_v = true;
+
+ boolean v = true;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.get();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, true, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeBoolean.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, boolean.class)).
+ invoke(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, boolean.class)).
+ invoke(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, boolean.class)).
+ invoke(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, boolean.class, Class.class)).
+ invoke(recv, true, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(true, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, boolean.class, Class.class)).
+ invoke(true, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ boolean[] array = new boolean[10];
+ Arrays.fill(array, true);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.get();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, true, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+ Arrays.fill(array, true);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, boolean[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class, boolean[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, boolean.class)).
+ invoke(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, boolean.class)).
+ invoke(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, boolean.class)).
+ invoke(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, boolean[].class, Class.class, boolean.class)).
+ invoke(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, true, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeByte
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v = (byte)1;
+
+ final byte final_v = (byte)1;
+
+ byte v = (byte)1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeByte::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeByte::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.get();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, (byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, (byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, (byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, (byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) hs.get(am, methodType(byte.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) hs.get(am, methodType(byte.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeByte.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) hs.get(am, methodType(byte.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, byte.class)).
+ invoke(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, byte.class)).
+ invoke(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, byte.class)).
+ invoke(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, byte.class, Class.class)).
+ invoke(recv, (byte)1, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set((byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile((byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque((byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease((byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, byte.class, Class.class)).
+ invoke((byte)1, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ byte[] array = new byte[10];
+ Arrays.fill(array, (byte)1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.get();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, (byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+ Arrays.fill(array, (byte)1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) hs.get(am, methodType(byte.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) hs.get(am, methodType(byte.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, byte[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, byte[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) hs.get(am, methodType(byte.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, byte.class)).
+ invoke(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, byte.class)).
+ invoke(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, byte.class)).
+ invoke(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, byte[].class, Class.class, byte.class)).
+ invoke(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, (byte)1, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeChar
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v = 'a';
+
+ final char final_v = 'a';
+
+ char v = 'a';
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeChar::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeChar::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.get();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 'a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 'a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 'a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 'a', Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) hs.get(am, methodType(char.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) hs.get(am, methodType(char.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) hs.get(am, methodType(char.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeChar.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) hs.get(am, methodType(char.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, char.class)).
+ invoke(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, char.class)).
+ invoke(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, char.class)).
+ invoke(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, char.class, Class.class)).
+ invoke(recv, 'a', Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set('a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile('a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque('a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease('a', Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, char.class, Class.class)).
+ invoke('a', Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ char[] array = new char[10];
+ Arrays.fill(array, 'a');
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.get();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 'a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 'a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 'a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 'a', Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ char[] array = new char[10];
+ Arrays.fill(array, 'a');
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) hs.get(am, methodType(char.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) hs.get(am, methodType(char.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) hs.get(am, methodType(char.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) hs.get(am, methodType(char.class, char[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, char[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, char[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) hs.get(am, methodType(char.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(char.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, char.class)).
+ invoke(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, char.class)).
+ invoke(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, char.class)).
+ invoke(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, char[].class, Class.class, char.class)).
+ invoke(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, 'a', Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeDouble
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v = 1.0d;
+
+ final double final_v = 1.0d;
+
+ double v = 1.0d;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeDouble::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeDouble::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.get();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) hs.get(am, methodType(double.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) hs.get(am, methodType(double.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) hs.get(am, methodType(double.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) hs.get(am, methodType(double.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, double.class)).
+ invoke(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, double.class)).
+ invoke(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, double.class)).
+ invoke(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)).
+ invoke(recv, 1.0d, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, double.class, Class.class)).
+ invoke(1.0d, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ double[] array = new double[10];
+ Arrays.fill(array, 1.0d);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.get();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ double[] array = new double[10];
+ Arrays.fill(array, 1.0d);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) hs.get(am, methodType(double.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) hs.get(am, methodType(double.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) hs.get(am, methodType(double.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, double[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) hs.get(am, methodType(double.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, double.class)).
+ invoke(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, double.class)).
+ invoke(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, double.class)).
+ invoke(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, double[].class, Class.class, double.class)).
+ invoke(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, 1.0d, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeFloat
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v = 1.0f;
+
+ final float final_v = 1.0f;
+
+ float v = 1.0f;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeFloat::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeFloat::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.get();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) hs.get(am, methodType(float.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) hs.get(am, methodType(float.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) hs.get(am, methodType(float.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) hs.get(am, methodType(float.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, float.class)).
+ invoke(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, float.class)).
+ invoke(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, float.class)).
+ invoke(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)).
+ invoke(recv, 1.0f, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, float.class, Class.class)).
+ invoke(1.0f, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ float[] array = new float[10];
+ Arrays.fill(array, 1.0f);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.get();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ float[] array = new float[10];
+ Arrays.fill(array, 1.0f);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) hs.get(am, methodType(float.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) hs.get(am, methodType(float.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) hs.get(am, methodType(float.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, float[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) hs.get(am, methodType(float.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, float.class)).
+ invoke(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, float.class)).
+ invoke(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, float.class)).
+ invoke(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, float[].class, Class.class, float.class)).
+ invoke(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, 1.0f, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,2075 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeInt
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v = 1;
+
+ final int final_v = 1;
+
+ int v = 1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeInt::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeInt::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.get();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeVolatile(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeVolatile(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeAcquire(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeAcquire(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeRelease(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeRelease(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(recv, 1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAndSet(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.getAndSet(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(recv, 1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAndAdd(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAndAdd(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.getAndAdd(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(recv, 1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.addAndGet(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.addAndGet(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.addAndGet(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(recv, 1, Void.class);
+ });
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class)).
+ invoke(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)).
+ invoke(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , int.class, int.class)).
+ invoke(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)).
+ invoke(recv, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)).
+ invoke(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class , int.class, int.class)).
+ invoke(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class , int.class, int.class)).
+ invoke(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class , int.class, int.class)).
+ invoke(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)).
+ invoke(recv, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(1, Void.class);
+ });
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, Class.class)).
+ invoke(1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class, int.class)).
+ invoke(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)).
+ invoke(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, Class.class)).
+ invoke(1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class)).
+ invoke(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class)).
+ invoke(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ int[] array = new int[10];
+ Arrays.fill(array, 1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.get();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeVolatile(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeVolatile(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeAcquire(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeAcquire(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeRelease(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeRelease(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeRelease(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(array, 0, 1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAndSet(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAndSet(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ int x = (int) vh.getAndSet(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAndSet(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(array, 0, 1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAndAdd(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAndAdd(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getAndAdd(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAndAdd(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(array, 0, 1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.addAndGet(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.addAndGet(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.addAndGet(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.addAndGet(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(array, 0, 1, Void.class);
+ });
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ int[] array = new int[10];
+ Arrays.fill(array, 1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, int[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class, int.class)).
+ invoke(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class, int.class)).
+ invoke(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, Class.class, int.class)).
+ invoke(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, Class.class, int.class, int.class)).
+ invoke(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class, int.class)).
+ invoke(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class, int.class)).
+ invoke(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class, int.class)).
+ invoke(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class, int.class)).
+ invoke(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class, int.class)).
+ invoke(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class)).
+ invoke(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,2075 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeLong
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v = 1L;
+
+ final long final_v = 1L;
+
+ long v = 1L;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeLong::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeLong::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.get();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeVolatile(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeVolatile(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeAcquire(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeAcquire(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeRelease(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeRelease(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(recv, 1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAndSet(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.getAndSet(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(recv, 1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAndAdd(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAndAdd(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.getAndAdd(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(recv, 1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.addAndGet(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.addAndGet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.addAndGet(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(recv, 1L, Void.class);
+ });
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, long.class, long.class)).
+ invoke(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class, long.class)).
+ invoke(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)).
+ invoke(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , long.class, long.class)).
+ invoke(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)).
+ invoke(recv, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class, long.class)).
+ invoke(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class, long.class)).
+ invoke(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)).
+ invoke(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class , long.class, long.class)).
+ invoke(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class , long.class, long.class)).
+ invoke(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class , long.class, long.class)).
+ invoke(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)).
+ invoke(recv, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(1L, Void.class);
+ });
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class, Class.class)).
+ invoke(1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class, long.class)).
+ invoke(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class)).
+ invoke(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, long.class, Class.class)).
+ invoke(1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class)).
+ invoke(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)).
+ invoke(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class)).
+ invoke(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)).
+ invoke(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ long[] array = new long[10];
+ Arrays.fill(array, 1L);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.get();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeVolatile(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeVolatile(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeAcquire(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeAcquire(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeRelease(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeRelease(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeRelease(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAndSet(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAndSet(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ long x = (long) vh.getAndSet(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAndSet(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(array, 0, 1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAndAdd(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAndAdd(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getAndAdd(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAndAdd(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(array, 0, 1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.addAndGet(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.addAndGet(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.addAndGet(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.addAndGet(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(array, 0, 1L, Void.class);
+ });
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ long[] array = new long[10];
+ Arrays.fill(array, 1L);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, long[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, long.class, long.class)).
+ invoke(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, long.class, long.class)).
+ invoke(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, Class.class, long.class)).
+ invoke(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, long.class, long.class)).
+ invoke(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, Class.class, long.class, long.class)).
+ invoke(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class, Class.class)).
+ invoke(array, 0, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class, long.class)).
+ invoke(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class, long.class)).
+ invoke(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class, long.class)).
+ invoke(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class, long.class)).
+ invoke(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class, long.class)).
+ invoke(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class, long.class)).
+ invoke(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class)).
+ invoke(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, long.class, Class.class)).
+ invoke(array, 0, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeShort
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v = (short)1;
+
+ final short final_v = (short)1;
+
+ short v = (short)1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeShort::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeShort::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.get();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, (short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, (short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, (short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, (short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) hs.get(am, methodType(short.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) hs.get(am, methodType(short.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) hs.get(am, methodType(short.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeShort.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) hs.get(am, methodType(short.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, short.class)).
+ invoke(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, short.class)).
+ invoke(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, short.class)).
+ invoke(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, short.class, Class.class)).
+ invoke(recv, (short)1, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set((short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile((short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque((short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease((short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, short.class, Class.class)).
+ invoke((short)1, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ short[] array = new short[10];
+ Arrays.fill(array, (short)1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.get();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, (short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ short[] array = new short[10];
+ Arrays.fill(array, (short)1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) hs.get(am, methodType(short.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) hs.get(am, methodType(short.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) hs.get(am, methodType(short.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) hs.get(am, methodType(short.class, short[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, short[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, short[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) hs.get(am, methodType(short.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(short.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, short.class)).
+ invoke(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, short.class)).
+ invoke(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, short.class)).
+ invoke(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, short[].class, Class.class, short.class)).
+ invoke(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, (short)1, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,1811 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeString
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v = "foo";
+
+ final String final_v = "foo";
+
+ String v = "foo";
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeString::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeString::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.get(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.get();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, "foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, "foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, "foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, "foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeVolatile(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeVolatile(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeAcquire(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeAcquire(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeRelease(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeRelease(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease(recv, "foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getAndSet(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.getAndSet(0, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet(recv, "foo", Void.class);
+ });
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, String.class)).
+ invoke(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, String.class)).
+ invoke(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, String.class, String.class)).
+ invoke(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)).
+ invoke(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
+ invoke(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)).
+ invoke(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
+ invoke(recv, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, String.class, String.class)).
+ invoke(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)).
+ invoke(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
+ invoke(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)).
+ invoke(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
+ invoke(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
+ invoke(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
+ invoke(recv, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, String.class)).
+ invoke(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, String.class)).
+ invoke(0, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ }
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set("foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile("foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque("foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease("foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease("foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet("foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet("foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet("foo", Void.class);
+ });
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)).
+ invoke("foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)).
+ invoke("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)).
+ invoke("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)).
+ invoke("foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String.class)).
+ invoke("foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)).
+ invoke("foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ String[] array = new String[10];
+ Arrays.fill(array, "foo");
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.get();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, "foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, "foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, "foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, "foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeVolatile(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeVolatile(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeAcquire(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeAcquire(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeRelease(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeRelease(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeRelease(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getAndSet(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getAndSet(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ String x = (String) vh.getAndSet(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getAndSet(array, Void.class, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet(array, 0, "foo", Void.class);
+ });
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ String[] array = new String[10];
+ Arrays.fill(array, "foo");
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, String.class)).
+ invoke(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, String.class)).
+ invoke(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, String.class)).
+ invoke(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, String[].class, Class.class, String.class)).
+ invoke(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, String.class, String.class)).
+ invoke(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)).
+ invoke(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)).
+ invoke(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)).
+ invoke(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)).
+ invoke(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)).
+ invoke(array, 0, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class, String.class)).
+ invoke(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)).
+ invoke(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)).
+ invoke(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)).
+ invoke(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)).
+ invoke(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)).
+ invoke(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
+ invoke(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)).
+ invoke(array, 0, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class)).
+ invoke(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)).
+ invoke(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)).
+ invoke(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)).
+ invoke(array, Void.class, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)).
+ invoke(array, 0, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)).
+ invoke(array, 0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestReflection.java Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng VarHandleTestReflection
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.lang.reflect.Method;
+import java.util.stream.Stream;
+
+public class VarHandleTestReflection extends VarHandleBaseTest {
+ String string;
+
+ @DataProvider
+ public static Object[][] accessModesProvider() {
+ return Stream.of(VarHandle.AccessMode.values()).
+ map(am -> new Object[]{am}).
+ toArray(Object[][]::new);
+ }
+
+ static VarHandle handle() throws Exception {
+ return MethodHandles.lookup().
+ findVarHandle(VarHandleTestReflection.class, "string", String.class);
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void methodInvocation(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a Method
+
+ Method vhm = VarHandle.class.getMethod(accessMode.name(), Object[].class);
+ vhm.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = UnsupportedOperationException.class)
+ public void methodHandleInvoke(VarHandle.AccessMode accessMode) throws Throwable {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a MethodHandle
+
+ MethodHandle mh = MethodHandles.lookup().unreflect(
+ VarHandle.class.getMethod(accessMode.name(), Object[].class));
+ // Use invoke to avoid WrongMethodTypeException for
+ // non-signature-polymorphic return types
+ Object o = (Object) mh.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void methodInvocationFromMethodInfo(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a Method obtained from cracking
+ // a MethodHandle
+
+ MethodHandle mh = MethodHandles.lookup().unreflect(
+ VarHandle.class.getMethod(accessMode.name(), Object[].class));
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+ Method im = info.reflectAs(Method.class, MethodHandles.lookup());
+ im.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void reflectAsFromVarHandleInvoker(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ accessMode, v.accessModeType(accessMode));
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+
+ info.reflectAs(Method.class, MethodHandles.lookup());
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void reflectAsFromFindVirtual(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ MethodHandle mh = MethodHandles.publicLookup().findVirtual(
+ VarHandle.class, accessMode.name(), v.accessModeType(accessMode));
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+
+ info.reflectAs(Method.class, MethodHandles.lookup());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccess$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+#if[CAS]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#else[CAS]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#end[CAS]
+
+#if[AtomicAdd]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#else[AtomicAdd]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#end[AtomicAdd]
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList($type$[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), $type$.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "final_v", $type$.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "v", $type$.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "static_v", $type$.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccess$Type$::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccess$Type$::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccess$Type$::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccess$Type$::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ // Plain
+ {
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile(recv);
+ assertEquals(x, $value1$, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire(recv);
+ assertEquals(x, $value1$, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque(recv);
+ assertEquals(x, $value1$, "getOpaque $type$ value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, $value2$);
+ });
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(recv, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile();
+ assertEquals(x, $value1$, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire();
+ assertEquals(x, $value1$, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque();
+ assertEquals(x, $value1$, "getOpaque $type$ value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque($value2$);
+ });
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd($value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet($value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testInstanceField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, $value1$);
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, $value2$);
+ $type$ x = ($type$) vh.getVolatile(recv);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, $value1$);
+ $type$ x = ($type$) vh.getAcquire(recv);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, $value2$);
+ $type$ x = ($type$) vh.getOpaque(recv);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set(recv, $value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(recv, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(recv, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(recv, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(recv, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set($value1$);
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile($value2$);
+ $type$ x = ($type$) vh.getVolatile();
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease($value1$);
+ $type$ x = ($type$) vh.getAcquire();
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque($value2$);
+ $type$ x = ($type$) vh.getOpaque();
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set($value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet($value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet($value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire($value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet( $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set($value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd( $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet($value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd($value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet($value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testArray(VarHandle vh) {
+ $type$[] array = new $type$[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, $value1$);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, $value2$);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, $value1$);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, $value2$);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set(array, i, $value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ $type$[] array = new $type$[10];
+
+ int i = 0;
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, i, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, i, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, $value1$);
+ });
+
+#if[CAS]
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, $value1$);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, $value3$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, $value3$);
+ });
+#end[AtomicAdd]
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,1089 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
+ static final int SIZE = $BoxType$.BYTES;
+
+ static final $type$ VALUE_1 = $value1$;
+
+ static final $type$ VALUE_2 = $value2$;
+
+ static final $type$ VALUE_3 = $value3$;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle($type$[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle($type$[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+#if[CAS]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#else[CAS]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#end[CAS]
+
+#if[AtomicAdd]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#else[AtomicAdd]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#end[AtomicAdd]
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), $type$.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+#else[CAS]
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#else[AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ else {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+#if[CAS]
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+#if[CAS]
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get $type$ value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque $type$ value");
+ }
+#if[CAS]
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get $type$ value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque $type$ value");
+ }
+#if[CAS]
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.put$Type$(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, v, "get $type$ value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque $type$ value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccess$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(recv, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(recv, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact($value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact($value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact($value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact($value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact($value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact( $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact( $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact($value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact($value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ final int i = 0;
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ $type$ x = ($type$) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, $value1$);
+ });
+ }
+
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, ci, $value2$, $value1$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$);
+ });
+ }
+#end[AtomicAdd]
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,2099 @@
+/*
+ * Copyright (c) 2015, 2016 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodType$Type$
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodType$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v = $value1$;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v = $value1$;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodType$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodType$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodType$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodType$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodType$Type$::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodType$Type$::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.get(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.get();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, $value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, $value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, $value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, $value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeRelease(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAndSet(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.getAndSet(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet(recv, $value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAndAdd(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.getAndAdd(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd(recv, $value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.addAndGet(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.addAndGet(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet(recv, $value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, $type$.class, $type$.class)).
+ invoke(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class, $type$.class)).
+ invoke(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)).
+ invoke(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , $type$.class, $type$.class)).
+ invoke(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class, $type$.class)).
+ invoke(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class, $type$.class)).
+ invoke(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)).
+ invoke(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class , $type$.class, $type$.class)).
+ invoke(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)).
+ invoke(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)).
+ invoke(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set($value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile($value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque($value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease($value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet($value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd($value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet($value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, $type$.class, Class.class)).
+ invoke($value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class, $type$.class)).
+ invoke($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class, $type$.class)).
+ invoke($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, $type$.class, Class.class)).
+ invoke($value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)).
+ invoke($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)).
+ invoke($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)).
+ invoke($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)).
+ invoke($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ $type$[] array = new $type$[10];
+ Arrays.fill(array, $value1$);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.get();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, $value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeRelease(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAndSet(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ $type$ x = ($type$) vh.getAndSet(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAndSet(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet(array, 0, $value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAndAdd(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getAndAdd(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAndAdd(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd(array, 0, $value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.addAndGet(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.addAndGet(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.addAndGet(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet(array, 0, $value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+ Arrays.fill(array, $value1$);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, $type$.class, $type$.class)).
+ invoke(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, $type$.class, $type$.class)).
+ invoke(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, Class.class, $type$.class)).
+ invoke(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, $type$.class, $type$.class)).
+ invoke(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, Class.class, $type$.class, $type$.class)).
+ invoke(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class, $type$.class)).
+ invoke(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class, $type$.class)).
+ invoke(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class, $type$.class)).
+ invoke(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class, $type$.class)).
+ invoke(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class, $type$.class)).
+ invoke(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class, $type$.class)).
+ invoke(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class, $type$.class)).
+ invoke(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh Thu Mar 24 11:21:21 2016 +0100
@@ -0,0 +1,155 @@
+#!/bin/bash
+
+javac -d . ../../../../../make/src/classes/build/tools/spp/Spp.java
+
+SPP=build.tools.spp.Spp
+
+# Generates variable handle tests for objects and all primitive types
+# This is likely to be a temporary testing approach as it may be more
+# desirable to generate code using ASM which will allow more flexibility
+# in the kinds of tests that are generated.
+
+for type in boolean byte short char int long float double String
+do
+ Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
+ args="-K$type -Dtype=$type -DType=$Type"
+
+ case $type in
+ String|int|long)
+ args="$args -KCAS"
+ ;;
+ esac
+
+ case $type in
+ int|long)
+ args="$args -KAtomicAdd"
+ ;;
+ esac
+
+ wrong_primitive_type=boolean
+
+ case $type in
+ boolean)
+ value1=true
+ value2=false
+ value3=false
+ wrong_primitive_type=int
+ ;;
+ byte)
+ value1=(byte)1
+ value2=(byte)2
+ value3=(byte)3
+ ;;
+ short)
+ value1=(short)1
+ value2=(short)2
+ value3=(short)3
+ ;;
+ char)
+ value1=\'a\'
+ value2=\'b\'
+ value3=\'c\'
+ ;;
+ int)
+ value1=1
+ value2=2
+ value3=3
+ ;;
+ long)
+ value1=1L
+ value2=2L
+ value3=3L
+ ;;
+ float)
+ value1=1.0f
+ value2=2.0f
+ value3=3.0f
+ ;;
+ double)
+ value1=1.0d
+ value2=2.0d
+ value3=3.0d
+ ;;
+ String)
+ value1=\"foo\"
+ value2=\"bar\"
+ value3=\"baz\"
+ ;;
+ esac
+
+ args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3 -Dwrong_primitive_type=$wrong_primitive_type"
+
+ echo $args
+ java $SPP -nel $args < X-VarHandleTestAccess.java.template > VarHandleTestAccess${Type}.java
+ java $SPP -nel $args < X-VarHandleTestMethodHandleAccess.java.template > VarHandleTestMethodHandleAccess${Type}.java
+ java $SPP -nel $args < X-VarHandleTestMethodType.java.template > VarHandleTestMethodType${Type}.java
+done
+
+for type in short char int long float double
+do
+ Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
+ args="-K$type -Dtype=$type -DType=$Type"
+
+ BoxType=$Type
+ case $type in
+ char)
+ BoxType=Character
+ ;;
+ int)
+ BoxType=Integer
+ ;;
+ esac
+ args="$args -DBoxType=$BoxType"
+
+ case $type in
+ int|long|float|double)
+ args="$args -KCAS"
+ ;;
+ esac
+
+ case $type in
+ int|long)
+ args="$args -KAtomicAdd"
+ ;;
+ esac
+
+ case $type in
+ short)
+ value1=(short)0x0102
+ value2=(short)0x1112
+ value3=(short)0x2122
+ ;;
+ char)
+ value1=(char)0x0102
+ value2=(char)0x1112
+ value3=(char)0x2122
+ ;;
+ int)
+ value1=0x01020304
+ value2=0x11121314
+ value3=0x21222324
+ ;;
+ long)
+ value1=0x0102030405060708L
+ value2=0x1112131415161718L
+ value3=0x2122232425262728L
+ ;;
+ float)
+ value1=0x01020304
+ value2=0x11121314
+ value3=0x21222324
+ ;;
+ double)
+ value1=0x0102030405060708L
+ value2=0x1112131415161718L
+ value3=0x2122232425262728L
+ ;;
+ esac
+
+ args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3"
+
+ echo $args
+ java $SPP -nel $args < X-VarHandleTestByteArrayView.java.template > VarHandleTestByteArrayAs${Type}.java
+done
+
+rm -fr build