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;