8185993: MethodHandle.invokeWithArguments jumbo-arity

Reviewed-by: psandoz, vlivanov
This commit is contained in:
John R Rose 2017-09-22 15:28:16 -07:00
parent 71e91d9c2e
commit f98aab0db9
6 changed files with 294 additions and 46 deletions

View file

@ -344,13 +344,21 @@ public class CallSite {
break;
default:
final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
throw new BootstrapMethodError("too many bootstrap method arguments");
MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
binding = spreader.invokeExact(typedBSM, (Object) caller, (Object) name, (Object) type, argv);
final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
if (argv.length >= MAX_SAFE_SIZE) {
// to be on the safe side, use invokeWithArguments which handles jumbo lists
Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argv.length];
newargv[0] = caller;
newargv[1] = name;
newargv[2] = type;
System.arraycopy(argv, 0, newargv, NON_SPREAD_ARG_COUNT, argv.length);
binding = bootstrapMethod.invokeWithArguments(newargv);
} else {
MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
binding = spreader.invokeExact(typedBSM, (Object) caller, (Object) name, (Object) type, argv);
}
}
}
if (binding instanceof CallSite) {