src/share/classes/java/lang/invoke/CallSite.java
Print this page
rev 7978 : direct (fastpath) LambdaMetafactory invokation from callSite
*** 259,271 ****
String name, MethodType type,
// Extra arguments for BSM, if any:
Object info,
// Caller information:
Class<?> callerClass) {
! Object caller = IMPL_LOOKUP.in(callerClass);
! CallSite site;
try {
Object binding;
info = maybeReBox(info);
if (info == null) {
binding = bootstrapMethod.invoke(caller, name, type);
} else if (!info.getClass().isArray()) {
--- 259,275 ----
String name, MethodType type,
// Extra arguments for BSM, if any:
Object info,
// Caller information:
Class<?> callerClass) {
! MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
try {
+ CallSite site;
+ if(isLambdaMetafactory(bootstrapMethod, info)) { // LambdaMetafactory fastpath
+ Object[] argv = (Object[]) info;
+ site = LambdaMetafactory.metafactory(caller, name, type, (MethodType)argv[0], (MethodHandle)argv[1], (MethodType)argv[2]);
+ } else {
Object binding;
info = maybeReBox(info);
if (info == null) {
binding = bootstrapMethod.invoke(caller, name, type);
} else if (!info.getClass().isArray()) {
*** 280,306 ****
binding = bootstrapMethod.invoke(caller, name, type, argv);
else
binding = MethodHandles.spreadInvoker(bsmType, 3)
.invoke(bootstrapMethod, caller, name, type, argv);
}
- //System.out.println("BSM for "+name+type+" => "+binding);
if (binding instanceof CallSite) {
site = (CallSite) binding;
} else {
throw new ClassCastException("bootstrap method failed to produce a CallSite");
}
if (!site.getTarget().type().equals(type))
throw new WrongMethodTypeException("wrong type: "+site.getTarget());
} catch (Throwable ex) {
BootstrapMethodError bex;
if (ex instanceof BootstrapMethodError)
bex = (BootstrapMethodError) ex;
else
bex = new BootstrapMethodError("call site initialization exception", ex);
throw bex;
}
! return site;
}
private static Object maybeReBox(Object x) {
if (x instanceof Integer) {
int xi = (int) x;
--- 284,328 ----
binding = bootstrapMethod.invoke(caller, name, type, argv);
else
binding = MethodHandles.spreadInvoker(bsmType, 3)
.invoke(bootstrapMethod, caller, name, type, argv);
}
if (binding instanceof CallSite) {
site = (CallSite) binding;
} else {
throw new ClassCastException("bootstrap method failed to produce a CallSite");
}
+ }
if (!site.getTarget().type().equals(type))
throw new WrongMethodTypeException("wrong type: "+site.getTarget());
+ return site;
} catch (Throwable ex) {
BootstrapMethodError bex;
if (ex instanceof BootstrapMethodError)
bex = (BootstrapMethodError) ex;
else
bex = new BootstrapMethodError("call site initialization exception", ex);
throw bex;
}
!
! }
!
! private static boolean isLambdaMetafactory(MethodHandle mh, Object info) {
! MemberName mn = mh.internalMemberName();
! if ((mn != null) &&
! (mn.getDeclaringClass().equals(LambdaMetafactory.class)) &&
! (mn.getName().equals("metafactory")) &&
! (mn.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeStatic) &&
! (info instanceof Object[])) {
! Object[] argv = (Object[]) info;
! // checks info inconsistency -> let's slowpath throws all exceptions
! return (argv.length == 3) &&
! (argv[0] instanceof MethodType) &&
! (argv[1] instanceof MethodHandle) &&
! (argv[2] instanceof MethodType);
! }
! return false;
}
private static Object maybeReBox(Object x) {
if (x instanceof Integer) {
int xi = (int) x;