hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 38034 f22f68545fd5
parent 37267 ad8c0e8de29f
child 38139 cf6f5c1b7205
equal deleted inserted replaced
38033:996ce936543f 38034:f22f68545fd5
   610       return methodHandle(THREAD, result);
   610       return methodHandle(THREAD, result);
   611     }
   611     }
   612   }
   612   }
   613 
   613 
   614   if (code == Bytecodes::_invokeinterface) {
   614   if (code == Bytecodes::_invokeinterface) {
   615     return resolve_interface_method(link_info, true, THREAD);
   615     return resolve_interface_method(link_info, code, THREAD);
   616   } else if (code == Bytecodes::_invokevirtual) {
   616   } else if (code == Bytecodes::_invokevirtual) {
   617     return resolve_method(link_info, /*require_methodref*/true, THREAD);
   617     return resolve_method(link_info, /*require_methodref*/true, THREAD);
   618   } else if (!resolved_klass->is_interface()) {
   618   } else if (!resolved_klass->is_interface()) {
   619     return resolve_method(link_info, /*require_methodref*/false, THREAD);
   619     return resolve_method(link_info, /*require_methodref*/false, THREAD);
   620   } else {
   620   } else {
   621     bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
   621     return resolve_interface_method(link_info, code, THREAD);
   622     return resolve_interface_method(link_info, nostatics, THREAD);
       
   623   }
   622   }
   624 }
   623 }
   625 
   624 
   626 // Check and print a loader constraint violation message for method or interface method
   625 // Check and print a loader constraint violation message for method or interface method
   627 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
   626 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
   775   }
   774   }
   776   st->cr();
   775   st->cr();
   777 #endif // PRODUCT
   776 #endif // PRODUCT
   778 }
   777 }
   779 
   778 
   780 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
   779 // Do linktime resolution of a method in the interface within the context of the specied bytecode.
   781                                                     bool nostatics, TRAPS) {
   780 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS) {
   782 
   781 
   783   KlassHandle resolved_klass = link_info.resolved_klass();
   782   KlassHandle resolved_klass = link_info.resolved_klass();
   784 
   783 
   785   // check if klass is interface
   784   // check if klass is interface
   786   if (!resolved_klass->is_interface()) {
   785   if (!resolved_klass->is_interface()) {
   822                                CHECK_NULL);
   821                                CHECK_NULL);
   823 
   822 
   824     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
   823     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
   825   }
   824   }
   826 
   825 
   827   if (nostatics && resolved_method->is_static()) {
   826   if (code != Bytecodes::_invokestatic && resolved_method->is_static()) {
   828     ResourceMark rm(THREAD);
   827     ResourceMark rm(THREAD);
   829     char buf[200];
   828     char buf[200];
   830     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
   829     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
   831                  Method::name_and_sig_as_C_string(resolved_klass(),
   830                  Method::name_and_sig_as_C_string(resolved_klass(),
   832                  resolved_method->name(), resolved_method->signature()));
   831                  resolved_method->name(), resolved_method->signature()));
   833     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   832     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
   833   }
       
   834 
       
   835   if (code == Bytecodes::_invokeinterface && resolved_method->is_private()) {
       
   836     ResourceMark rm(THREAD);
       
   837     char buf[200];
       
   838 
       
   839     KlassHandle current_klass = link_info.current_klass();
       
   840     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s, caller-class:%s",
       
   841                  Method::name_and_sig_as_C_string(resolved_klass(),
       
   842                                                   resolved_method->name(),
       
   843                                                   resolved_method->signature()),
       
   844                                                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
       
   845      THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   834   }
   846   }
   835 
   847 
   836   if (log_develop_is_enabled(Trace, itables)) {
   848   if (log_develop_is_enabled(Trace, itables)) {
   837     trace_method_resolution("invokeinterface resolved method: caller-class",
   849     trace_method_resolution("invokeinterface resolved method: caller-class",
   838                             link_info.current_klass(), resolved_klass,
   850                             link_info.current_klass(), resolved_klass,
   982   KlassHandle resolved_klass = link_info.resolved_klass();
   994   KlassHandle resolved_klass = link_info.resolved_klass();
   983   methodHandle resolved_method;
   995   methodHandle resolved_method;
   984   if (!resolved_klass->is_interface()) {
   996   if (!resolved_klass->is_interface()) {
   985     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
   997     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
   986   } else {
   998   } else {
   987     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
   999     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
   988   }
  1000   }
   989   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
  1001   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   990 
  1002 
   991   // check if static
  1003   // check if static
   992   if (!resolved_method->is_static()) {
  1004   if (!resolved_method->is_static()) {
  1025   methodHandle resolved_method;
  1037   methodHandle resolved_method;
  1026 
  1038 
  1027   if (!resolved_klass->is_interface()) {
  1039   if (!resolved_klass->is_interface()) {
  1028     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
  1040     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
  1029   } else {
  1041   } else {
  1030     resolved_method = resolve_interface_method(link_info, /*nostatics*/true, CHECK_NULL);
  1042     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
  1031   }
  1043   }
  1032 
  1044 
  1033   // check if method name is <init>, that it is found in same klass as static type
  1045   // check if method name is <init>, that it is found in same klass as static type
  1034   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
  1046   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
  1035       resolved_method->method_holder() != resolved_klass()) {
  1047       resolved_method->method_holder() != resolved_klass()) {
  1300 }
  1312 }
  1301 
  1313 
  1302 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
  1314 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
  1303                                                              TRAPS) {
  1315                                                              TRAPS) {
  1304   // normal interface method resolution
  1316   // normal interface method resolution
  1305   methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
  1317   methodHandle resolved_method = resolve_interface_method(link_info, Bytecodes::_invokeinterface, CHECK_NULL);
  1306   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1318   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1307   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1319   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1308 
  1320 
  1309   return resolved_method;
  1321   return resolved_method;
  1310 }
  1322 }
  1317                                                     KlassHandle recv_klass,
  1329                                                     KlassHandle recv_klass,
  1318                                                     bool check_null_and_abstract, TRAPS) {
  1330                                                     bool check_null_and_abstract, TRAPS) {
  1319   // check if receiver exists
  1331   // check if receiver exists
  1320   if (check_null_and_abstract && recv.is_null()) {
  1332   if (check_null_and_abstract && recv.is_null()) {
  1321     THROW(vmSymbols::java_lang_NullPointerException());
  1333     THROW(vmSymbols::java_lang_NullPointerException());
  1322   }
       
  1323 
       
  1324   // check if private interface method
       
  1325   if (resolved_klass->is_interface() && resolved_method->is_private()) {
       
  1326     ResourceMark rm(THREAD);
       
  1327     char buf[200];
       
  1328     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
       
  1329                  Method::name_and_sig_as_C_string(resolved_klass(),
       
  1330                                                   resolved_method->name(),
       
  1331                                                   resolved_method->signature()));
       
  1332     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
  1333   }
  1334   }
  1334 
  1335 
  1335   // check if receiver klass implements the resolved interface
  1336   // check if receiver klass implements the resolved interface
  1336   if (!recv_klass->is_subtype_of(resolved_klass())) {
  1337   if (!recv_klass->is_subtype_of(resolved_klass())) {
  1337     ResourceMark rm(THREAD);
  1338     ResourceMark rm(THREAD);