jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
changeset 44591 b9bf065070fe
parent 44590 15a77e5b7612
child 44592 6b028630b652
equal deleted inserted replaced
44590:15a77e5b7612 44591:b9bf065070fe
   639     MethodType methodType() {
   639     MethodType methodType() {
   640         Class<?>[] ptypes = new Class<?>[arity];
   640         Class<?>[] ptypes = new Class<?>[arity];
   641         for (int i = 0; i < arity; ++i) {
   641         for (int i = 0; i < arity; ++i) {
   642             ptypes[i] = parameterType(i).btClass;
   642             ptypes[i] = parameterType(i).btClass;
   643         }
   643         }
   644         return MethodType.methodType(returnType().btClass, ptypes);
   644         return MethodType.makeImpl(returnType().btClass, ptypes, true);
   645     }
   645     }
   646 
   646 
   647     /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
   647     /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
   648     final String basicTypeSignature() {
   648     final String basicTypeSignature() {
   649         StringBuilder buf = new StringBuilder(arity() + 3);
   649         StringBuilder buf = new StringBuilder(arity() + 3);
   675     static MethodType signatureType(String sig) {
   675     static MethodType signatureType(String sig) {
   676         Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
   676         Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
   677         for (int i = 0; i < ptypes.length; i++)
   677         for (int i = 0; i < ptypes.length; i++)
   678             ptypes[i] = basicType(sig.charAt(i)).btClass;
   678             ptypes[i] = basicType(sig.charAt(i)).btClass;
   679         Class<?> rtype = signatureReturn(sig).btClass;
   679         Class<?> rtype = signatureReturn(sig).btClass;
   680         return MethodType.methodType(rtype, ptypes);
   680         return MethodType.makeImpl(rtype, ptypes, true);
   681     }
   681     }
   682 
   682 
   683     /**
   683     /**
   684      * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
   684      * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
   685      */
   685      */
   845             return; // this should not be compiled
   845             return; // this should not be compiled
   846         }
   846         }
   847         if (vmentry != null && isCompiled) {
   847         if (vmentry != null && isCompiled) {
   848             return;  // already compiled somehow
   848             return;  // already compiled somehow
   849         }
   849         }
   850         MethodType invokerType = methodType();
   850         assert(vmentry == null || vmentry.getMethodType().basicType().equals(methodType()));
   851         assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
       
   852         try {
   851         try {
   853             vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
   852             vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this);
   854             if (TRACE_INTERPRETER)
   853             if (TRACE_INTERPRETER)
   855                 traceInterpreter("compileToBytecode", this);
   854                 traceInterpreter("compileToBytecode", this);
   856             isCompiled = true;
   855             isCompiled = true;
   857         } catch (InvokerBytecodeGenerator.BytecodeGenerationException bge) {
   856         } catch (InvokerBytecodeGenerator.BytecodeGenerationException bge) {
   858             // bytecode generation failed - mark this LambdaForm as to be run in interpretation mode only
   857             // bytecode generation failed - mark this LambdaForm as to be run in interpretation mode only
   898         case L_TYPE: assert checkRef(type, x)   : "checkRef(" + type + "," + x + ")";  break;
   897         case L_TYPE: assert checkRef(type, x)   : "checkRef(" + type + "," + x + ")";  break;
   899         case V_TYPE: break;  // allow anything here; will be dropped
   898         case V_TYPE: break;  // allow anything here; will be dropped
   900         default:  assert(false);
   899         default:  assert(false);
   901         }
   900         }
   902         return true;
   901         return true;
   903     }
       
   904     private static boolean returnTypesMatch(String sig, Object[] av, Object res) {
       
   905         MethodHandle mh = (MethodHandle) av[0];
       
   906         return valueMatches(signatureReturn(sig), mh.type().returnType(), res);
       
   907     }
   902     }
   908     private static boolean checkInt(Class<?> type, Object x) {
   903     private static boolean checkInt(Class<?> type, Object x) {
   909         assert(x instanceof Integer);
   904         assert(x instanceof Integer);
   910         if (type == int.class)  return true;
   905         if (type == int.class)  return true;
   911         Wrapper w = Wrapper.forBasicType(type);
   906         Wrapper w = Wrapper.forBasicType(type);
  1177         @Hidden
  1172         @Hidden
  1178         Object invokeWithArguments(Object... arguments) throws Throwable {
  1173         Object invokeWithArguments(Object... arguments) throws Throwable {
  1179             // If we have a cached invoker, call it right away.
  1174             // If we have a cached invoker, call it right away.
  1180             // NOTE: The invoker always returns a reference value.
  1175             // NOTE: The invoker always returns a reference value.
  1181             if (TRACE_INTERPRETER)  return invokeWithArgumentsTracing(arguments);
  1176             if (TRACE_INTERPRETER)  return invokeWithArgumentsTracing(arguments);
  1182             assert(checkArgumentTypes(arguments, methodType()));
       
  1183             return invoker().invokeBasic(resolvedHandle(), arguments);
  1177             return invoker().invokeBasic(resolvedHandle(), arguments);
  1184         }
  1178         }
  1185 
  1179 
  1186         @Hidden
  1180         @Hidden
  1187         Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
  1181         Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
  1195                 // resolvedHandle might be uninitialized, ok for tracing
  1189                 // resolvedHandle might be uninitialized, ok for tracing
  1196                 if (resolvedHandle == null) {
  1190                 if (resolvedHandle == null) {
  1197                     traceInterpreter("| resolve", this);
  1191                     traceInterpreter("| resolve", this);
  1198                     resolvedHandle();
  1192                     resolvedHandle();
  1199                 }
  1193                 }
  1200                 assert(checkArgumentTypes(arguments, methodType()));
       
  1201                 rval = invoker().invokeBasic(resolvedHandle(), arguments);
  1194                 rval = invoker().invokeBasic(resolvedHandle(), arguments);
  1202             } catch (Throwable ex) {
  1195             } catch (Throwable ex) {
  1203                 traceInterpreter("] throw =>", ex);
  1196                 traceInterpreter("] throw =>", ex);
  1204                 throw ex;
  1197                 throw ex;
  1205             }
  1198             }
  1209 
  1202 
  1210         private MethodHandle invoker() {
  1203         private MethodHandle invoker() {
  1211             if (invoker != null)  return invoker;
  1204             if (invoker != null)  return invoker;
  1212             // Get an invoker and cache it.
  1205             // Get an invoker and cache it.
  1213             return invoker = computeInvoker(methodType().form());
  1206             return invoker = computeInvoker(methodType().form());
  1214         }
       
  1215 
       
  1216         private static boolean checkArgumentTypes(Object[] arguments, MethodType methodType) {
       
  1217             if (true)  return true;  // FIXME
       
  1218             MethodType dstType = methodType.form().erasedType();
       
  1219             MethodType srcType = dstType.basicType().wrap();
       
  1220             Class<?>[] ptypes = new Class<?>[arguments.length];
       
  1221             for (int i = 0; i < arguments.length; i++) {
       
  1222                 Object arg = arguments[i];
       
  1223                 Class<?> ptype = arg == null ? Object.class : arg.getClass();
       
  1224                 // If the dest. type is a primitive we keep the
       
  1225                 // argument type.
       
  1226                 ptypes[i] = dstType.parameterType(i).isPrimitive() ? ptype : Object.class;
       
  1227             }
       
  1228             MethodType argType = MethodType.methodType(srcType.returnType(), ptypes).wrap();
       
  1229             assert(argType.isConvertibleTo(srcType)) : "wrong argument types: cannot convert " + argType + " to " + srcType;
       
  1230             return true;
       
  1231         }
  1207         }
  1232 
  1208 
  1233         MethodType methodType() {
  1209         MethodType methodType() {
  1234             if (resolvedHandle != null)
  1210             if (resolvedHandle != null)
  1235                 return resolvedHandle.type();
  1211                 return resolvedHandle.type();
  1723         }
  1699         }
  1724         char btChar = type.basicTypeChar();
  1700         char btChar = type.basicTypeChar();
  1725         boolean isVoid = (type == V_TYPE);
  1701         boolean isVoid = (type == V_TYPE);
  1726         Class<?> btClass = type.btClass;
  1702         Class<?> btClass = type.btClass;
  1727         MethodType zeType = MethodType.methodType(btClass);
  1703         MethodType zeType = MethodType.methodType(btClass);
  1728         MethodType idType = (isVoid) ? zeType : zeType.appendParameterTypes(btClass);
  1704         MethodType idType = (isVoid) ? zeType : MethodType.methodType(btClass, btClass);
  1729 
  1705 
  1730         // Look up symbolic names.  It might not be necessary to have these,
  1706         // Look up symbolic names.  It might not be necessary to have these,
  1731         // but if we need to emit direct references to bytecodes, it helps.
  1707         // but if we need to emit direct references to bytecodes, it helps.
  1732         // Zero is built from a call to an identity function with a constant zero input.
  1708         // Zero is built from a call to an identity function with a constant zero input.
  1733         MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
  1709         MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);