477 // overriding. They may also override other methods. |
477 // overriding. They may also override other methods. |
478 if (!target_method()->is_package_private()) { |
478 if (!target_method()->is_package_private()) { |
479 allocate_new = false; |
479 allocate_new = false; |
480 } |
480 } |
481 |
481 |
482 if (checkconstraints) { |
482 // Do not check loader constraints for overpass methods because overpass |
483 // Override vtable entry if passes loader constraint check |
483 // methods are created by the jvm to throw exceptions. |
484 // if loader constraint checking requested |
484 if (checkconstraints && !target_method()->is_overpass()) { |
485 // No need to visit his super, since he and his super |
485 // Override vtable entry if passes loader constraint check |
486 // have already made any needed loader constraints. |
486 // if loader constraint checking requested |
487 // Since loader constraints are transitive, it is enough |
487 // No need to visit his super, since he and his super |
488 // to link to the first super, and we get all the others. |
488 // have already made any needed loader constraints. |
|
489 // Since loader constraints are transitive, it is enough |
|
490 // to link to the first super, and we get all the others. |
489 Handle super_loader(THREAD, super_klass->class_loader()); |
491 Handle super_loader(THREAD, super_klass->class_loader()); |
490 |
492 |
491 if (target_loader() != super_loader()) { |
493 if (target_loader() != super_loader()) { |
492 ResourceMark rm(THREAD); |
494 ResourceMark rm(THREAD); |
493 Symbol* failed_type_symbol = |
495 Symbol* failed_type_symbol = |
494 SystemDictionary::check_signature_loaders(signature, target_loader, |
496 SystemDictionary::check_signature_loaders(signature, target_loader, |
495 super_loader, true, |
497 super_loader, true, |
496 CHECK_(false)); |
498 CHECK_(false)); |
497 if (failed_type_symbol != NULL) { |
499 if (failed_type_symbol != NULL) { |
498 const char* msg = "loader constraint violation: when resolving " |
500 const char* msg = "loader constraint violation for class %s: when selecting " |
499 "overridden method \"%s\" the class loader (instance" |
501 "overriding method \"%s\" the class loader (instance of %s) of the " |
500 " of %s) of the current class, %s, and its superclass loader " |
502 "selected method's type %s, and the class loader (instance of %s) for its super " |
501 "(instance of %s), have different Class objects for the type " |
503 "type %s have different Class objects for the type %s used in the signature"; |
502 "%s used in the signature"; |
504 char* curr_class = klass->name()->as_C_string(); |
503 char* sig = target_method()->name_and_sig_as_C_string(); |
505 char* sig = target_method()->name_and_sig_as_C_string(); |
504 const char* loader1 = SystemDictionary::loader_name(target_loader()); |
506 const char* loader1 = SystemDictionary::loader_name(target_loader()); |
505 char* current = target_klass->name()->as_C_string(); |
507 char* sel_class = target_klass->name()->as_C_string(); |
506 const char* loader2 = SystemDictionary::loader_name(super_loader()); |
508 const char* loader2 = SystemDictionary::loader_name(super_loader()); |
|
509 char* super_class = super_klass->name()->as_C_string(); |
507 char* failed_type_name = failed_type_symbol->as_C_string(); |
510 char* failed_type_name = failed_type_symbol->as_C_string(); |
508 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
511 size_t buflen = strlen(msg) + strlen(curr_class) + strlen(sig) + |
509 strlen(current) + strlen(loader2) + strlen(failed_type_name); |
512 strlen(loader1) + strlen(sel_class) + strlen(loader2) + |
|
513 strlen(super_class) + strlen(failed_type_name); |
510 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
514 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
511 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
515 jio_snprintf(buf, buflen, msg, curr_class, sig, loader1, sel_class, loader2, |
512 failed_type_name); |
516 super_class, failed_type_name); |
513 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
517 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
514 } |
518 } |
515 } |
519 } |
516 } |
520 } |
517 |
521 |
1191 if (m->has_itable_index()) { |
1195 if (m->has_itable_index()) { |
1192 // This search must match the runtime resolution, i.e. selection search for invokeinterface |
1196 // This search must match the runtime resolution, i.e. selection search for invokeinterface |
1193 // to correctly enforce loader constraints for interface method inheritance |
1197 // to correctly enforce loader constraints for interface method inheritance |
1194 target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK); |
1198 target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK); |
1195 } |
1199 } |
1196 if (target == NULL || !target->is_public() || target->is_abstract()) { |
1200 if (target == NULL || !target->is_public() || target->is_abstract() || target->is_overpass()) { |
1197 // Entry does not resolve. Leave it empty for AbstractMethodError. |
1201 assert(target == NULL || !target->is_overpass() || target->is_public(), |
1198 if (!(target == NULL) && !target->is_public()) { |
1202 "Non-public overpass method!"); |
1199 // Stuff an IllegalAccessError throwing method in there instead. |
1203 // Entry does not resolve. Leave it empty for AbstractMethodError or other error. |
1200 itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()]. |
1204 if (!(target == NULL) && !target->is_public()) { |
1201 initialize(Universe::throw_illegal_access_error()); |
1205 // Stuff an IllegalAccessError throwing method in there instead. |
1202 } |
1206 itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()]. |
|
1207 initialize(Universe::throw_illegal_access_error()); |
|
1208 } |
1203 } else { |
1209 } else { |
1204 // Entry did resolve, check loader constraints before initializing |
1210 // Entry did resolve, check loader constraints before initializing |
1205 // if checkconstraints requested |
1211 // if checkconstraints requested |
1206 if (checkconstraints) { |
1212 if (checkconstraints) { |
1207 Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); |
1213 Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); |
1211 SystemDictionary::check_signature_loaders(m->signature(), |
1217 SystemDictionary::check_signature_loaders(m->signature(), |
1212 method_holder_loader, |
1218 method_holder_loader, |
1213 interface_loader, |
1219 interface_loader, |
1214 true, CHECK); |
1220 true, CHECK); |
1215 if (failed_type_symbol != NULL) { |
1221 if (failed_type_symbol != NULL) { |
1216 const char* msg = "loader constraint violation in interface " |
1222 const char* msg = "loader constraint violation in interface itable" |
1217 "itable initialization: when resolving method \"%s\" the class" |
1223 " initialization for class %s: when selecting method \"%s\" the" |
1218 " loader (instance of %s) of the current class, %s, " |
1224 " class loader (instance of %s) for super interface %s, and the class" |
1219 "and the class loader (instance of %s) for interface " |
1225 " loader (instance of %s) of the selected method's type, %s have" |
1220 "%s have different Class objects for the type %s " |
1226 " different Class objects for the type %s used in the signature"; |
1221 "used in the signature"; |
|
1222 char* sig = target()->name_and_sig_as_C_string(); |
|
1223 const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); |
|
1224 char* current = _klass->name()->as_C_string(); |
1227 char* current = _klass->name()->as_C_string(); |
1225 const char* loader2 = SystemDictionary::loader_name(interface_loader()); |
1228 char* sig = m->name_and_sig_as_C_string(); |
|
1229 const char* loader1 = SystemDictionary::loader_name(interface_loader()); |
1226 char* iface = InstanceKlass::cast(interf)->name()->as_C_string(); |
1230 char* iface = InstanceKlass::cast(interf)->name()->as_C_string(); |
|
1231 const char* loader2 = SystemDictionary::loader_name(method_holder_loader()); |
|
1232 char* mclass = target()->method_holder()->name()->as_C_string(); |
1227 char* failed_type_name = failed_type_symbol->as_C_string(); |
1233 char* failed_type_name = failed_type_symbol->as_C_string(); |
1228 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
1234 size_t buflen = strlen(msg) + strlen(current) + strlen(sig) + |
1229 strlen(current) + strlen(loader2) + strlen(iface) + |
1235 strlen(loader1) + strlen(iface) + strlen(loader2) + strlen(mclass) + |
1230 strlen(failed_type_name); |
1236 strlen(failed_type_name); |
1231 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
1237 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
1232 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
1238 jio_snprintf(buf, buflen, msg, current, sig, loader1, iface, |
1233 iface, failed_type_name); |
1239 loader2, mclass, failed_type_name); |
1234 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
1240 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
1235 } |
1241 } |
1236 } |
1242 } |
1237 } |
1243 } |
1238 |
1244 |