src/share/classes/java/lang/invoke/LambdaForm.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/LambdaForm.java

Print this page
rev 10271 : 8037209: Improvements and cleanups to bytecode assembly for lambda forms
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
rev 10274 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10275 : imported patch invokers


1130         @Override
1131         public int hashCode() {
1132             if (member != null)
1133                 return member.hashCode();
1134             return super.hashCode();
1135         }
1136 
1137         // Put the predefined NamedFunction invokers into the table.
1138         static void initializeInvokers() {
1139             for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
1140                 if (!m.isStatic() || !m.isPackage())  continue;
1141                 MethodType type = m.getMethodType();
1142                 if (type.equals(INVOKER_METHOD_TYPE) &&
1143                     m.getName().startsWith("invoke_")) {
1144                     String sig = m.getName().substring("invoke_".length());
1145                     int arity = LambdaForm.signatureArity(sig);
1146                     MethodType srcType = MethodType.genericMethodType(arity);
1147                     if (LambdaForm.signatureReturn(sig) == V_TYPE)
1148                         srcType = srcType.changeReturnType(void.class);
1149                     MethodTypeForm typeForm = srcType.form();
1150                     typeForm.namedFunctionInvoker = DirectMethodHandle.make(m);
1151                 }
1152             }
1153         }
1154 
1155         // The following are predefined NamedFunction invokers.  The system must build
1156         // a separate invoker for each distinct signature.
1157         /** void return type invokers. */
1158         @Hidden
1159         static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
1160             assert(arityCheck(0, void.class, mh, a));
1161             mh.invokeBasic();
1162             return null;
1163         }
1164         @Hidden
1165         static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
1166             assert(arityCheck(1, void.class, mh, a));
1167             mh.invokeBasic(a[0]);
1168             return null;
1169         }
1170         @Hidden


1228         private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
1229             assert(a.length == arity)
1230                     : Arrays.asList(a.length, arity);
1231             assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
1232                     : Arrays.asList(mh, rtype, arity);
1233             MemberName member = mh.internalMemberName();
1234             if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) {
1235                 assert(arity > 0);
1236                 assert(a[0] instanceof MethodHandle);
1237                 MethodHandle mh2 = (MethodHandle) a[0];
1238                 assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
1239                         : Arrays.asList(member, mh2, rtype, arity);
1240             }
1241             return true;
1242         }
1243 
1244         static final MethodType INVOKER_METHOD_TYPE =
1245             MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
1246 
1247         private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
1248             MethodHandle mh = typeForm.namedFunctionInvoker;

1249             if (mh != null)  return mh;
1250             MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm);  // this could take a while
1251             mh = DirectMethodHandle.make(invoker);
1252             MethodHandle mh2 = typeForm.namedFunctionInvoker;
1253             if (mh2 != null)  return mh2;  // benign race
1254             if (!mh.type().equals(INVOKER_METHOD_TYPE))
1255                 throw newInternalError(mh.debugString());
1256             return typeForm.namedFunctionInvoker = mh;
1257         }
1258 
1259         @Hidden
1260         Object invokeWithArguments(Object... arguments) throws Throwable {
1261             // If we have a cached invoker, call it right away.
1262             // NOTE: The invoker always returns a reference value.
1263             if (TRACE_INTERPRETER)  return invokeWithArgumentsTracing(arguments);
1264             assert(checkArgumentTypes(arguments, methodType()));
1265             return invoker().invokeBasic(resolvedHandle(), arguments);
1266         }
1267 
1268         @Hidden
1269         Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
1270             Object rval;
1271             try {
1272                 traceInterpreter("[ call", this, arguments);
1273                 if (invoker == null) {
1274                     traceInterpreter("| getInvoker", this);
1275                     invoker();
1276                 }




1130         @Override
1131         public int hashCode() {
1132             if (member != null)
1133                 return member.hashCode();
1134             return super.hashCode();
1135         }
1136 
1137         // Put the predefined NamedFunction invokers into the table.
1138         static void initializeInvokers() {
1139             for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
1140                 if (!m.isStatic() || !m.isPackage())  continue;
1141                 MethodType type = m.getMethodType();
1142                 if (type.equals(INVOKER_METHOD_TYPE) &&
1143                     m.getName().startsWith("invoke_")) {
1144                     String sig = m.getName().substring("invoke_".length());
1145                     int arity = LambdaForm.signatureArity(sig);
1146                     MethodType srcType = MethodType.genericMethodType(arity);
1147                     if (LambdaForm.signatureReturn(sig) == V_TYPE)
1148                         srcType = srcType.changeReturnType(void.class);
1149                     MethodTypeForm typeForm = srcType.form();
1150                     typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m));
1151                 }
1152             }
1153         }
1154 
1155         // The following are predefined NamedFunction invokers.  The system must build
1156         // a separate invoker for each distinct signature.
1157         /** void return type invokers. */
1158         @Hidden
1159         static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
1160             assert(arityCheck(0, void.class, mh, a));
1161             mh.invokeBasic();
1162             return null;
1163         }
1164         @Hidden
1165         static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
1166             assert(arityCheck(1, void.class, mh, a));
1167             mh.invokeBasic(a[0]);
1168             return null;
1169         }
1170         @Hidden


1228         private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
1229             assert(a.length == arity)
1230                     : Arrays.asList(a.length, arity);
1231             assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
1232                     : Arrays.asList(mh, rtype, arity);
1233             MemberName member = mh.internalMemberName();
1234             if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) {
1235                 assert(arity > 0);
1236                 assert(a[0] instanceof MethodHandle);
1237                 MethodHandle mh2 = (MethodHandle) a[0];
1238                 assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
1239                         : Arrays.asList(member, mh2, rtype, arity);
1240             }
1241             return true;
1242         }
1243 
1244         static final MethodType INVOKER_METHOD_TYPE =
1245             MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
1246 
1247         private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
1248             typeForm = typeForm.basicType().form();  // normalize to basic type
1249             MethodHandle mh = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
1250             if (mh != null)  return mh;
1251             MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm);  // this could take a while
1252             mh = DirectMethodHandle.make(invoker);
1253             MethodHandle mh2 = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
1254             if (mh2 != null)  return mh2;  // benign race
1255             if (!mh.type().equals(INVOKER_METHOD_TYPE))
1256                 throw newInternalError(mh.debugString());
1257             return typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, mh);
1258         }
1259 
1260         @Hidden
1261         Object invokeWithArguments(Object... arguments) throws Throwable {
1262             // If we have a cached invoker, call it right away.
1263             // NOTE: The invoker always returns a reference value.
1264             if (TRACE_INTERPRETER)  return invokeWithArgumentsTracing(arguments);
1265             assert(checkArgumentTypes(arguments, methodType()));
1266             return invoker().invokeBasic(resolvedHandle(), arguments);
1267         }
1268 
1269         @Hidden
1270         Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
1271             Object rval;
1272             try {
1273                 traceInterpreter("[ call", this, arguments);
1274                 if (invoker == null) {
1275                     traceInterpreter("| getInvoker", this);
1276                     invoker();
1277                 }


src/share/classes/java/lang/invoke/LambdaForm.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File