< prev index next >

src/hotspot/share/oops/klassVtable.cpp

Print this page




 462 
 463       // Whether the method is being overridden
 464       bool overrides = false;
 465 
 466       // private methods are also never overridden
 467       if (!super_method->is_private() &&
 468           (is_default
 469           || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD))
 470           || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
 471           && ((super_klass = find_transitive_override(super_klass,
 472                              target_method, i, target_loader,
 473                              target_classname, THREAD))
 474                              != (InstanceKlass*)NULL)))))
 475         {
 476         // Package private methods always need a new entry to root their own
 477         // overriding. They may also override other methods.
 478         if (!target_method()->is_package_private()) {
 479           allocate_new = false;
 480         }
 481 
 482         if (checkconstraints) {



 483         // Override vtable entry if passes loader constraint check
 484         // if loader constraint checking requested
 485         // No need to visit his super, since he and his super
 486         // have already made any needed loader constraints.
 487         // Since loader constraints are transitive, it is enough
 488         // to link to the first super, and we get all the others.
 489           Handle super_loader(THREAD, super_klass->class_loader());
 490 
 491           if (target_loader() != super_loader()) {
 492             ResourceMark rm(THREAD);
 493             Symbol* failed_type_symbol =
 494               SystemDictionary::check_signature_loaders(signature, target_loader,
 495                                                         super_loader, true,
 496                                                         CHECK_(false));
 497             if (failed_type_symbol != NULL) {
 498               const char* msg = "loader constraint violation: when resolving "
 499                 "overridden method \"%s\" the class loader (instance"
 500                 " of %s) of the current class, %s, and its superclass loader "
 501                 "(instance of %s), have different Class objects for the type "
 502                 "%s used in the signature";
 503               char* sig = target_method()->name_and_sig_as_C_string();
 504               const char* loader1 = SystemDictionary::loader_name(target_loader());
 505               char* current = target_klass->name()->as_C_string();
 506               const char* loader2 = SystemDictionary::loader_name(super_loader());

 507               char* failed_type_name = failed_type_symbol->as_C_string();
 508               size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
 509                 strlen(current) + strlen(loader2) + strlen(failed_type_name);

 510               char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
 511               jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
 512                            failed_type_name);
 513               THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false);
 514             }
 515           }
 516         }
 517 
 518         put_method_at(target_method(), i);
 519         overrides = true;
 520         if (!is_default) {
 521           target_method()->set_vtable_index(i);
 522         } else {
 523           if (def_vtable_indices != NULL) {
 524             if (is_preinitialized_vtable()) {
 525               // At runtime initialize_vtable is rerun as part of link_class_impl()
 526               // for a shared class loaded by the non-boot loader.
 527               // The dumptime vtable index should be the same as the runtime index.
 528               assert(def_vtable_indices->at(default_index) == i,
 529                      "dump time vtable index is different from runtime index");
 530             } else {
 531               def_vtable_indices->at_put(default_index, i);
 532             }


1176   return length;
1177 }
1178 
1179 
1180 void klassItable::initialize_itable_for_interface(int method_table_offset, Klass* interf, bool checkconstraints, TRAPS) {
1181   Array<Method*>* methods = InstanceKlass::cast(interf)->methods();
1182   int nof_methods = methods->length();
1183   HandleMark hm;
1184   assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
1185   Handle interface_loader (THREAD, InstanceKlass::cast(interf)->class_loader());
1186 
1187   int ime_count = method_count_for_interface(interf);
1188   for (int i = 0; i < nof_methods; i++) {
1189     Method* m = methods->at(i);
1190     methodHandle target;
1191     if (m->has_itable_index()) {
1192       // This search must match the runtime resolution, i.e. selection search for invokeinterface
1193       // to correctly enforce loader constraints for interface method inheritance
1194       target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
1195     }
1196     if (target == NULL || !target->is_public() || target->is_abstract()) {
1197       // Entry does not resolve. Leave it empty for AbstractMethodError.
1198         if (!(target == NULL) && !target->is_public()) {
1199           // Stuff an IllegalAccessError throwing method in there instead.
1200           itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()].
1201               initialize(Universe::throw_illegal_access_error());
1202         }
1203     } else {
1204       // Entry did resolve, check loader constraints before initializing
1205       // if checkconstraints requested
1206       if (checkconstraints) {
1207         Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
1208         if (method_holder_loader() != interface_loader()) {
1209           ResourceMark rm(THREAD);
1210           Symbol* failed_type_symbol =
1211             SystemDictionary::check_signature_loaders(m->signature(),
1212                                                       method_holder_loader,
1213                                                       interface_loader,
1214                                                       true, CHECK);
1215           if (failed_type_symbol != NULL) {
1216             const char* msg = "loader constraint violation in interface "
1217               "itable initialization: when resolving method \"%s\" the class"
1218               " loader (instance of %s) of the current class, %s, "
1219               "and the class loader (instance of %s) for interface "
1220               "%s have different Class objects for the type %s "
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();
1225             const char* loader2 = SystemDictionary::loader_name(interface_loader());

1226             char* iface = InstanceKlass::cast(interf)->name()->as_C_string();


1227             char* failed_type_name = failed_type_symbol->as_C_string();
1228             size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
1229               strlen(current) + strlen(loader2) + strlen(iface) +
1230               strlen(failed_type_name);
1231             char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
1232             jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
1233                          iface, failed_type_name);
1234             THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
1235           }
1236         }
1237       }
1238 
1239       // ime may have moved during GC so recalculate address
1240       int ime_num = m->itable_index();
1241       assert(ime_num < ime_count, "oob");
1242       itableOffsetEntry::method_entry(_klass, method_table_offset)[ime_num].initialize(target());
1243       if (log_develop_is_enabled(Trace, itables)) {
1244         ResourceMark rm(THREAD);
1245         if (target() != NULL) {
1246           LogTarget(Trace, itables) lt;
1247           LogStream ls(lt);
1248           char* sig = target()->name_and_sig_as_C_string();
1249           ls.print("interface: %s, ime_num: %d, target: %s, method_holder: %s ",
1250                        interf->internal_name(), ime_num, sig,
1251                        target()->method_holder()->internal_name());
1252           ls.print("target_method flags: ");
1253           target()->print_linkage_flags(&ls);




 462 
 463       // Whether the method is being overridden
 464       bool overrides = false;
 465 
 466       // private methods are also never overridden
 467       if (!super_method->is_private() &&
 468           (is_default
 469           || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD))
 470           || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
 471           && ((super_klass = find_transitive_override(super_klass,
 472                              target_method, i, target_loader,
 473                              target_classname, THREAD))
 474                              != (InstanceKlass*)NULL)))))
 475         {
 476         // Package private methods always need a new entry to root their own
 477         // overriding. They may also override other methods.
 478         if (!target_method()->is_package_private()) {
 479           allocate_new = false;
 480         }
 481 
 482         // Do not check loader constraints for overpass methods because overpass
 483         // methods are created by the jvm to throw exceptions.  They are not
 484         // resolved methods.
 485         if (checkconstraints && !target_method()->is_overpass()) {
 486           // Override vtable entry if passes loader constraint check
 487           // if loader constraint checking requested
 488           // No need to visit his super, since he and his super
 489           // have already made any needed loader constraints.
 490           // Since loader constraints are transitive, it is enough
 491           // to link to the first super, and we get all the others.
 492           Handle super_loader(THREAD, super_klass->class_loader());
 493 
 494           if (target_loader() != super_loader()) {
 495             ResourceMark rm(THREAD);
 496             Symbol* failed_type_symbol =
 497               SystemDictionary::check_signature_loaders(signature, target_loader,
 498                                                         super_loader, true,
 499                                                         CHECK_(false));
 500             if (failed_type_symbol != NULL) {
 501               const char* msg = "loader constraint violation for class %s: when resolving "
 502                 "overriding method \"%s\" the class loader (instance of %s) of the "
 503                 "selected method's type, %s, and the class loader (instance of %s) for its super "
 504                 "type %s have different Class objects for the type %s used in the signature";
 505               char* curr_class = klass->name()->as_C_string();
 506               char* sig = target_method()->name_and_sig_as_C_string();
 507               const char* loader1 = SystemDictionary::loader_name(target_loader());
 508               char* sel_class = target_klass->name()->as_C_string();
 509               const char* loader2 = SystemDictionary::loader_name(super_loader());
 510               char* super_class = super_klass->name()->as_C_string();
 511               char* failed_type_name = failed_type_symbol->as_C_string();
 512               size_t buflen = strlen(msg) + strlen(curr_class) + strlen(sig) +
 513                 strlen(loader1) + strlen(sel_class) + strlen(loader2) +
 514                 strlen(super_class) + strlen(failed_type_name);
 515               char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
 516               jio_snprintf(buf, buflen, msg, curr_class, sig, loader1, sel_class, loader2,
 517                            super_class, failed_type_name);
 518               THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false);
 519             }
 520           }
 521         }
 522 
 523         put_method_at(target_method(), i);
 524         overrides = true;
 525         if (!is_default) {
 526           target_method()->set_vtable_index(i);
 527         } else {
 528           if (def_vtable_indices != NULL) {
 529             if (is_preinitialized_vtable()) {
 530               // At runtime initialize_vtable is rerun as part of link_class_impl()
 531               // for a shared class loaded by the non-boot loader.
 532               // The dumptime vtable index should be the same as the runtime index.
 533               assert(def_vtable_indices->at(default_index) == i,
 534                      "dump time vtable index is different from runtime index");
 535             } else {
 536               def_vtable_indices->at_put(default_index, i);
 537             }


1181   return length;
1182 }
1183 
1184 
1185 void klassItable::initialize_itable_for_interface(int method_table_offset, Klass* interf, bool checkconstraints, TRAPS) {
1186   Array<Method*>* methods = InstanceKlass::cast(interf)->methods();
1187   int nof_methods = methods->length();
1188   HandleMark hm;
1189   assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
1190   Handle interface_loader (THREAD, InstanceKlass::cast(interf)->class_loader());
1191 
1192   int ime_count = method_count_for_interface(interf);
1193   for (int i = 0; i < nof_methods; i++) {
1194     Method* m = methods->at(i);
1195     methodHandle target;
1196     if (m->has_itable_index()) {
1197       // This search must match the runtime resolution, i.e. selection search for invokeinterface
1198       // to correctly enforce loader constraints for interface method inheritance
1199       target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
1200     }
1201     if (target == NULL || !target->is_public() || target->is_abstract() || target->is_overpass()) {
1202       // Entry does not resolve. Leave it empty for AbstractMethodError.
1203       if (!(target == NULL) && !target->is_public()) {
1204         // Stuff an IllegalAccessError throwing method in there instead.
1205         itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()].
1206             initialize(Universe::throw_illegal_access_error());
1207       }
1208     } else {
1209       // Entry did resolve, check loader constraints before initializing
1210       // if checkconstraints requested
1211       if (checkconstraints) {
1212         Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
1213         if (method_holder_loader() != interface_loader()) {
1214           ResourceMark rm(THREAD);
1215           Symbol* failed_type_symbol =
1216             SystemDictionary::check_signature_loaders(m->signature(),
1217                                                       method_holder_loader,
1218                                                       interface_loader,
1219                                                       true, CHECK);
1220           if (failed_type_symbol != NULL) {
1221             const char* msg = "loader constraint violation in interface itable"
1222               " initialization for class %s: when resolving method \"%s\" the"
1223               " class loader (instance of %s) for super interface %s, and the class"
1224               " loader (instance of %s) of the selected method's type, %s have"
1225               " different Class objects for the type %s used in the signature";



1226             char* current = _klass->name()->as_C_string();
1227             char* sig = m->name_and_sig_as_C_string();
1228             const char* loader1 = SystemDictionary::loader_name(interface_loader());
1229             char* iface = InstanceKlass::cast(interf)->name()->as_C_string();
1230             const char* loader2 = SystemDictionary::loader_name(method_holder_loader());
1231             char* mclass = target()->method_holder()->name()->as_C_string();
1232             char* failed_type_name = failed_type_symbol->as_C_string();
1233             size_t buflen = strlen(msg) + strlen(current) + strlen(sig) +
1234               strlen(loader1) + strlen(iface) + strlen(loader2) + strlen(mclass) +
1235               strlen(failed_type_name);
1236             char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
1237             jio_snprintf(buf, buflen, msg, current, sig, loader1, iface,
1238                          loader2, mclass, failed_type_name);
1239             THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
1240           }
1241         }
1242       }
1243 
1244       // ime may have moved during GC so recalculate address
1245       int ime_num = m->itable_index();
1246       assert(ime_num < ime_count, "oob");
1247       itableOffsetEntry::method_entry(_klass, method_table_offset)[ime_num].initialize(target());
1248       if (log_develop_is_enabled(Trace, itables)) {
1249         ResourceMark rm(THREAD);
1250         if (target() != NULL) {
1251           LogTarget(Trace, itables) lt;
1252           LogStream ls(lt);
1253           char* sig = target()->name_and_sig_as_C_string();
1254           ls.print("interface: %s, ime_num: %d, target: %s, method_holder: %s ",
1255                        interf->internal_name(), ime_num, sig,
1256                        target()->method_holder()->internal_name());
1257           ls.print("target_method flags: ");
1258           target()->print_linkage_flags(&ls);


< prev index next >