hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 14488 ab48109f7d1b
parent 14391 df0a1573d5bd
child 14583 d70ee55535f4
equal deleted inserted replaced
14486:7d079e0eedef 14488:ab48109f7d1b
   201 // returns first instance method
   201 // returns first instance method
   202 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
   202 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
   203   Method* result_oop = klass->uncached_lookup_method(name, signature);
   203   Method* result_oop = klass->uncached_lookup_method(name, signature);
   204   result = methodHandle(THREAD, result_oop);
   204   result = methodHandle(THREAD, result_oop);
   205   while (!result.is_null() && result->is_static()) {
   205   while (!result.is_null() && result->is_static()) {
   206     klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
   206     klass = KlassHandle(THREAD, result->method_holder()->super());
   207     result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
   207     result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
   208   }
   208   }
   209 }
   209 }
   210 
   210 
   211 
   211 
   426 
   426 
   427     if (resolved_method.is_null()) {
   427     if (resolved_method.is_null()) {
   428       // 3. method lookup failed
   428       // 3. method lookup failed
   429       ResourceMark rm(THREAD);
   429       ResourceMark rm(THREAD);
   430       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
   430       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
   431                       Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   431                       Method::name_and_sig_as_C_string(resolved_klass(),
   432                                                               method_name,
   432                                                               method_name,
   433                                                               method_signature),
   433                                                               method_signature),
   434                       nested_exception);
   434                       nested_exception);
   435     }
   435     }
   436   }
   436   }
   446 
   446 
   447   // 5. check if method is concrete
   447   // 5. check if method is concrete
   448   if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   448   if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   449     ResourceMark rm(THREAD);
   449     ResourceMark rm(THREAD);
   450     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   450     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   451               Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   451               Method::name_and_sig_as_C_string(resolved_klass(),
   452                                                       method_name,
   452                                                       method_name,
   453                                                       method_signature));
   453                                                       method_signature));
   454   }
   454   }
   455 
   455 
   456   // 6. access checks, access checking may be turned off when calling from within the VM.
   456   // 6. access checks, access checking may be turned off when calling from within the VM.
   475       if (failed_type_name != NULL) {
   475       if (failed_type_name != NULL) {
   476         const char* msg = "loader constraint violation: when resolving method"
   476         const char* msg = "loader constraint violation: when resolving method"
   477           " \"%s\" the class loader (instance of %s) of the current class, %s,"
   477           " \"%s\" the class loader (instance of %s) of the current class, %s,"
   478           " and the class loader (instance of %s) for resolved class, %s, have"
   478           " and the class loader (instance of %s) for resolved class, %s, have"
   479           " different Class objects for the type %s used in the signature";
   479           " different Class objects for the type %s used in the signature";
   480         char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
   480         char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
   481         const char* loader1 = SystemDictionary::loader_name(loader());
   481         const char* loader1 = SystemDictionary::loader_name(loader());
   482         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
   482         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
   483         const char* loader2 = SystemDictionary::loader_name(class_loader());
   483         const char* loader2 = SystemDictionary::loader_name(class_loader());
   484         char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
   484         char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
   485         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   485         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   503 
   503 
   504  // check if klass is interface
   504  // check if klass is interface
   505   if (!resolved_klass->is_interface()) {
   505   if (!resolved_klass->is_interface()) {
   506     ResourceMark rm(THREAD);
   506     ResourceMark rm(THREAD);
   507     char buf[200];
   507     char buf[200];
   508     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name());
   508     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
   509     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   509     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   510   }
   510   }
   511 
   511 
   512   // lookup method in this interface or its super, java.lang.Object
   512   // lookup method in this interface or its super, java.lang.Object
   513   lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   513   lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   517     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   517     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   518     if (resolved_method.is_null()) {
   518     if (resolved_method.is_null()) {
   519       // no method found
   519       // no method found
   520       ResourceMark rm(THREAD);
   520       ResourceMark rm(THREAD);
   521       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   521       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   522                 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   522                 Method::name_and_sig_as_C_string(resolved_klass(),
   523                                                         method_name,
   523                                                         method_name,
   524                                                         method_signature));
   524                                                         method_signature));
   525     }
   525     }
   526   }
   526   }
   527 
   527 
   538         const char* msg = "loader constraint violation: when resolving "
   538         const char* msg = "loader constraint violation: when resolving "
   539           "interface method \"%s\" the class loader (instance of %s) of the "
   539           "interface method \"%s\" the class loader (instance of %s) of the "
   540           "current class, %s, and the class loader (instance of %s) for "
   540           "current class, %s, and the class loader (instance of %s) for "
   541           "resolved class, %s, have different Class objects for the type %s "
   541           "resolved class, %s, have different Class objects for the type %s "
   542           "used in the signature";
   542           "used in the signature";
   543         char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
   543         char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
   544         const char* loader1 = SystemDictionary::loader_name(loader());
   544         const char* loader1 = SystemDictionary::loader_name(loader());
   545         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
   545         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
   546         const char* loader2 = SystemDictionary::loader_name(class_loader());
   546         const char* loader2 = SystemDictionary::loader_name(class_loader());
   547         char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
   547         char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
   548         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   548         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   625 
   625 
   626   // check for errors
   626   // check for errors
   627   if (is_static != fd.is_static()) {
   627   if (is_static != fd.is_static()) {
   628     ResourceMark rm(THREAD);
   628     ResourceMark rm(THREAD);
   629     char msg[200];
   629     char msg[200];
   630     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", Klass::cast(resolved_klass())->external_name(), fd.name()->as_C_string());
   630     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
   631     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
   631     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
   632   }
   632   }
   633 
   633 
   634   // Final fields can only be accessed from its own class.
   634   // Final fields can only be accessed from its own class.
   635   if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
   635   if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
   699 void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name,
   699 void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name,
   700                                        Symbol* method_signature, KlassHandle current_klass,
   700                                        Symbol* method_signature, KlassHandle current_klass,
   701                                        bool check_access, bool initialize_class, TRAPS) {
   701                                        bool check_access, bool initialize_class, TRAPS) {
   702   methodHandle resolved_method;
   702   methodHandle resolved_method;
   703   linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   703   linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   704   resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder()));
   704   resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
   705 
   705 
   706   // Initialize klass (this should only happen if everything is ok)
   706   // Initialize klass (this should only happen if everything is ok)
   707   if (initialize_class && resolved_klass->should_be_initialized()) {
   707   if (initialize_class && resolved_klass->should_be_initialized()) {
   708     resolved_klass->initialize(CHECK);
   708     resolved_klass->initialize(CHECK);
   709     linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   709     linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   723 
   723 
   724   // check if static
   724   // check if static
   725   if (!resolved_method->is_static()) {
   725   if (!resolved_method->is_static()) {
   726     ResourceMark rm(THREAD);
   726     ResourceMark rm(THREAD);
   727     char buf[200];
   727     char buf[200];
   728     jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   728     jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
   729                                                       resolved_method->name(),
   729                                                       resolved_method->name(),
   730                                                       resolved_method->signature()));
   730                                                       resolved_method->signature()));
   731     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   731     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   732   }
   732   }
   733 }
   733 }
   787   if (resolved_method->is_static()) {
   787   if (resolved_method->is_static()) {
   788     ResourceMark rm(THREAD);
   788     ResourceMark rm(THREAD);
   789     char buf[200];
   789     char buf[200];
   790     jio_snprintf(buf, sizeof(buf),
   790     jio_snprintf(buf, sizeof(buf),
   791                  "Expecting non-static method %s",
   791                  "Expecting non-static method %s",
   792                  Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   792                  Method::name_and_sig_as_C_string(resolved_klass(),
   793                                                          resolved_method->name(),
   793                                                          resolved_method->name(),
   794                                                          resolved_method->signature()));
   794                                                          resolved_method->signature()));
   795     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   795     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   796   }
   796   }
   797 }
   797 }
   827                            resolved_method->signature(), CHECK);
   827                            resolved_method->signature(), CHECK);
   828       // check if found
   828       // check if found
   829       if (sel_method.is_null()) {
   829       if (sel_method.is_null()) {
   830         ResourceMark rm(THREAD);
   830         ResourceMark rm(THREAD);
   831         THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   831         THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   832                   Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   832                   Method::name_and_sig_as_C_string(resolved_klass(),
   833                                             resolved_method->name(),
   833                                             resolved_method->name(),
   834                                             resolved_method->signature()));
   834                                             resolved_method->signature()));
   835       }
   835       }
   836     }
   836     }
   837   }
   837   }
   838 
   838 
   839   // check if not static
   839   // check if not static
   840   if (sel_method->is_static()) {
   840   if (sel_method->is_static()) {
   841     ResourceMark rm(THREAD);
   841     ResourceMark rm(THREAD);
   842     char buf[200];
   842     char buf[200];
   843     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   843     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
   844                                                                                                              resolved_method->name(),
   844                                                                                                              resolved_method->name(),
   845                                                                                                              resolved_method->signature()));
   845                                                                                                              resolved_method->signature()));
   846     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   846     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   847   }
   847   }
   848 
   848 
   849   // check if abstract
   849   // check if abstract
   850   if (sel_method->is_abstract()) {
   850   if (sel_method->is_abstract()) {
   851     ResourceMark rm(THREAD);
   851     ResourceMark rm(THREAD);
   852     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   852     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   853               Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   853               Method::name_and_sig_as_C_string(resolved_klass(),
   854                                                       sel_method->name(),
   854                                                       sel_method->name(),
   855                                                       sel_method->signature()));
   855                                                       sel_method->signature()));
   856   }
   856   }
   857 
   857 
   858   // setup result
   858   // setup result
   879 
   879 
   880   // check if not static
   880   // check if not static
   881   if (resolved_method->is_static()) {
   881   if (resolved_method->is_static()) {
   882     ResourceMark rm(THREAD);
   882     ResourceMark rm(THREAD);
   883     char buf[200];
   883     char buf[200];
   884     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   884     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
   885                                                                                                              resolved_method->name(),
   885                                                                                                              resolved_method->name(),
   886                                                                                                              resolved_method->signature()));
   886                                                                                                              resolved_method->signature()));
   887     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   887     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   888   }
   888   }
   889 }
   889 }
   948 
   948 
   949   // check if method exists
   949   // check if method exists
   950   if (selected_method.is_null()) {
   950   if (selected_method.is_null()) {
   951     ResourceMark rm(THREAD);
   951     ResourceMark rm(THREAD);
   952     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   952     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   953               Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   953               Method::name_and_sig_as_C_string(resolved_klass(),
   954                                                       resolved_method->name(),
   954                                                       resolved_method->name(),
   955                                                       resolved_method->signature()));
   955                                                       resolved_method->signature()));
   956   }
   956   }
   957 
   957 
   958   // check if abstract
   958   // check if abstract
   959   if (check_null_and_abstract && selected_method->is_abstract()) {
   959   if (check_null_and_abstract && selected_method->is_abstract()) {
   960     ResourceMark rm(THREAD);
   960     ResourceMark rm(THREAD);
   961     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   961     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   962               Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   962               Method::name_and_sig_as_C_string(resolved_klass(),
   963                                                       selected_method->name(),
   963                                                       selected_method->name(),
   964                                                       selected_method->signature()));
   964                                                       selected_method->signature()));
   965   }
   965   }
   966 
   966 
   967   // setup result
   967   // setup result
   997   // check if receiver klass implements the resolved interface
   997   // check if receiver klass implements the resolved interface
   998   if (!recv_klass->is_subtype_of(resolved_klass())) {
   998   if (!recv_klass->is_subtype_of(resolved_klass())) {
   999     ResourceMark rm(THREAD);
   999     ResourceMark rm(THREAD);
  1000     char buf[200];
  1000     char buf[200];
  1001     jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
  1001     jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
  1002                  (Klass::cast(recv_klass()))->external_name(),
  1002                  recv_klass()->external_name(),
  1003                  (Klass::cast(resolved_klass()))->external_name());
  1003                  resolved_klass()->external_name());
  1004     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1004     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1005   }
  1005   }
  1006   // do lookup based on receiver klass
  1006   // do lookup based on receiver klass
  1007   methodHandle sel_method;
  1007   methodHandle sel_method;
  1008   lookup_instance_method_in_klasses(sel_method, recv_klass,
  1008   lookup_instance_method_in_klasses(sel_method, recv_klass,
  1010             resolved_method->signature(), CHECK);
  1010             resolved_method->signature(), CHECK);
  1011   // check if method exists
  1011   // check if method exists
  1012   if (sel_method.is_null()) {
  1012   if (sel_method.is_null()) {
  1013     ResourceMark rm(THREAD);
  1013     ResourceMark rm(THREAD);
  1014     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1014     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1015               Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
  1015               Method::name_and_sig_as_C_string(recv_klass(),
  1016                                                       resolved_method->name(),
  1016                                                       resolved_method->name(),
  1017                                                       resolved_method->signature()));
  1017                                                       resolved_method->signature()));
  1018   }
  1018   }
  1019   // check if public
  1019   // check if public
  1020   if (!sel_method->is_public()) {
  1020   if (!sel_method->is_public()) {
  1021     ResourceMark rm(THREAD);
  1021     ResourceMark rm(THREAD);
  1022     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
  1022     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
  1023               Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
  1023               Method::name_and_sig_as_C_string(recv_klass(),
  1024                                                       sel_method->name(),
  1024                                                       sel_method->name(),
  1025                                                       sel_method->signature()));
  1025                                                       sel_method->signature()));
  1026   }
  1026   }
  1027   // check if abstract
  1027   // check if abstract
  1028   if (check_null_and_abstract && sel_method->is_abstract()) {
  1028   if (check_null_and_abstract && sel_method->is_abstract()) {
  1029     ResourceMark rm(THREAD);
  1029     ResourceMark rm(THREAD);
  1030     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1030     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1031               Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
  1031               Method::name_and_sig_as_C_string(recv_klass(),
  1032                                                       sel_method->name(),
  1032                                                       sel_method->name(),
  1033                                                       sel_method->signature()));
  1033                                                       sel_method->signature()));
  1034   }
  1034   }
  1035   // setup result
  1035   // setup result
  1036   result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
  1036   result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);