Mercurial > hg > truffle
comparison src/share/vm/prims/methodHandles.cpp @ 2478:328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
Summary: Make MH verification tests more correct, robust, and informative. Fix lingering symbol refcount problems.
Reviewed-by: twisti
author | jrose |
---|---|
date | Sat, 09 Apr 2011 22:55:25 -0700 |
parents | ed69575596ac |
children | 2a23b1b5a0a8 |
comparison
equal
deleted
inserted
replaced
2468:6c97c830fb6f | 2478:328926869b15 |
---|---|
926 "sun/invoke/empty/Empty", | 926 "sun/invoke/empty/Empty", |
927 NULL | 927 NULL |
928 }; | 928 }; |
929 | 929 |
930 static bool is_always_null_type(klassOop klass) { | 930 static bool is_always_null_type(klassOop klass) { |
931 if (klass == NULL) return false; // safety | |
931 if (!Klass::cast(klass)->oop_is_instance()) return false; | 932 if (!Klass::cast(klass)->oop_is_instance()) return false; |
932 instanceKlass* ik = instanceKlass::cast(klass); | 933 instanceKlass* ik = instanceKlass::cast(klass); |
933 // Must be on the boot class path: | 934 // Must be on the boot class path: |
934 if (ik->class_loader() != NULL) return false; | 935 if (ik->class_loader() != NULL) return false; |
935 // Check the name. | 936 // Check the name. |
942 } | 943 } |
943 return false; | 944 return false; |
944 } | 945 } |
945 | 946 |
946 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { | 947 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { |
948 if (dst == NULL) return true; | |
949 if (src == NULL) return (dst != SystemDictionary::Object_klass()); | |
947 if (src == dst || dst == SystemDictionary::Object_klass()) | 950 if (src == dst || dst == SystemDictionary::Object_klass()) |
948 return false; // quickest checks | 951 return false; // quickest checks |
949 Klass* srck = Klass::cast(src); | 952 Klass* srck = Klass::cast(src); |
950 Klass* dstk = Klass::cast(dst); | 953 Klass* dstk = Klass::cast(dst); |
951 if (dstk->is_interface()) { | 954 if (dstk->is_interface()) { |
1024 void MethodHandles::verify_method_signature(methodHandle m, | 1027 void MethodHandles::verify_method_signature(methodHandle m, |
1025 Handle mtype, | 1028 Handle mtype, |
1026 int first_ptype_pos, | 1029 int first_ptype_pos, |
1027 KlassHandle insert_ptype, | 1030 KlassHandle insert_ptype, |
1028 TRAPS) { | 1031 TRAPS) { |
1032 Handle mhi_type; | |
1033 if (m->is_method_handle_invoke()) { | |
1034 // use this more exact typing instead of the symbolic signature: | |
1035 mhi_type = Handle(THREAD, m->method_handle_type()); | |
1036 } | |
1029 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); | 1037 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); |
1030 int pnum = first_ptype_pos; | 1038 int pnum = first_ptype_pos; |
1031 int pmax = ptypes->length(); | 1039 int pmax = ptypes->length(); |
1032 int mnum = 0; // method argument | 1040 int anum = 0; // method argument |
1033 const char* err = NULL; | 1041 const char* err = NULL; |
1034 ResourceMark rm(THREAD); | 1042 ResourceMark rm(THREAD); |
1035 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { | 1043 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1036 oop ptype_oop = NULL; | 1044 oop ptype_oop = NULL; |
1037 if (ss.at_return_type()) { | 1045 if (ss.at_return_type()) { |
1046 else if (insert_ptype.is_null()) | 1054 else if (insert_ptype.is_null()) |
1047 ptype_oop = NULL; | 1055 ptype_oop = NULL; |
1048 else | 1056 else |
1049 ptype_oop = insert_ptype->java_mirror(); | 1057 ptype_oop = insert_ptype->java_mirror(); |
1050 pnum += 1; | 1058 pnum += 1; |
1051 mnum += 1; | 1059 anum += 1; |
1052 } | 1060 } |
1053 klassOop pklass = NULL; | 1061 KlassHandle pklass; |
1054 BasicType ptype = T_OBJECT; | 1062 BasicType ptype = T_OBJECT; |
1055 if (ptype_oop != NULL) | 1063 bool have_ptype = false; |
1056 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass); | 1064 // missing ptype_oop does not match any non-reference; use Object to report the error |
1057 else | 1065 pklass = SystemDictionaryHandles::Object_klass(); |
1058 // null does not match any non-reference; use Object to report the error | 1066 if (ptype_oop != NULL) { |
1059 pklass = SystemDictionary::Object_klass(); | 1067 have_ptype = true; |
1060 klassOop mklass = NULL; | 1068 klassOop pklass_oop = NULL; |
1061 BasicType mtype = ss.type(); | 1069 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop); |
1062 if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT | 1070 pklass = KlassHandle(THREAD, pklass_oop); |
1063 if (mtype == T_OBJECT) { | 1071 } |
1064 if (ptype_oop == NULL) { | 1072 ptype_oop = NULL; //done with this |
1073 KlassHandle aklass; | |
1074 BasicType atype = ss.type(); | |
1075 if (atype == T_ARRAY) atype = T_OBJECT; // fold all refs to T_OBJECT | |
1076 if (atype == T_OBJECT) { | |
1077 if (!have_ptype) { | |
1065 // null matches any reference | 1078 // null matches any reference |
1066 continue; | 1079 continue; |
1067 } | 1080 } |
1068 KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; | 1081 if (mhi_type.is_null()) { |
1069 // If we fail to resolve types at this point, we will throw an error. | 1082 // If we fail to resolve types at this point, we will usually throw an error. |
1070 Symbol* name = ss.as_symbol(CHECK); | 1083 TempNewSymbol name = ss.as_symbol_or_null(); |
1071 instanceKlass* mk = instanceKlass::cast(m->method_holder()); | 1084 if (name != NULL) { |
1072 Handle loader(THREAD, mk->class_loader()); | 1085 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
1073 Handle domain(THREAD, mk->protection_domain()); | 1086 Handle loader(THREAD, mk->class_loader()); |
1074 mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); | 1087 Handle domain(THREAD, mk->protection_domain()); |
1075 pklass = pklass_handle(); | 1088 klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1076 if (mklass == NULL && pklass != NULL && | 1089 if (aklass_oop != NULL) |
1077 Klass::cast(pklass)->name() == name && | 1090 aklass = KlassHandle(THREAD, aklass_oop); |
1078 m->is_method_handle_invoke()) { | 1091 } |
1079 // Assume a match. We can't really decode the signature of MH.invoke*. | 1092 } else { |
1080 continue; | 1093 // for method handle invokers we don't look at the name in the signature |
1094 oop atype_oop; | |
1095 if (ss.at_return_type()) | |
1096 atype_oop = java_lang_invoke_MethodType::rtype(mhi_type()); | |
1097 else | |
1098 atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1); | |
1099 klassOop aklass_oop = NULL; | |
1100 atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop); | |
1101 aklass = KlassHandle(THREAD, aklass_oop); | |
1081 } | 1102 } |
1082 } | 1103 } |
1083 if (!ss.at_return_type()) { | 1104 if (!ss.at_return_type()) { |
1084 err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum); | 1105 err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum); |
1085 } else { | 1106 } else { |
1086 err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal! | 1107 err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal! |
1087 } | 1108 } |
1088 if (err != NULL) break; | 1109 if (err != NULL) break; |
1089 } | 1110 } |
1090 | 1111 |
1091 if (err != NULL) { | 1112 if (err != NULL) { |
1113 #ifndef PRODUCT | |
1114 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1115 tty->print("*** verify_method_signature failed: "); | |
1116 java_lang_invoke_MethodType::print_signature(mtype(), tty); | |
1117 tty->cr(); | |
1118 tty->print_cr(" first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype()); | |
1119 tty->print(" Failing method: "); | |
1120 m->print(); | |
1121 } | |
1122 #endif //PRODUCT | |
1092 THROW_MSG(vmSymbols::java_lang_InternalError(), err); | 1123 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1093 } | 1124 } |
1094 } | 1125 } |
1095 | 1126 |
1096 // Main routine for verifying the MethodHandle.type of a proposed | 1127 // Main routine for verifying the MethodHandle.type of a proposed |
1286 } | 1317 } |
1287 | 1318 |
1288 // format, format, format | 1319 // format, format, format |
1289 const char* src_name = type2name(src_type); | 1320 const char* src_name = type2name(src_type); |
1290 const char* dst_name = type2name(dst_type); | 1321 const char* dst_name = type2name(dst_type); |
1291 if (src_type == T_OBJECT) src_name = Klass::cast(src_klass)->external_name(); | |
1292 if (dst_type == T_OBJECT) dst_name = Klass::cast(dst_klass)->external_name(); | |
1293 if (src_name == NULL) src_name = "unknown type"; | 1322 if (src_name == NULL) src_name = "unknown type"; |
1294 if (dst_name == NULL) dst_name = "unknown type"; | 1323 if (dst_name == NULL) dst_name = "unknown type"; |
1324 if (src_type == T_OBJECT) | |
1325 src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class"; | |
1326 if (dst_type == T_OBJECT) | |
1327 dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; | |
1295 | 1328 |
1296 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); | 1329 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); |
1297 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); | 1330 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); |
1298 if (argnum >= 0) { | 1331 if (argnum >= 0) { |
1299 assert(strstr(err, "%d") != NULL, ""); | 1332 assert(strstr(err, "%d") != NULL, ""); |