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); |