1.1 --- a/src/share/vm/prims/methodHandles.cpp Sat Apr 09 21:16:12 2011 -0700 1.2 +++ b/src/share/vm/prims/methodHandles.cpp Sat Apr 09 22:55:25 2011 -0700 1.3 @@ -928,6 +928,7 @@ 1.4 }; 1.5 1.6 static bool is_always_null_type(klassOop klass) { 1.7 + if (klass == NULL) return false; // safety 1.8 if (!Klass::cast(klass)->oop_is_instance()) return false; 1.9 instanceKlass* ik = instanceKlass::cast(klass); 1.10 // Must be on the boot class path: 1.11 @@ -944,6 +945,8 @@ 1.12 } 1.13 1.14 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { 1.15 + if (dst == NULL) return true; 1.16 + if (src == NULL) return (dst != SystemDictionary::Object_klass()); 1.17 if (src == dst || dst == SystemDictionary::Object_klass()) 1.18 return false; // quickest checks 1.19 Klass* srck = Klass::cast(src); 1.20 @@ -1026,10 +1029,15 @@ 1.21 int first_ptype_pos, 1.22 KlassHandle insert_ptype, 1.23 TRAPS) { 1.24 + Handle mhi_type; 1.25 + if (m->is_method_handle_invoke()) { 1.26 + // use this more exact typing instead of the symbolic signature: 1.27 + mhi_type = Handle(THREAD, m->method_handle_type()); 1.28 + } 1.29 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); 1.30 int pnum = first_ptype_pos; 1.31 int pmax = ptypes->length(); 1.32 - int mnum = 0; // method argument 1.33 + int anum = 0; // method argument 1.34 const char* err = NULL; 1.35 ResourceMark rm(THREAD); 1.36 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { 1.37 @@ -1048,47 +1056,70 @@ 1.38 else 1.39 ptype_oop = insert_ptype->java_mirror(); 1.40 pnum += 1; 1.41 - mnum += 1; 1.42 + anum += 1; 1.43 } 1.44 - klassOop pklass = NULL; 1.45 - BasicType ptype = T_OBJECT; 1.46 - if (ptype_oop != NULL) 1.47 - ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass); 1.48 - else 1.49 - // null does not match any non-reference; use Object to report the error 1.50 - pklass = SystemDictionary::Object_klass(); 1.51 - klassOop mklass = NULL; 1.52 - BasicType mtype = ss.type(); 1.53 - if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT 1.54 - if (mtype == T_OBJECT) { 1.55 - if (ptype_oop == NULL) { 1.56 + KlassHandle pklass; 1.57 + BasicType ptype = T_OBJECT; 1.58 + bool have_ptype = false; 1.59 + // missing ptype_oop does not match any non-reference; use Object to report the error 1.60 + pklass = SystemDictionaryHandles::Object_klass(); 1.61 + if (ptype_oop != NULL) { 1.62 + have_ptype = true; 1.63 + klassOop pklass_oop = NULL; 1.64 + ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop); 1.65 + pklass = KlassHandle(THREAD, pklass_oop); 1.66 + } 1.67 + ptype_oop = NULL; //done with this 1.68 + KlassHandle aklass; 1.69 + BasicType atype = ss.type(); 1.70 + if (atype == T_ARRAY) atype = T_OBJECT; // fold all refs to T_OBJECT 1.71 + if (atype == T_OBJECT) { 1.72 + if (!have_ptype) { 1.73 // null matches any reference 1.74 continue; 1.75 } 1.76 - KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; 1.77 - // If we fail to resolve types at this point, we will throw an error. 1.78 - Symbol* name = ss.as_symbol(CHECK); 1.79 - instanceKlass* mk = instanceKlass::cast(m->method_holder()); 1.80 - Handle loader(THREAD, mk->class_loader()); 1.81 - Handle domain(THREAD, mk->protection_domain()); 1.82 - mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); 1.83 - pklass = pklass_handle(); 1.84 - if (mklass == NULL && pklass != NULL && 1.85 - Klass::cast(pklass)->name() == name && 1.86 - m->is_method_handle_invoke()) { 1.87 - // Assume a match. We can't really decode the signature of MH.invoke*. 1.88 - continue; 1.89 + if (mhi_type.is_null()) { 1.90 + // If we fail to resolve types at this point, we will usually throw an error. 1.91 + TempNewSymbol name = ss.as_symbol_or_null(); 1.92 + if (name != NULL) { 1.93 + instanceKlass* mk = instanceKlass::cast(m->method_holder()); 1.94 + Handle loader(THREAD, mk->class_loader()); 1.95 + Handle domain(THREAD, mk->protection_domain()); 1.96 + klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); 1.97 + if (aklass_oop != NULL) 1.98 + aklass = KlassHandle(THREAD, aklass_oop); 1.99 + } 1.100 + } else { 1.101 + // for method handle invokers we don't look at the name in the signature 1.102 + oop atype_oop; 1.103 + if (ss.at_return_type()) 1.104 + atype_oop = java_lang_invoke_MethodType::rtype(mhi_type()); 1.105 + else 1.106 + atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1); 1.107 + klassOop aklass_oop = NULL; 1.108 + atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop); 1.109 + aklass = KlassHandle(THREAD, aklass_oop); 1.110 } 1.111 } 1.112 if (!ss.at_return_type()) { 1.113 - err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum); 1.114 + err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum); 1.115 } else { 1.116 - err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal! 1.117 + err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal! 1.118 } 1.119 if (err != NULL) break; 1.120 } 1.121 1.122 if (err != NULL) { 1.123 +#ifndef PRODUCT 1.124 + if (PrintMiscellaneous && (Verbose || WizardMode)) { 1.125 + tty->print("*** verify_method_signature failed: "); 1.126 + java_lang_invoke_MethodType::print_signature(mtype(), tty); 1.127 + tty->cr(); 1.128 + tty->print_cr(" first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype()); 1.129 + tty->print(" Failing method: "); 1.130 + m->print(); 1.131 + } 1.132 +#endif //PRODUCT 1.133 THROW_MSG(vmSymbols::java_lang_InternalError(), err); 1.134 } 1.135 } 1.136 @@ -1288,10 +1319,12 @@ 1.137 // format, format, format 1.138 const char* src_name = type2name(src_type); 1.139 const char* dst_name = type2name(dst_type); 1.140 - if (src_type == T_OBJECT) src_name = Klass::cast(src_klass)->external_name(); 1.141 - if (dst_type == T_OBJECT) dst_name = Klass::cast(dst_klass)->external_name(); 1.142 if (src_name == NULL) src_name = "unknown type"; 1.143 if (dst_name == NULL) dst_name = "unknown type"; 1.144 + if (src_type == T_OBJECT) 1.145 + src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class"; 1.146 + if (dst_type == T_OBJECT) 1.147 + dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; 1.148 1.149 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); 1.150 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);