提交 9afe3461 编写于 作者: J jrose

7191102: nightly failures after JSR 292 lazy method handle update (round 3)

Reviewed-by: twisti, kvn
上级 5bf74720
......@@ -142,6 +142,11 @@ import com.sun.xml.internal.ws.org.objectweb.asm.Type;
*/
protected abstract SpeciesData speciesData();
@Override
final Object internalProperties() {
return "/BMH="+internalValues();
}
@Override
final Object internalValues() {
Object[] boundValues = new Object[speciesData().fieldCount()];
......
......@@ -108,8 +108,8 @@ class DirectMethodHandle extends MethodHandle {
}
@Override
String debugString() {
return "DMH["+member.toString()+"]="+super.debugString();
String internalProperties() {
return "/DMH="+member.toString();
}
//// Implementation methods.
......
......@@ -185,12 +185,17 @@ class InvokerBytecodeGenerator {
}
class CpPatch {
int index;
Object value;
CpPatch(int index, Object value) {
final int index;
final String placeholder;
final Object value;
CpPatch(int index, String placeholder, Object value) {
this.index = index;
this.placeholder = placeholder;
this.value = value;
}
public String toString() {
return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
}
}
Map<Object, CpPatch> cpPatches = new HashMap<>();
......@@ -205,7 +210,7 @@ class InvokerBytecodeGenerator {
}
// insert placeholder in CP and remember the patch
int index = cw.newConst((Object) cpPlaceholder); // TODO check if aready in the constant pool
cpPatches.put(cpPlaceholder, new CpPatch(index, arg));
cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
return cpPlaceholder;
}
......@@ -213,7 +218,9 @@ class InvokerBytecodeGenerator {
int size = getConstantPoolSize(classFile);
Object[] res = new Object[size];
for (CpPatch p : cpPatches.values()) {
res[p.index] = p.value;
if (p.index >= size)
throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
res[p.index] = p.value;
}
return res;
}
......
......@@ -74,8 +74,18 @@ class Invokers {
MethodHandle invoker = exactInvoker;
if (invoker != null) return invoker;
MethodType mtype = targetType;
LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_EX_INVOKER);
invoker = BoundMethodHandle.bindSingle(mtype.invokerType(), lform, mtype);
MethodType invokerType = mtype.invokerType();
LambdaForm lform;
final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) {
lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER);
invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
} else {
// At maximum arity, we cannot afford an extra mtype argument,
// so build a fully customized (non-cached) invoker form.
lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER);
invoker = SimpleMethodHandle.make(invokerType, lform);
}
assert(checkInvoker(invoker));
exactInvoker = invoker;
return invoker;
......@@ -85,9 +95,20 @@ class Invokers {
MethodHandle invoker = generalInvoker;
if (invoker != null) return invoker;
MethodType mtype = targetType;
prepareForGenericCall(mtype);
LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_GEN_INVOKER);
invoker = BoundMethodHandle.bindSingle(mtype.invokerType(), lform, mtype);
MethodType invokerType = mtype.invokerType();
LambdaForm lform;
final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED);
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) {
prepareForGenericCall(mtype);
lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER);
invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
} else {
// At maximum arity, we cannot afford an extra mtype argument,
// so build a fully customized (non-cached) invoker form.
lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER);
invoker = SimpleMethodHandle.make(invokerType, lform);
}
assert(checkInvoker(invoker));
generalInvoker = invoker;
return invoker;
......@@ -102,6 +123,7 @@ class Invokers {
}
static MemberName invokeBasicMethod(MethodType type) {
type = type.basicType();
String name = "invokeBasic";
try {
//Lookup.findVirtual(MethodHandle.class, name, type);
......@@ -135,9 +157,31 @@ class Invokers {
/*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
if (vaInvoker != null) return vaInvoker;
MethodHandle gInvoker = generalInvoker();
int spreadArgCount = targetType.parameterCount() - leadingArgCount;
vaInvoker = gInvoker.asSpreader(Object[].class, spreadArgCount);
MethodType spreadInvokerType = targetType
.replaceParameterTypes(leadingArgCount, targetType.parameterCount(), Object[].class);
if (targetType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
// Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
// where ginvoker.invoke(mh, a*) => mh.invoke(a*).
MethodHandle genInvoker = generalInvoker();
vaInvoker = genInvoker.asSpreader(Object[].class, spreadArgCount);
} else {
// Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
// Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
// where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
MethodHandle arrayInvoker = MethodHandles.exactInvoker(spreadInvokerType);
MethodHandle makeSpreader;
try {
makeSpreader = IMPL_LOOKUP
.findVirtual(MethodHandle.class, "asSpreader",
MethodType.methodType(MethodHandle.class, Class.class, int.class));
} catch (ReflectiveOperationException ex) {
throw new InternalError(ex);
}
makeSpreader = MethodHandles.insertArguments(makeSpreader, 1, Object[].class, spreadArgCount);
vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
}
assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
spreadInvokers[leadingArgCount] = vaInvoker;
return vaInvoker;
}
......@@ -171,7 +215,7 @@ class Invokers {
.findStatic(CallSite.class, "uninitializedCallSite",
MethodType.methodType(Empty.class));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
throw new InternalError(ex);
}
}
invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
......@@ -185,30 +229,39 @@ class Invokers {
return "Invokers"+targetType;
}
private static MethodType fixMethodType(Class<?> callerClass, Object type) {
if (type instanceof MethodType)
return (MethodType) type;
else
return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
}
static MemberName exactInvokerMethod(Class<?> callerClass, Object type, Object[] appendixResult) {
MethodType mtype = fixMethodType(callerClass, type);
LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_EX_LINKER);
appendixResult[0] = mtype;
static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) {
LambdaForm lform;
final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) {
lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER);
appendixResult[0] = mtype;
} else {
lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER);
}
return lform.vmentry;
}
static MemberName genericInvokerMethod(Class<?> callerClass, Object type, Object[] appendixResult) {
MethodType mtype = fixMethodType(callerClass, type);
LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_GEN_LINKER);
prepareForGenericCall(mtype);
appendixResult[0] = mtype;
static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) {
LambdaForm lform;
final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) {
lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER);
appendixResult[0] = mtype;
prepareForGenericCall(mtype);
} else {
lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER);
}
return lform.vmentry;
}
private static LambdaForm invokeForm(MethodType mtype, int which) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) {
boolean isCached;
if (!customized) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
isCached = true;
} else {
isCached = false; // maybe cache if mtype == mtype.basicType()
}
boolean isLinker, isGeneric;
String debugName;
switch (which) {
......@@ -218,27 +271,32 @@ class Invokers {
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
default: throw new InternalError();
}
LambdaForm lform = mtype.form().cachedLambdaForm(which);
if (lform != null) return lform;
LambdaForm lform;
if (isCached) {
lform = mtype.form().cachedLambdaForm(which);
if (lform != null) return lform;
}
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final int THIS_MH = 0;
final int CALL_MH = THIS_MH + (isLinker ? 0 : 1);
final int ARG_BASE = CALL_MH + 1;
final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
final int INARG_LIMIT = OUTARG_LIMIT + (isLinker ? 1 : 0);
final int INARG_LIMIT = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
int nameCursor = OUTARG_LIMIT;
final int MTYPE_ARG = nameCursor++; // might be last in-argument
final int MTYPE_ARG = customized ? -1 : nameCursor++; // might be last in-argument
final int CHECK_TYPE = nameCursor++;
final int LINKER_CALL = nameCursor++;
MethodType invokerFormType = mtype.invokerType();
if (isLinker) {
invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
if (!customized)
invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
} else {
invokerFormType = invokerFormType.invokerType();
}
Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
assert(names.length == nameCursor);
assert(names.length == nameCursor)
: Arrays.asList(mtype, customized, which, nameCursor, names.length);
if (MTYPE_ARG >= INARG_LIMIT) {
assert(names[MTYPE_ARG] == null);
names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0);
......@@ -248,31 +306,42 @@ class Invokers {
// Make the final call. If isGeneric, then prepend the result of type checking.
MethodType outCallType;
Object[] outArgs;
Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
if (!isGeneric) {
names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], names[MTYPE_ARG]);
names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
outCallType = mtype;
} else if (customized) {
names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg);
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), tmh=asType(mh, mt);
// tmh.invokeBasic(a*)
outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
outCallType = mtype;
} else {
names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], names[MTYPE_ARG]);
names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
// gamh.invokeBasic(mt, mh, a*)
final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2;
assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT);
outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
// prepend arguments:
System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
outArgs[PREPEND_GAMH] = names[CHECK_TYPE];
outArgs[PREPEND_MT] = names[MTYPE_ARG];
outArgs[PREPEND_MT] = mtypeArg;
outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class);
}
names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs);
lform = new LambdaForm(debugName, INARG_LIMIT, names);
if (isLinker)
lform.compileToBytecode(); // JVM needs a real methodOop
lform = mtype.form().setCachedLambdaForm(which, lform);
if (isCached)
lform = mtype.form().setCachedLambdaForm(which, lform);
return lform;
}
private static final int GENERIC_INVOKER_SLOP = 2; // used elsewhere to avoid arity problems
/*non-public*/ static
WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
......@@ -370,6 +439,7 @@ class Invokers {
// Local constant functions:
private static final NamedFunction NF_checkExactType;
private static final NamedFunction NF_checkGenericType;
private static final NamedFunction NF_asType;
private static final NamedFunction NF_getCallSiteTarget;
static {
try {
......@@ -377,6 +447,8 @@ class Invokers {
.getDeclaredMethod("checkExactType", Object.class, Object.class));
NF_checkGenericType = new NamedFunction(Invokers.class
.getDeclaredMethod("checkGenericType", Object.class, Object.class));
NF_asType = new NamedFunction(MethodHandle.class
.getDeclaredMethod("asType", MethodType.class));
NF_getCallSiteTarget = new NamedFunction(Invokers.class
.getDeclaredMethod("getCallSiteTarget", Object.class));
NF_checkExactType.resolve();
......
......@@ -596,14 +596,7 @@ class LambdaForm {
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
return interpretWithArgumentsTracing(argumentValues);
if (COMPILE_THRESHOLD != 0 &&
invocationCounter < COMPILE_THRESHOLD) {
invocationCounter++; // benign race
if (invocationCounter >= COMPILE_THRESHOLD) {
// Replace vmentry with a bytecode version of this LF.
compileToBytecode();
}
}
checkInvocationCounter();
assert(arityCheck(argumentValues));
Object[] values = Arrays.copyOf(argumentValues, names.length);
for (int i = argumentValues.length; i < values.length; i++) {
......@@ -630,6 +623,16 @@ class LambdaForm {
return name.function.invokeWithArguments(arguments);
}
private void checkInvocationCounter() {
if (COMPILE_THRESHOLD != 0 &&
invocationCounter < COMPILE_THRESHOLD) {
invocationCounter++; // benign race
if (invocationCounter >= COMPILE_THRESHOLD) {
// Replace vmentry with a bytecode version of this LF.
compileToBytecode();
}
}
}
Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
traceInterpreter("[ interpretWithArguments", this, argumentValues);
if (invocationCounter < COMPILE_THRESHOLD) {
......@@ -703,7 +706,7 @@ class LambdaForm {
}
public String toString() {
StringBuilder buf = new StringBuilder("Lambda(");
StringBuilder buf = new StringBuilder(debugName+"=Lambda(");
for (int i = 0; i < names.length; i++) {
if (i == arity) buf.append(")=>{");
Name n = names[i];
......
......@@ -924,7 +924,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
if (arrayType != type().parameterType(collectArgPos))
target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
MethodHandle collector = ValueConversions.varargsArray(arrayType, arrayLength);
return MethodHandleImpl.makeCollectArguments(target, collector, collectArgPos, false);
return MethodHandles.collectArguments(target, collectArgPos, collector);
}
// private API: return true if last param exactly matches arrayType
......@@ -1226,7 +1226,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
return "MethodHandle"+type;
}
String debugString() {
return standardString()+"="+internalForm()+internalValues();
return standardString()+"/LF="+internalForm()+internalProperties();
}
//// Implementation methods.
......@@ -1269,6 +1269,12 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*non-public*/
Object internalValues() {
return null;
}
/*non-public*/
Object internalProperties() {
// Override to something like "/FOO=bar"
return "";
}
......
......@@ -59,7 +59,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
Name[] args = Arrays.copyOfRange(names, 1, 1 + srcType.parameterCount());
names[names.length - 1] = new Name(accessor.asType(srcType), (Object[]) args);
LambdaForm form = new LambdaForm("getElement", lambdaType.parameterCount(), names);
MethodHandle mh = new SimpleMethodHandle(srcType, form);
MethodHandle mh = SimpleMethodHandle.make(srcType, form);
if (ArrayAccessor.needCast(arrayClass)) {
mh = mh.bindTo(arrayClass);
}
......@@ -171,38 +171,46 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// Calculate extra arguments (temporaries) required in the names array.
// FIXME: Use an ArrayList<Name>. Some arguments require more than one conversion step.
int extra = 0;
for (int i = 0; i < srcType.parameterCount(); i++) {
Class<?> src = srcType.parameterType(i);
Class<?> dst = dstType.parameterType(i);
if (!VerifyType.isNullConversion(src, dst)) {
extra++;
final int INARG_COUNT = srcType.parameterCount();
int conversions = 0;
boolean[] needConv = new boolean[1+INARG_COUNT];
for (int i = 0; i <= INARG_COUNT; i++) {
Class<?> src = (i == INARG_COUNT) ? dstType.returnType() : srcType.parameterType(i);
Class<?> dst = (i == INARG_COUNT) ? srcType.returnType() : dstType.parameterType(i);
if (!VerifyType.isNullConversion(src, dst) ||
level <= 1 && dst.isInterface() && !dst.isAssignableFrom(src)) {
needConv[i] = true;
conversions++;
}
}
boolean retConv = needConv[INARG_COUNT];
Class<?> needReturn = srcType.returnType();
Class<?> haveReturn = dstType.returnType();
boolean retConv = !VerifyType.isNullConversion(haveReturn, needReturn);
final int IN_MH = 0;
final int INARG_BASE = 1;
final int INARG_LIMIT = INARG_BASE + INARG_COUNT;
final int NAME_LIMIT = INARG_LIMIT + conversions + 1;
final int RETURN_CONV = (!retConv ? -1 : NAME_LIMIT - 1);
final int OUT_CALL = (!retConv ? NAME_LIMIT : RETURN_CONV) - 1;
// Now build a LambdaForm.
MethodType lambdaType = srcType.invokerType();
Name[] names = arguments(extra + 1, lambdaType);
int[] indexes = new int[lambdaType.parameterCount()];
MethodType lambdaType = srcType.basicType().invokerType();
Name[] names = arguments(NAME_LIMIT - INARG_LIMIT, lambdaType);
// Collect the arguments to the outgoing call, maybe with conversions:
final int OUTARG_BASE = 0; // target MH is Name.function, name Name.arguments[0]
Object[] outArgs = new Object[OUTARG_BASE + INARG_COUNT];
MethodType midType = dstType;
for (int i = 0, argIndex = 1, tmpIndex = lambdaType.parameterCount(); i < srcType.parameterCount(); i++, argIndex++) {
int nameCursor = INARG_LIMIT;
for (int i = 0; i < INARG_COUNT; i++) {
Class<?> src = srcType.parameterType(i);
Class<?> dst = midType.parameterType(i);
Class<?> dst = dstType.parameterType(i);
if (VerifyType.isNullConversion(src, dst)) {
if (!needConv[i]) {
// do nothing: difference is trivial
indexes[i] = argIndex;
outArgs[OUTARG_BASE + i] = names[INARG_BASE + i];
continue;
}
// Work the current type backward toward the desired caller type:
midType = midType.changeParameterType(i, src);
// Tricky case analysis follows.
MethodHandle fn = null;
if (src.isPrimitive()) {
......@@ -246,33 +254,41 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
fn = ValueConversions.cast(dst);
}
}
names[tmpIndex] = new Name(fn, names[argIndex]);
indexes[i] = tmpIndex;
tmpIndex++;
Name conv = new Name(fn, names[INARG_BASE + i]);
assert(names[nameCursor] == null);
names[nameCursor++] = conv;
assert(outArgs[OUTARG_BASE + i] == null);
outArgs[OUTARG_BASE + i] = conv;
}
if (retConv) {
MethodHandle adjustReturn;
// Build argument array for the call.
assert(nameCursor == OUT_CALL);
names[OUT_CALL] = new Name(target, outArgs);
if (RETURN_CONV < 0) {
assert(OUT_CALL == names.length-1);
} else {
Class<?> needReturn = srcType.returnType();
Class<?> haveReturn = dstType.returnType();
MethodHandle fn;
Object[] arg = { names[OUT_CALL] };
if (haveReturn == void.class) {
// synthesize a zero value for the given void
Object zero = Wrapper.forBasicType(needReturn).zero();
adjustReturn = MethodHandles.constant(needReturn, zero);
fn = MethodHandles.constant(needReturn, zero);
arg = new Object[0]; // don't pass names[OUT_CALL] to conversion
} else {
MethodHandle identity = MethodHandles.identity(needReturn);
MethodType needConversion = identity.type().changeParameterType(0, haveReturn);
adjustReturn = makePairwiseConvert(identity, needConversion, level);
fn = makePairwiseConvert(identity, needConversion, level);
}
target = makeCollectArguments(adjustReturn, target, 0, false);
assert(names[RETURN_CONV] == null);
names[RETURN_CONV] = new Name(fn, arg);
assert(RETURN_CONV == names.length-1);
}
// Build argument array for the call.
Name[] targetArgs = new Name[dstType.parameterCount()];
for (int i = 0; i < dstType.parameterCount(); i++) {
int idx = indexes[i];
targetArgs[i] = names[idx];
}
names[names.length - 1] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names);
return new SimpleMethodHandle(srcType, form);
return SimpleMethodHandle.make(srcType, form);
}
static MethodHandle makeReferenceIdentity(Class<?> refType) {
......@@ -280,7 +296,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
Name[] names = arguments(1, lambdaType);
names[names.length - 1] = new Name(ValueConversions.identity(), names[1]);
LambdaForm form = new LambdaForm("identity", lambdaType.parameterCount(), names);
return new SimpleMethodHandle(MethodType.methodType(refType, refType), form);
return SimpleMethodHandle.make(MethodType.methodType(refType, refType), form);
}
static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
......@@ -334,8 +350,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle collector;
try {
collector = asFixedArity().asCollector(arrayType, arrayLength);
assert(collector.type().parameterCount() == newArity) : "newArity="+newArity+" but collector="+collector;
} catch (IllegalArgumentException ex) {
throw new WrongMethodTypeException("cannot build collector");
throw new WrongMethodTypeException("cannot build collector", ex);
}
cache = collector;
return collector.asType(newType);
......@@ -429,12 +446,18 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
names[names.length - 1] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
return new SimpleMethodHandle(srcType, form);
return SimpleMethodHandle.make(srcType, form);
}
static void checkSpreadArgument(Object av, int n) {
// FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
// but the actual exception raised by an arity mismatch should be WMTE
final boolean RAISE_RANDOM_EXCEPTIONS = true; // FIXME: delete in JSR 292 M1
if (av == null) {
if (n == 0) return;
int len;
if (RAISE_RANDOM_EXCEPTIONS)
len = ((Object[])av).length; // throw NPE; but delete this after tests are fixed
} else if (av instanceof Object[]) {
int len = ((Object[])av).length;
if (len == n) return;
......@@ -443,7 +466,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
if (len == n) return;
}
// fall through to error:
throw newIllegalArgumentException("Array is not of length "+n);
if (RAISE_RANDOM_EXCEPTIONS)
throw newIllegalArgumentException("Array is not of length "+n);
throw new WrongMethodTypeException("Array is not of length "+n);
}
private static final NamedFunction NF_checkSpreadArgument;
......@@ -508,7 +533,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
names[targetNamePos] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
return new SimpleMethodHandle(srcType, form);
return SimpleMethodHandle.make(srcType, form);
}
static
......@@ -555,7 +580,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
names[arity + 3] = new Name(new NamedFunction(invokeBasic), targetArgs);
LambdaForm form = new LambdaForm("guard", lambdaType.parameterCount(), names);
return new SimpleMethodHandle(target.type(), form);
return SimpleMethodHandle.make(target.type(), form);
}
private static class GuardWithCatch {
......
......@@ -325,15 +325,28 @@ class MethodHandleNatives {
static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
Class<?> defc, String name, Object type,
Object[] appendixResult) {
if (defc != MethodHandle.class || refKind != REF_invokeVirtual)
throw new LinkageError("no such method "+defc.getName()+"."+name+type);
switch (name) {
case "invoke":
return Invokers.genericInvokerMethod(callerClass, type, appendixResult);
case "invokeExact":
return Invokers.exactInvokerMethod(callerClass, type, appendixResult);
try {
if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
switch (name) {
case "invoke":
return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult);
case "invokeExact":
return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult);
}
}
} catch (Throwable ex) {
if (ex instanceof LinkageError)
throw (LinkageError) ex;
else
throw new LinkageError(ex.getMessage(), ex);
}
throw new UnsupportedOperationException("linkMethod "+name);
throw new LinkageError("no such method "+defc.getName()+"."+name+type);
}
private static MethodType fixMethodType(Class<?> callerClass, Object type) {
if (type instanceof MethodType)
return (MethodType) type;
else
return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
}
// Tracing logic:
static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
......@@ -351,6 +364,7 @@ class MethodHandleNatives {
}
}
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
* It will make an up-call to this method. (Do not change the name or signature.)
......
......@@ -1876,6 +1876,17 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
}
// FIXME: Make this public in M1.
/*non-public*/ static
MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle collector) {
MethodType targetType = target.type();
MethodType filterType = collector.type();
if (filterType.returnType() != void.class &&
filterType.returnType() != targetType.parameterType(pos))
throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
return MethodHandleImpl.makeCollectArguments(target, collector, pos, false);
}
/**
* Adapts a target method handle by post-processing
* its return value (if any) with a filter (another method handle).
......
......@@ -111,6 +111,36 @@ class MethodType implements java.io.Serializable {
void setForm(MethodTypeForm f) { form = f; }
/** This number, mandated by the JVM spec as 255,
* is the maximum number of <em>slots</em>
* that any Java method can receive in its argument list.
* It limits both JVM signatures and method type objects.
* The longest possible invocation will look like
* {@code staticMethod(arg1, arg2, ..., arg255)} or
* {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
*/
/*non-public*/ static final int MAX_JVM_ARITY = 255; // this is mandated by the JVM spec.
/** This number is the maximum arity of a method handle, 254.
* It is derived from the absolute JVM-imposed arity by subtracting one,
* which is the slot occupied by the method handle itself at the
* beginning of the argument list used to invoke the method handle.
* The longest possible invocation will look like
* {@code mh.invoke(arg1, arg2, ..., arg254)}.
*/
// Issue: Should we allow MH.invokeWithArguments to go to the full 255?
/*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1; // deduct one for mh receiver
/** This number is the maximum arity of a method handle invoker, 253.
* It is derived from the absolute JVM-imposed arity by subtracting two,
* which are the slots occupied by invoke method handle, and the the
* target method handle, which are both at the beginning of the argument
* list used to invoke the target method handle.
* The longest possible invocation will look like
* {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
*/
/*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
private static void checkRtype(Class<?> rtype) {
rtype.equals(rtype); // null check
}
......@@ -131,7 +161,9 @@ class MethodType implements java.io.Serializable {
return slots;
}
static void checkSlotCount(int count) {
if ((count & 0xFF) != count)
assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
// MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
if ((count & MAX_JVM_ARITY) != count)
throw newIllegalArgumentException("bad parameter count "+count);
}
private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
......
......@@ -35,10 +35,14 @@ import java.util.logging.Logger;
* @author jrose
*/
final class SimpleMethodHandle extends MethodHandle {
SimpleMethodHandle(MethodType type, LambdaForm form) {
private SimpleMethodHandle(MethodType type, LambdaForm form) {
super(type, form);
}
/*non-public*/ static SimpleMethodHandle make(MethodType type, LambdaForm form) {
return new SimpleMethodHandle(type, form);
}
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodType type2 = type().dropParameterTypes(pos, pos+1);
......
......@@ -59,4 +59,27 @@ public class WrongMethodTypeException extends RuntimeException {
public WrongMethodTypeException(String s) {
super(s);
}
/**
* Constructs a {@code WrongMethodTypeException} with the specified
* detail message and cause.
*
* @param s the detail message.
* @param cause the cause of the exception, or null.
*/
//FIXME: make this public in MR1
/*non-public*/ WrongMethodTypeException(String s, Throwable cause) {
super(s, cause);
}
/**
* Constructs a {@code WrongMethodTypeException} with the specified
* cause.
*
* @param cause the cause of the exception, or null.
*/
//FIXME: make this public in MR1
/*non-public*/ WrongMethodTypeException(Throwable cause) {
super(cause);
}
}
......@@ -44,6 +44,7 @@ public class ValueConversions {
static {
final Object[] values = { 255 };
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
return null;
......@@ -182,7 +183,7 @@ public class ValueConversions {
*/
public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) {
// Maybe merge this code with Wrapper.convert/cast.
Number res = null;
Number res;
if (x == null) {
if (!cast) return null;
return ZERO_INT;
......@@ -322,11 +323,9 @@ public class ValueConversions {
static void ignore(Object x) {
// no value to return; this is an unbox of null
return;
}
static void empty() {
return;
}
static Object zeroObject() {
......@@ -389,24 +388,6 @@ public class ValueConversions {
/// Converting references to references.
/**
* Value-killing function.
* @param x an arbitrary reference value
* @return a null
*/
static Object alwaysNull(Object x) {
return null;
}
/**
* Value-killing function.
* @param x an arbitrary reference value
* @return a zero
*/
static int alwaysZero(Object x) {
return 0;
}
/**
* Identity function.
* @param x an arbitrary reference value
......@@ -416,6 +397,10 @@ public class ValueConversions {
return x;
}
static <T> T[] identity(T[] x) {
return x;
}
/**
* Identity function on ints.
* @param x an arbitrary int value
......@@ -468,29 +453,33 @@ public class ValueConversions {
return t.cast(x);
}
private static final MethodHandle IDENTITY, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY;
private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
static {
try {
MethodType idType = MethodType.genericMethodType(1);
MethodType castType = idType.insertParameterTypes(0, Class.class);
MethodType alwaysZeroType = idType.changeReturnType(int.class);
MethodType ignoreType = idType.changeReturnType(void.class);
MethodType zeroObjectType = MethodType.genericMethodType(0);
IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType);
ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType);
ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class));
ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
FILL_NEW_ARRAY = IMPL_LOOKUP
.findStatic(THIS_CLASS, "fillNewArray",
MethodType.methodType(Object[].class, Integer.class, Object[].class));
FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
.findStatic(THIS_CLASS, "fillNewTypedArray",
MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
} catch (NoSuchMethodException | IllegalAccessException ex) {
throw new InternalError("uncaught exception", ex);
}
}
// Varargs methods need to be in a separately initialized class, to bootstrapping problems.
// Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
static class LazyStatics {
private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
static {
......@@ -505,34 +494,64 @@ public class ValueConversions {
}
}
static MethodHandle collectArguments(MethodHandle mh, int pos, MethodHandle collector) {
// FIXME: API needs public MHs.collectArguments.
// Should be:
// return MethodHandles.collectArguments(mh, 0, collector);
// The rest of this code is a workaround for not having that API.
if (COLLECT_ARGUMENTS != null) {
try {
return (MethodHandle)
COLLECT_ARGUMENTS.invokeExact(mh, pos, collector);
} catch (Throwable ex) {
if (ex instanceof RuntimeException)
throw (RuntimeException) ex;
if (ex instanceof Error)
throw (Error) ex;
throw new Error(ex.getMessage(), ex);
}
}
// Emulate MHs.collectArguments using fold + drop.
// This is slightly inefficient.
// More seriously, it can put a MH over the 255-argument limit.
mh = MethodHandles.dropArguments(mh, 1, collector.type().parameterList());
mh = MethodHandles.foldArguments(mh, collector);
return mh;
}
private static final MethodHandle COLLECT_ARGUMENTS;
static {
MethodHandle mh = null;
try {
java.lang.reflect.Method m = MethodHandles.class
.getDeclaredMethod("collectArguments",
MethodHandle.class, int.class, MethodHandle.class);
m.setAccessible(true);
mh = IMPL_LOOKUP.unreflect(m);
} catch (ReflectiveOperationException | SecurityException ex) {
throw new InternalError(ex);
}
COLLECT_ARGUMENTS = mh;
}
private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
= newWrapperCaches(2);
= newWrapperCaches(1);
/** Return a method that casts its sole argument (an Object) to the given type
* and returns it as the given type (if exact is true), or as plain Object (if erase is true).
* and returns it as the given type.
*/
public static MethodHandle cast(Class<?> type) {
boolean exact = false;
if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type);
MethodHandle mh = null;
MethodHandle mh;
Wrapper wrap = null;
EnumMap<Wrapper, MethodHandle> cache = null;
if (Wrapper.isWrapperType(type)) {
wrap = Wrapper.forWrapperType(type);
cache = WRAPPER_CASTS[exact?1:0];
cache = WRAPPER_CASTS[0];
mh = cache.get(wrap);
if (mh != null) return mh;
}
if (VerifyType.isNullReferenceConversion(Object.class, type))
mh = IDENTITY;
else if (VerifyType.isNullType(type))
mh = ALWAYS_NULL;
else
mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (exact) {
MethodType xmt = MethodType.methodType(type, Object.class);
mh = MethodHandles.explicitCastArguments(mh, xmt);
}
mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (cache != null)
cache.put(wrap, mh);
return mh;
......@@ -920,37 +939,47 @@ public class ValueConversions {
}
private static final MethodHandle[] ARRAYS = makeArrays();
// mh-fill versions of the above:
private static Object[] newArray(int len) { return new Object[len]; }
// filling versions of the above:
// using Integer len instead of int len and no varargs to avoid bootstrapping problems
private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
Object[] a = new Object[len];
fillWithArguments(a, 0, args);
return a;
}
private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
Object[] a = Arrays.copyOf(example, len);
fillWithArguments(a, 0, args);
return a;
}
private static void fillWithArguments(Object[] a, int pos, Object... args) {
System.arraycopy(args, 0, a, pos, args.length);
}
// using Integer pos instead of int pos to avoid bootstrapping problems
private static Object[] fillArray(Object[] a, Integer pos, Object a0)
private static Object[] fillArray(Integer pos, Object[] a, Object a0)
{ fillWithArguments(a, pos, a0); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
{ fillWithArguments(a, pos, a0, a1); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
{ fillWithArguments(a, pos, a0, a1, a2); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
{ fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8, Object a9)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
......@@ -958,7 +987,7 @@ public class ValueConversions {
ArrayList<MethodHandle> mhs = new ArrayList<>();
mhs.add(null); // there is no empty fill; at least a0 is required
for (;;) {
MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);
MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
if (mh == null) break;
mhs.add(mh);
}
......@@ -984,69 +1013,95 @@ public class ValueConversions {
if (mh != null) return mh;
mh = findCollector("array", nargs, Object[].class);
if (mh != null) return ARRAYS[nargs] = mh;
MethodHandle producer = filler(0); // identity function produces result
return ARRAYS[nargs] = buildVarargsArray(producer, nargs);
mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
assert(assertCorrectArity(mh, nargs));
return ARRAYS[nargs] = mh;
}
private static boolean assertCorrectArity(MethodHandle mh, int arity) {
assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
return true;
}
private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {
private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
// Build up the result mh as a sequence of fills like this:
// producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))
// finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
// The various fill(_,10*I,___*[J]) are reusable.
MethodHandle filler = filler(nargs);
MethodHandle mh = producer;
mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());
mh = MethodHandles.foldArguments(mh, filler);
mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));
int leftLen = Math.min(nargs, LEFT_ARGS); // absorb some arguments immediately
int rightLen = nargs - leftLen;
MethodHandle leftCollector = newArray.bindTo(nargs);
leftCollector = leftCollector.asCollector(Object[].class, leftLen);
MethodHandle mh = finisher;
if (rightLen > 0) {
MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
if (mh == ARRAY_IDENTITY)
mh = rightFiller;
else
mh = collectArguments(mh, 0, rightFiller);
}
if (mh == ARRAY_IDENTITY)
mh = leftCollector;
else
mh = collectArguments(mh, 0, leftCollector);
return mh;
}
private static MethodHandle buildNewArray(int nargs) {
return MethodHandles.insertArguments(NEW_ARRAY, 0, nargs);
}
private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
// filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]
private static MethodHandle filler(int nargs) {
MethodHandle filler = FILLERS[nargs];
private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
/** fill_array_to_right(N).invoke(a, argL..arg[N-1])
* fills a[L]..a[N-1] with corresponding arguments,
* and then returns a. The value L is a global constant (LEFT_ARGS).
*/
private static MethodHandle fillToRight(int nargs) {
MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
if (filler != null) return filler;
return FILLERS[nargs] = buildFiller(nargs);
filler = buildFiller(nargs);
assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
return FILL_ARRAY_TO_RIGHT[nargs] = filler;
}
private static MethodHandle buildFiller(int nargs) {
if (nargs == 0)
return MethodHandles.identity(Object[].class);
final int CHUNK = (FILL_ARRAYS.length - 1);
if (nargs <= LEFT_ARGS)
return ARRAY_IDENTITY; // no args to fill; return the array unchanged
// we need room for both mh and a in mh.invoke(a, arg*[nargs])
final int CHUNK = LEFT_ARGS;
int rightLen = nargs % CHUNK;
int leftLen = nargs - rightLen;
int midLen = nargs - rightLen;
if (rightLen == 0) {
leftLen = nargs - (rightLen = CHUNK);
if (FILLERS[leftLen] == null) {
midLen = nargs - (rightLen = CHUNK);
if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
// build some precursors from left to right
for (int j = 0; j < leftLen; j += CHUNK) filler(j);
for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
if (j > LEFT_ARGS) fillToRight(j);
}
}
MethodHandle leftFill = filler(leftLen); // recursive fill
MethodHandle rightFill = FILL_ARRAYS[rightLen];
rightFill = MethodHandles.insertArguments(rightFill, 1, leftLen); // [leftLen..nargs-1]
// Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
MethodHandle mh = filler(0); // identity function produces result
mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());
mh = MethodHandles.foldArguments(mh, rightFill);
if (leftLen > 0) {
mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());
mh = MethodHandles.foldArguments(mh, leftFill);
}
return mh;
if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
assert(rightLen > 0);
MethodHandle midFill = fillToRight(midLen); // recursive fill
MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1]
assert(midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS);
assert(rightFill.type().parameterCount() == 1 + rightLen);
// Combine the two fills:
// right(mid(a, x10..x19), x20..x23)
// The final product will look like this:
// right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
if (midLen == LEFT_ARGS)
return rightFill;
else
return collectArguments(rightFill, 0, midFill);
}
// Type-polymorphic version of varargs maker.
private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
= new ClassValue<MethodHandle[]>() {
@Override
protected MethodHandle[] computeValue(Class<?> type) {
return new MethodHandle[256];
}
};
static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
/** Return a method handle that takes the indicated number of
* typed arguments and returns an array of them.
* The type argument is the array type.
......@@ -1055,16 +1110,36 @@ public class ValueConversions {
Class<?> elemType = arrayType.getComponentType();
if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
// FIXME: Need more special casing and caching here.
if (nargs >= MAX_JVM_ARITY/2 - 1) {
int slots = nargs;
final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
if (arrayType == double[].class || arrayType == long[].class)
slots *= 2;
if (slots > MAX_ARRAY_SLOTS)
throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
}
if (elemType == Object.class)
return varargsArray(nargs);
// other cases: primitive arrays, subtypes of Object[]
MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
if (mh != null) return mh;
MethodHandle producer = buildArrayProducer(arrayType);
mh = buildVarargsArray(producer, nargs);
if (elemType.isPrimitive()) {
MethodHandle builder = FILL_NEW_ARRAY;
MethodHandle producer = buildArrayProducer(arrayType);
mh = buildVarargsArray(builder, producer, nargs);
} else {
@SuppressWarnings("unchecked")
Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
MethodHandle producer = ARRAY_IDENTITY;
mh = buildVarargsArray(builder, producer, nargs);
}
mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
cache[nargs] = mh;
assert(assertCorrectArity(mh, nargs));
if (nargs < cache.length)
cache[nargs] = mh;
return mh;
}
......
/*
* Copyright (c) 2012, 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.
*/
/* @test
* @summary High arity invocations, up to the maximum of 255 arguments
* @compile BigArityTest.java
* @run junit/othervm -DBigArityTest.ITERATION_COUNT=1 test.java.lang.invoke.BigArityTest
*/
package test.java.lang.invoke;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class BigArityTest {
static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
static final int MAX_JVM_ARITY = 255;
static final int ITERATION_COUNT = getProperty("ITERATION_COUNT", 40000);
static final int MIN_ARITY = getProperty("MIN_ARITY", 250);
static final int SLOW_ARITY = getProperty("SLOW_ARITY", MAX_JVM_ARITY-3);
static final int MAX_ARITY = getProperty("MAX_ARITY", MAX_JVM_ARITY-1); // always -1 for the MH reciever itself
private static int getProperty(String name, int dflt) {
return Integer.parseInt(getProperty(name, ""+dflt));
}
private static String getProperty(String name, String dflt) {
String x = System.getProperty(BigArityTest.class.getSimpleName() + "." + name);
if (x == null) x = System.getProperty(BigArityTest.class.getName() + "." + name);
return x == null ? dflt : x;
}
static Object hashArguments(Object... args) {
return Objects.hash(args);
}
static final MethodHandle MH_hashArguments_VA;
static {
try {
MH_hashArguments_VA =
MethodHandles.lookup().unreflect(
BigArityTest.class.getDeclaredMethod("hashArguments", Object[].class));
} catch (ReflectiveOperationException ex) {
throw new InternalError(ex);
}
}
static MethodHandle MH_hashArguments(int arity) {
MethodType mt = MethodType.genericMethodType(arity);
return MH_hashArguments_VA.asType(mt);
}
static MethodHandle MH_hashArguments(Class<? extends Object[]> arrayClass, int arity) {
if (arrayClass == Object[].class)
return MH_hashArguments(arity);
ArrayList<Class<?>> ptypes = new ArrayList<>(Collections.<Class<?>>nCopies(arity, arrayClass.getComponentType()));
MethodType mt = MethodType.methodType(Object.class, ptypes);
return MH_hashArguments_VA.asType(mt);
}
static Object[] testArgs(int arity) {
Object args[] = new Object[arity];
for (int i = 0; i < arity; i++)
args[i] = i * (i + 1) / 2;
return args;
}
@Test
public void testBoundaryValues() throws Throwable {
for (int badArity : new int[]{ -1, MAX_JVM_ARITY+1, MAX_JVM_ARITY }) {
try {
MethodHandle badmh = MH_hashArguments(badArity);
throw new AssertionError("should not be able to build a 255-arity MH: "+badmh);
} catch (IllegalArgumentException | WrongMethodTypeException ex) {
System.out.println("OK: "+ex);
}
}
}
// Make sure the basic argument spreading and varargs mechanisms are working.
// Exercise arity 3 thoroughly.
@Test
public void testSpreads() throws Throwable {
System.out.println("testing asSpreader on arity=3");
Object[] args = testArgs(3);
int r0 = Objects.hash(args);
MethodHandle mh = MH_hashArguments(3);
Object r;
r = mh.invokeExact(args[0], args[1], args[2]);
assertEquals(r0, r);
r = mh.invoke(args[0], args[1], args[2]);
assertEquals(r0, r);
r = mh.invoke((Comparable) args[0], (Integer) args[1], (Number) args[2]);
assertEquals(r0, r);
r = mh.invokeWithArguments(args);
assertEquals(r0, r);
for (Class<?> cls0 : new Class<?>[] {
Object[].class, Number[].class, Integer[].class, Comparable[].class
}) {
@SuppressWarnings("unchecked")
Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
//Class<? extends Object[]> cls = Object[].class.asSubclass(cls0);
int nargs = args.length, skip;
MethodHandle smh = mh.asSpreader(cls, nargs - (skip = 0));
Object[] tail = Arrays.copyOfRange(args, skip, nargs, cls);
if (cls == Object[].class)
r = smh.invokeExact(tail);
else if (cls == Integer[].class)
r = smh.invokeExact((Integer[]) tail);
else
r = smh.invoke(tail);
assertEquals(r0, r);
smh = mh.asSpreader(cls, nargs - (skip = 1));
tail = Arrays.copyOfRange(args, skip, nargs, cls);
if (cls == Object[].class)
r = smh.invokeExact(args[0], tail);
else if (cls == Integer[].class)
r = smh.invokeExact(args[0], (Integer[]) tail);
else
r = smh.invoke(args[0], tail);
assertEquals(r0, r);
smh = mh.asSpreader(cls, nargs - (skip = 2));
tail = Arrays.copyOfRange(args, skip, nargs, cls);
if (cls == Object[].class)
r = smh.invokeExact(args[0], args[1], tail);
else if (cls == Integer[].class)
r = smh.invokeExact(args[0], args[1], (Integer[]) tail);
else
r = smh.invoke(args[0], args[1], tail);
assertEquals(r0, r);
smh = mh.asSpreader(cls, nargs - (skip = 3));
tail = Arrays.copyOfRange(args, skip, nargs, cls);
if (cls == Object[].class)
r = smh.invokeExact(args[0], args[1], args[2], tail);
else if (cls == Integer[].class)
r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
else
r = smh.invoke(args[0], args[1], args[2], tail);
assertEquals(r0, r);
// Try null array in addition to zero-length array:
tail = null;
if (cls == Object[].class)
r = smh.invokeExact(args[0], args[1], args[2], tail);
else if (cls == Integer[].class)
r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
else
r = smh.invoke(args[0], args[1], args[2], tail);
assertEquals(r0, r);
}
}
@Test
public void testInvokeWithArguments() throws Throwable {
System.out.println("testing invokeWithArguments on all arities");
for (int arity = 0; arity < MAX_ARITY; arity++) {
Object[] args = testArgs(arity);
Object r0 = Objects.hash(args);
Object r = MH_hashArguments(arity).invokeWithArguments(args);
assertEquals("arity="+arity, r0, r);
}
// The next one is the most likely to fail:
int arity = MAX_ARITY;
Object[] args = testArgs(arity);
Object r0 = Objects.hash(args);
Object r = MH_hashArguments(arity).invokeWithArguments(args);
assertEquals("arity=MAX_ARITY", r0, r);
}
static Object[] cat(Object a, Object[] b) {
int alen = 1, blen = b.length;
Object[] c = new Object[alen + blen];
c[0] = a;
System.arraycopy(b, 0, c, alen, blen);
return c;
}
@Test
public void testArities() throws Throwable {
System.out.println("testing spreaders and collectors on high arities...");
int iterations = ITERATION_COUNT;
testArities(Object[].class, MIN_ARITY-10, MIN_ARITY-1, iterations / 1000);
testArities(Object[].class, MIN_ARITY, SLOW_ARITY-1, iterations);
testArities(Object[].class, SLOW_ARITY, MAX_ARITY, iterations / 1000);
}
@Test
public void testAritiesOnTypedArrays() throws Throwable {
for (Class<?> cls0 : new Class<?>[] {
Number[].class, Integer[].class, Comparable[].class
}) {
@SuppressWarnings("unchecked")
Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
System.out.println("array class: "+cls.getSimpleName());
int iterations = ITERATION_COUNT / 1000;
testArities(cls, MIN_ARITY, SLOW_ARITY-1, iterations);
testArities(cls, SLOW_ARITY, MAX_ARITY, iterations / 100);
}
}
private void testArities(Class<? extends Object[]> cls,
int minArity,
int maxArity,
int iterations) throws Throwable {
boolean verbose = (cls == Object[].class);
for (int arity = minArity; arity <= maxArity; arity++) {
if (verbose) System.out.println("arity="+arity);
MethodHandle mh = MH_hashArguments(cls, arity);
MethodHandle mh_VA = mh.asSpreader(cls, arity);
assert(mh_VA.type().parameterType(0) == cls);
testArities(cls, arity, iterations, verbose, mh, mh_VA);
if (cls != Object[].class) {
// mh_CA will collect arguments of a particular type and pass them to mh_VA
MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
try {
mh_VA2.invokeWithArguments(new Object[arity]);
throw new AssertionError("should not reach");
} catch (ClassCastException | WrongMethodTypeException ex) {
}
assert(mh_CA.type().equals(mh.type()));
assert(mh_VA2.type().equals(mh_VA.type()));
testArities(cls, arity, iterations, false, mh_CA, mh_VA2);
}
}
}
private void testArities(Class<? extends Object[]> cls,
int arity,
int iterations,
boolean verbose,
MethodHandle mh,
MethodHandle mh_VA
) throws Throwable {
if (iterations < 4) iterations = 4;
final int MAX_MH_ARITY = MAX_JVM_ARITY - 1; // mh.invoke(arg*[N])
final int MAX_INVOKER_ARITY = MAX_MH_ARITY - 1; // inv.invoke(mh, arg*[N])
Object[] args = testArgs(arity);
if (cls != Object[].class)
args = Arrays.copyOf(args, arity, cls);
Object r0 = Objects.hash(args);
Object r;
MethodHandle ximh = null;
MethodHandle gimh = null;
if (arity <= MAX_INVOKER_ARITY) {
ximh = MethodHandles.exactInvoker(mh.type());
gimh = MethodHandles.invoker(mh.type());
} else {
try {
ximh = MethodHandles.exactInvoker(mh.type());
throw new AssertionError("should fail to create ximh of arity "+arity);
} catch (IllegalArgumentException ex) {
if (verbose)
System.out.println("OK: xmih["+arity+"] => "+ex);
}
try {
gimh = MethodHandles.invoker(mh.type());
throw new AssertionError("should fail to create gimh of arity "+arity);
} catch (IllegalArgumentException ex) {
if (verbose)
System.out.println("OK: gmih["+arity+"] => "+ex);
}
}
Object[] mh_args = cat(mh, args);
assert(arity <= MAX_MH_ARITY);
for (int i = 0; i < iterations; ++i) {
if (cls == Object[].class)
r = mh_VA.invokeExact(args);
else if (cls == Integer[].class)
r = mh_VA.invokeExact((Integer[])args);
else
r = mh_VA.invoke(args);
assertEquals(r0, r);
r = mh.invokeWithArguments(args);
assertEquals(r0, r);
if (ximh != null) {
r = ximh.invokeWithArguments(mh_args);
assertEquals(r0, r);
}
if (gimh != null) {
r = gimh.invokeWithArguments(mh_args);
assertEquals(r0, r);
}
}
}
static Object hashArguments_252(
// <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
// </editor-fold>
Object xF8, Object xF9, Object xFA, Object xFB) {
return Objects.hash(
// <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
// </editor-fold>
xF8, xF9, xFA, xFB);
}
@Test
public void test252() throws Throwable {
final int ARITY = 252;
System.out.println("test"+ARITY);
Object[] a = testArgs(ARITY);
Object r0 = hashArguments(a);
Object r;
r = hashArguments_252(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
MethodType mt = MethodType.genericMethodType(ARITY);
MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
r = mh.invokeWithArguments(a);
assertEquals(r0, r);
MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
r = ximh.invokeExact(mh,
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
r = ximh.invokeWithArguments(cat(mh,a));
assertEquals(r0, r);
MethodHandle gimh = MethodHandles.invoker(mh.type());
r = gimh.invoke(mh,
// <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
(Number)
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
r = gimh.invokeWithArguments(cat(mh,a));
assertEquals(r0, r);
mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
//System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
(Integer)
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
r = mh.invoke(
// <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
(Comparable<?>)
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
assertEquals(r0, r);
}
static Object hashArguments_253(
// <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
// </editor-fold>
Object xF8, Object xF9, Object xFA, Object xFB, Object xFC) {
return Objects.hash(
// <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
// </editor-fold>
xF8, xF9, xFA, xFB, xFC);
}
@Test
public void test253() throws Throwable {
final int ARITY = 253;
System.out.println("test"+ARITY);
Object[] a = testArgs(ARITY);
Object r0 = hashArguments(a);
Object r;
r = hashArguments_253(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
MethodType mt = MethodType.genericMethodType(ARITY);
MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
r = mh.invokeWithArguments(a);
assertEquals(r0, r);
MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
r = ximh.invokeExact(mh,
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
// FIXME: This next one fails, because it uses an internal invoker of arity 255.
r = ximh.invokeWithArguments(cat(mh,a));
assertEquals(r0, r);
MethodHandle gimh = MethodHandles.invoker(mh.type());
r = gimh.invoke(mh,
// <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
(Number)
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
// FIXME: This next one fails, because it uses an internal invoker of arity 255.
r = gimh.invokeWithArguments(cat(mh,a));
assertEquals(r0, r);
mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
//System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
(Integer)
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
r = mh.invoke(
// <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
(Comparable<?>)
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
assertEquals(r0, r);
}
static Object hashArguments_254(
// <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
// </editor-fold>
Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD) {
return Objects.hash(
// <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
// </editor-fold>
xF8, xF9, xFA, xFB, xFC, xFD);
}
@Test
public void test254() throws Throwable {
final int ARITY = 254;
System.out.println("test"+ARITY);
Object[] a = testArgs(ARITY);
Object r0 = hashArguments(a);
Object r;
r = hashArguments_254(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
assertEquals(r0, r);
MethodType mt = MethodType.genericMethodType(ARITY);
MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
assertEquals(r0, r);
// FIXME: This next one fails, because it uses an internal invoker of arity 255.
r = mh.invokeWithArguments(a);
assertEquals(r0, r);
try {
MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
throw new AssertionError("should have thrown IAE; cannot have 1+1+254 arguments");
} catch (IllegalArgumentException ex) {
System.out.println("OK: "+ex);
}
mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
//System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
(Integer)
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
assertEquals(r0, r);
mh = mh.asType(mh.type().changeParameterType(0xE0, Number.class));
//System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ... (Number) a[0xE0], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
(Integer)
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
(Number)
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
assertEquals(r0, r);
r = mh.invoke(
// <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
(Comparable<?>)
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
assertEquals(r0, r);
}
static Object hashArguments_255(
// <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
// </editor-fold>
Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD, Object xFE) {
return Objects.hash(
// <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
// </editor-fold>
xF8, xF9, xFA, xFB, xFC, xFD, xFE);
}
@Test
public void test255() throws Throwable {
final int ARITY = 255;
System.out.println("test"+ARITY);
Object[] a = testArgs(ARITY);
Object r0 = hashArguments(a);
Object r;
r = hashArguments_255(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
assertEquals(r0, r);
MethodType mt = MethodType.genericMethodType(ARITY);
MethodHandle mh;
try {
mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
throw new AssertionError("should not create an arity 255 method handle");
} catch (IllegalArgumentException ex) {
System.out.println("OK: "+ex);
mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+(ARITY-1), mt.dropParameterTypes(ARITY-1, ARITY));
}
try {
r = mh.invokeExact(
// <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
// </editor-fold>
a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
throw new AssertionError("should not call an arity 255 method handle");
} catch (LinkageError ex) {
System.out.println("OK: "+ex);
}
try {
MethodHandle ximh = MethodHandles.exactInvoker(mt);
throw new AssertionError("should have thrown IAE; cannot have 1+1+255 arguments");
} catch (IllegalArgumentException ex) {
System.out.println("OK: "+ex);
}
}
}
/*
* Copyright (c) 2012, 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.
*/
/* @test
* @summary BoundMethodHandle tests with primitive types
* @compile MaxTest.java
* @run junit/othervm test.java.lang.invoke.MaxTest
*/
package test.java.lang.invoke;
import static org.junit.Assert.assertEquals;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import org.junit.Test;
public class MaxTest {
static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
private MethodHandle getMax(Class<?> t) throws Throwable {
return LOOKUP.findStatic(Math.class, "max", MethodType.methodType(t, t, t));
}
static int ITERATION_COUNT = 40000;
static {
String iterations = System.getProperty(MaxTest.class.getSimpleName() + ".ITERATION_COUNT");
if (iterations == null) {
iterations = System.getProperty(MaxTest.class.getName() + ".ITERATION_COUNT");
}
if (iterations != null) {
ITERATION_COUNT = Integer.parseInt(iterations);
}
}
@Test
public void testMaxLong() throws Throwable {
final Class<?> C = long.class;
final long P = 23L;
final long Q = 42L;
final long R = Math.max(P, Q);
for (int i = 0; i < ITERATION_COUNT; ++i) {
MethodHandle h = getMax(C);
assertEquals((long) h.invokeExact(P, Q), R);
MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
assertEquals((long) bh.invokeExact(Q), R);
MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
assertEquals((long) bbh.invokeExact(), R);
MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
assertEquals((long) b2h.invokeExact(P), R);
MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
assertEquals((long) bb2h.invokeExact(), R);
}
}
@Test
public void testMaxInt() throws Throwable {
final Class<?> C = int.class;
final int P = 23;
final int Q = 42;
final int R = Math.max(P, Q);
for (int i = 0; i < ITERATION_COUNT; ++i) {
MethodHandle h = getMax(C);
assertEquals((int) h.invokeExact(P, Q), R);
MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
assertEquals((int) bh.invokeExact(Q), R);
MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
assertEquals((int) bbh.invokeExact(), R);
MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
assertEquals((int) b2h.invokeExact(P), R);
MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
assertEquals((int) bb2h.invokeExact(), R);
}
}
@Test
public void testMaxFloat() throws Throwable {
final Class<?> C = float.class;
final float P = 23F;
final float Q = 42F;
final float R = Math.max(P, Q);
final float D = 0.1F;
for (int i = 0; i < ITERATION_COUNT; ++i) {
MethodHandle h = getMax(C);
assertEquals((float) h.invokeExact(P, Q), R, D);
MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
assertEquals((float) bh.invokeExact(Q), R, D);
MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
assertEquals((float) bbh.invokeExact(), R, D);
MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
assertEquals((float) b2h.invokeExact(P), R, D);
MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
assertEquals((float) bb2h.invokeExact(), R, D);
}
}
@Test
public void testMaxDouble() throws Throwable {
final Class<?> C = double.class;
final double P = 23F;
final double Q = 42F;
final double R = Math.max(P, Q);
final double D = 0.1;
for (int i = 0; i < ITERATION_COUNT; ++i) {
MethodHandle h = getMax(C);
assertEquals((double) h.invokeExact(P, Q), R, D);
MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
assertEquals((double) bh.invokeExact(Q), R, D);
MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
assertEquals((double) bbh.invokeExact(), R, D);
MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
assertEquals((double) b2h.invokeExact(P), R, D);
MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
assertEquals((double) bb2h.invokeExact(), R, D);
}
}
}
......@@ -1485,7 +1485,7 @@ public class MethodHandlesTest {
RuntimeException error = null;
try {
target = id.asType(newType);
} catch (RuntimeException ex) {
} catch (WrongMethodTypeException ex) {
error = ex;
}
if (verbosity >= 3)
......@@ -2381,47 +2381,100 @@ public class MethodHandlesTest {
assertSame(thrown, caught);
}
//@Test
@Test
public void testInterfaceCast() throws Throwable {
//if (CAN_SKIP_WORKING) return;
startTest("interfaceCast");
for (Class<?> ctype : new Class<?>[]{ Object.class, String.class, CharSequence.class, Number.class, Iterable.class}) {
testInterfaceCast(ctype, false, false);
testInterfaceCast(ctype, true, false);
testInterfaceCast(ctype, false, true);
testInterfaceCast(ctype, true, true);
assert( (((Object)"foo") instanceof CharSequence));
assert(!(((Object)"foo") instanceof Iterable));
for (MethodHandle mh : new MethodHandle[]{
MethodHandles.identity(String.class),
MethodHandles.identity(CharSequence.class),
MethodHandles.identity(Iterable.class)
}) {
if (verbosity > 0) System.out.println("-- mh = "+mh);
for (Class<?> ctype : new Class<?>[]{
Object.class, String.class, CharSequence.class,
Number.class, Iterable.class
}) {
if (verbosity > 0) System.out.println("---- ctype = "+ctype.getName());
// doret docast
testInterfaceCast(mh, ctype, false, false);
testInterfaceCast(mh, ctype, true, false);
testInterfaceCast(mh, ctype, false, true);
testInterfaceCast(mh, ctype, true, true);
}
}
}
public void testInterfaceCast(Class<?> ctype, boolean doret, boolean docast) throws Throwable {
String str = "normal return value";
MethodHandle mh = MethodHandles.identity(String.class);
private static Class<?> i2o(Class<?> c) {
return (c.isInterface() ? Object.class : c);
}
public void testInterfaceCast(MethodHandle mh, Class<?> ctype,
boolean doret, boolean docast) throws Throwable {
MethodHandle mh0 = mh;
if (verbosity > 1)
System.out.println("mh="+mh+", ctype="+ctype.getName()+", doret="+doret+", docast="+docast);
String normalRetVal = "normal return value";
MethodType mt = mh.type();
MethodType mt0 = mt;
if (doret) mt = mt.changeReturnType(ctype);
else mt = mt.changeParameterType(0, ctype);
if (docast) mh = MethodHandles.explicitCastArguments(mh, mt);
else mh = mh.asType(mt);
assertEquals(mt, mh.type());
MethodType mt1 = mt;
// this bit is needed to make the interface types disappear for invokeWithArguments:
mh = MethodHandles.explicitCastArguments(mh, mt.generic());
boolean expectFail = !ctype.isInstance(str);
if (ctype.isInterface()) {
// special rules: interfaces slide by more frequently
if (docast || !doret) expectFail = false;
Class<?>[] step = {
mt1.parameterType(0), // param as passed to mh at first
mt0.parameterType(0), // param after incoming cast
mt0.returnType(), // return value before cast
mt1.returnType(), // return value after outgoing cast
};
// where might a checkCast occur?
boolean[] checkCast = new boolean[step.length];
// the string value must pass each step without causing an exception
if (!docast) {
if (!doret) {
if (step[0] != step[1])
checkCast[1] = true; // incoming value is cast
} else {
if (step[2] != step[3])
checkCast[3] = true; // outgoing value is cast
}
}
boolean expectFail = false;
for (int i = 0; i < step.length; i++) {
Class<?> c = step[i];
if (!checkCast[i]) c = i2o(c);
if (!c.isInstance(normalRetVal)) {
if (verbosity > 3)
System.out.println("expect failure at step "+i+" in "+Arrays.toString(step)+Arrays.toString(checkCast));
expectFail = true;
break;
}
}
countTest(!expectFail);
if (verbosity > 2)
System.out.println("expectFail="+expectFail+", mt="+mt);
Object res;
try {
res = mh.invokeWithArguments(str);
res = mh.invokeWithArguments(normalRetVal);
} catch (Exception ex) {
res = ex;
}
boolean sawFail = !(res instanceof String);
if (sawFail != expectFail) {
System.out.println("*** testInterfaceCast: "+mh+" was "+mt+" => "+res+(docast ? " (explicitCastArguments)" : ""));
}
if (!sawFail) {
assertFalse(res.toString(), expectFail);
assertEquals(str, res);
System.out.println("*** testInterfaceCast: mh0 = "+mh0);
System.out.println(" retype using "+(docast ? "explicitCastArguments" : "asType")+" to "+mt+" => "+mh);
System.out.println(" call returned "+res);
System.out.println(" expected "+(expectFail ? "an exception" : normalRetVal));
}
if (!expectFail) {
assertFalse(res.toString(), sawFail);
assertEquals(normalRetVal, res);
} else {
assertTrue(res.toString(), expectFail);
assertTrue(res.toString(), sawFail);
}
}
......
......@@ -191,7 +191,11 @@ public class PermuteArgsTest {
pt = mt1.parameterType(mt1.parameterCount() - posArgs);
mt1 = mt1.appendParameterTypes(pt);
}
return mh.asType(mt1);
try {
return mh.asType(mt1);
} catch (WrongMethodTypeException | IllegalArgumentException ex) {
throw new IllegalArgumentException("cannot convert to type "+mt1+" from "+mh, ex);
}
}
static MethodHandle findTestMH(String name, int[] perm) throws ReflectiveOperationException {
int arity = perm.length;
......
......@@ -256,7 +256,7 @@ public class RicochetTest {
//System.out.println(" expect="+expect);
// now use the combined MH, and test the output:
MethodHandle mh = collectArguments(lister, pos, INT_COLLECTORS[collects]);
MethodHandle mh = collectArguments(lister, pos, int[].class, INT_COLLECTORS[collects]);
if (mh == null) continue; // no infix collection, yet
assert(mh.type().parameterCount() == inputs);
Object observe = mh.asSpreader(int[].class, args.length).invokeExact(args);
......@@ -266,13 +266,53 @@ public class RicochetTest {
}
}
private static MethodHandle collectArguments(MethodHandle lister, int pos, MethodHandle collector) {
@Test
public void testByteCollects() throws Throwable {
if (!startTest("testByteCollects")) return;
for (MethodHandle lister : BYTE_LISTERS) {
int outputs = lister.type().parameterCount();
for (int collects = 0; collects <= Math.min(outputs, BYTE_COLLECTORS.length-1); collects++) {
int inputs = outputs - 1 + collects;
if (inputs < 0) continue;
for (int pos = 0; pos + collects <= inputs; pos++) {
MethodHandle collector = BYTE_COLLECTORS[collects];
byte[] args = new byte[inputs];
int ap = 0, arg = 31;
for (int i = 0; i < pos; i++)
args[ap++] = (byte)(arg++ + 0);
for (int i = 0; i < collects; i++)
args[ap++] = (byte)(arg++ + 10);
while (ap < args.length)
args[ap++] = (byte)(arg++ + 20);
// calculate piecemeal:
//System.out.println("testIntCollects "+Arrays.asList(lister, pos, collector)+" on "+Arrays.toString(args));
byte[] collargs = Arrays.copyOfRange(args, pos, pos+collects);
byte coll = (byte) collector.asSpreader(byte[].class, collargs.length).invokeExact(collargs);
byte[] listargs = Arrays.copyOfRange(args, 0, outputs);
System.arraycopy(args, pos+collects, listargs, pos+1, outputs - (pos+1));
listargs[pos] = coll;
//System.out.println(" coll="+coll+" listargs="+Arrays.toString(listargs));
Object expect = lister.asSpreader(byte[].class, listargs.length).invokeExact(listargs);
//System.out.println(" expect="+expect);
// now use the combined MH, and test the output:
MethodHandle mh = collectArguments(lister, pos, byte[].class, BYTE_COLLECTORS[collects]);
if (mh == null) continue; // no infix collection, yet
assert(mh.type().parameterCount() == inputs);
Object observe = mh.asSpreader(byte[].class, args.length).invokeExact(args);
assertEquals(expect, observe);
}
}
}
}
private static MethodHandle collectArguments(MethodHandle lister, int pos, Class<?> array, MethodHandle collector) {
int collects = collector.type().parameterCount();
int outputs = lister.type().parameterCount();
if (pos == outputs - 1)
return MethodHandles.filterArguments(lister, pos,
collector.asSpreader(int[].class, collects))
.asCollector(int[].class, collects);
collector.asSpreader(array, collects))
.asCollector(array, collects);
//return MethodHandles.collectArguments(lister, pos, collector); //no such animal
return null;
}
......@@ -537,6 +577,9 @@ public class RicochetTest {
private static final MethodHandle[] INT_COLLECTORS = {
constant(int.class, 42), opI, opI2, opI3, opI4
};
private static final MethodHandle[] BYTE_COLLECTORS = {
constant(byte.class, (byte)42), i2b(opI), i2b(opI2), i2b(opI3), i2b(opI4)
};
private static final MethodHandle[] LONG_COLLECTORS = {
constant(long.class, 42), opJ, opJ2, opJ3
};
......@@ -559,21 +602,36 @@ public class RicochetTest {
Collections.nCopies(8, int.class));
private static final MethodHandle list8longs = findStatic("list8longs", Object.class,
Collections.nCopies(8, long.class));
private static final MethodHandle[] INT_LISTERS, LONG_LISTERS;
private static final MethodHandle[] INT_LISTERS, LONG_LISTERS, BYTE_LISTERS;
static {
int listerCount = list8ints.type().parameterCount() + 1;
INT_LISTERS = new MethodHandle[listerCount];
LONG_LISTERS = new MethodHandle[listerCount];
BYTE_LISTERS = new MethodHandle[listerCount];
MethodHandle lister = list8ints;
MethodHandle llister = list8longs;
for (int i = listerCount - 1; ; i--) {
INT_LISTERS[i] = lister;
LONG_LISTERS[i] = llister;
BYTE_LISTERS[i] = i2b(lister);
if (i == 0) break;
lister = insertArguments(lister, i-1, 0);
llister = insertArguments(llister, i-1, 0L);
}
}
private static MethodHandle i2b(MethodHandle mh) {
return MethodHandles.explicitCastArguments(mh, subst(mh.type(), int.class, byte.class));
}
private static MethodType subst(MethodType mt, Class<?> from, Class<?> to) {
for (int i = 0; i < mt.parameterCount(); i++) {
if (mt.parameterType(i) == from)
mt = mt.changeParameterType(i, to);
}
if (mt.returnType() == from)
mt = mt.changeReturnType(to);
return mt;
}
private static Object convI_L(int x) { stress(); return (Object) x; }
private static int convL_I(Object x) { stress(); return (int) x; }
......
......@@ -159,14 +159,8 @@ public class ValueConversionsTest {
assertEquals(caster.type(), ValueConversions.identity().type());
for (Object obj : objects) {
Class<?> src = obj.getClass();
boolean canCast;
if (dst.isInterface()) {
canCast = true;
} else {
canCast = dst.isAssignableFrom(src);
assertEquals(canCast, dst.isInstance(obj));
}
//System.out.println("obj="+obj+" <: dst="+dst);
boolean canCast = dst.isAssignableFrom(src);
//System.out.println("obj="+obj+" <: dst="+dst+(canCast ? " (OK)" : " (will fail)"));
try {
Object result = caster.invokeExact(obj);
if (canCast)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册