< prev index next >

src/share/vm/interpreter/linkResolver.cpp

Print this page


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 231   case direct_call: kindstr = "direct"; break;
 232   case vtable_call: kindstr = "vtable"; break;
 233   case itable_call: kindstr = "itable"; break;
 234   }
 235   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 236                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 237 }
 238 #endif
 239 
 240 //------------------------------------------------------------------------------------------------------------------------
 241 // Implementation of LinkInfo
 242 
 243 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 244    // resolve klass
 245   Klass* result = pool->klass_ref_at(index, CHECK);
 246   _resolved_klass = KlassHandle(THREAD, result);
 247 
 248   // Get name, signature, and static klass
 249   _name          = pool->name_ref_at(index);
 250   _signature     = pool->signature_ref_at(index);

 251   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 252 
 253   // Coming from the constant pool always checks access
 254   _check_access  = true;
 255 }
 256 
 257 char* LinkInfo::method_string() const {
 258   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 259 }
 260 
 261 #ifndef PRODUCT
 262 void LinkInfo::print() {
 263   ResourceMark rm;
 264   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 265                 _resolved_klass->name()->as_C_string(),
 266                 _name->as_C_string(),
 267                 _signature->as_C_string(),
 268                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 269                 _check_access ? "true" : "false");
 270 }


 667                      failed_type_name);
 668     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
 669   }
 670 }
 671 
 672 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
 673                                           bool require_methodref, TRAPS) {
 674 
 675   Handle nested_exception;
 676   KlassHandle resolved_klass = link_info.resolved_klass();
 677 
 678   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 679   if (require_methodref && resolved_klass->is_interface()) {
 680     ResourceMark rm(THREAD);
 681     char buf[200];
 682     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 683         resolved_klass()->external_name());
 684     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 685   }
 686 









 687   // 2. lookup method in resolved klass and its super klasses
 688   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
 689 
 690   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
 691     // 3. lookup method in all the interfaces implemented by the resolved klass
 692     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 693 
 694     if (resolved_method.is_null()) {
 695       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 696       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
 697       if (HAS_PENDING_EXCEPTION) {
 698         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 699         CLEAR_PENDING_EXCEPTION;
 700       }
 701     }
 702   }
 703 
 704   if (resolved_method.is_null()) {
 705     // 4. method lookup failed
 706     ResourceMark rm(THREAD);


 756   if (index != -1) {
 757     st->print("vtable_index:%d", index);
 758   }
 759   st->cr();
 760 #endif // PRODUCT
 761 }
 762 
 763 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 764                                                     bool nostatics, TRAPS) {
 765 
 766   KlassHandle resolved_klass = link_info.resolved_klass();
 767 
 768   // check if klass is interface
 769   if (!resolved_klass->is_interface()) {
 770     ResourceMark rm(THREAD);
 771     char buf[200];
 772     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 773     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 774   }
 775 








 776   // lookup method in this interface or its super, java.lang.Object
 777   // JDK8: also look for static methods
 778   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 779 
 780   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 781     // lookup method in all the super-interfaces
 782     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 783   }
 784 
 785   if (resolved_method.is_null()) {
 786     // no method found
 787     ResourceMark rm(THREAD);
 788     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
 789                    Method::name_and_sig_as_C_string(resolved_klass(),
 790                                                     link_info.name(),
 791                                                     link_info.signature()));
 792   }
 793 
 794   if (link_info.check_access()) {
 795     // JDK8 adds non-public interface methods, and accessability check requirement


 933 // resolved_method    the specified method (i.e., static receiver specified via constant pool index)
 934 // sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
 935 // resolved_klass     the specified klass  (i.e., specified via constant pool index)
 936 // recv_klass         the receiver klass
 937 
 938 
 939 void LinkResolver::resolve_static_call(CallInfo& result,
 940                                        const LinkInfo& link_info,
 941                                        bool initialize_class, TRAPS) {
 942   methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
 943 
 944   // The resolved class can change as a result of this resolution.
 945   KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
 946 
 947   Method* save_resolved_method = resolved_method();
 948   // Initialize klass (this should only happen if everything is ok)
 949   if (initialize_class && resolved_klass->should_be_initialized()) {
 950     resolved_klass->initialize(CHECK);
 951     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 952     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 953                       link_info.current_klass(), link_info.check_access());

 954     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 955   }
 956 
 957   assert(save_resolved_method == resolved_method(), "does this change?");
 958   // setup result
 959   result.set_static(resolved_klass, resolved_method, CHECK);
 960 }
 961 
 962 // throws linktime exceptions
 963 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 964 
 965   KlassHandle resolved_klass = link_info.resolved_klass();
 966   methodHandle resolved_method;
 967   if (!resolved_klass->is_interface()) {
 968     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 969   } else {
 970     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
 971   }
 972   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
 973 


1474 // ConstantPool entries
1475 
1476 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1477   switch (byte) {
1478     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1479     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
1480     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1481     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1482     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1483     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1484   }
1485   return;
1486 }
1487 
1488 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1489                              const methodHandle& attached_method,
1490                              Bytecodes::Code byte, TRAPS) {
1491   KlassHandle defc = attached_method->method_holder();
1492   Symbol* name = attached_method->name();
1493   Symbol* type = attached_method->signature();
1494   LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false);
1495   switch(byte) {
1496     case Bytecodes::_invokevirtual:
1497       resolve_virtual_call(result, recv, recv->klass(), link_info,
1498                            /*check_null_and_abstract=*/true, CHECK);
1499       break;
1500     case Bytecodes::_invokeinterface:
1501       resolve_interface_call(result, recv, recv->klass(), link_info,
1502                              /*check_null_and_abstract=*/true, CHECK);
1503       break;
1504     case Bytecodes::_invokestatic:
1505       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1506       break;
1507     case Bytecodes::_invokespecial:
1508       resolve_special_call(result, link_info, CHECK);
1509       break;
1510     default:
1511       fatal("bad call: %s", Bytecodes::name(byte));
1512   }
1513 }
1514 


   1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 231   case direct_call: kindstr = "direct"; break;
 232   case vtable_call: kindstr = "vtable"; break;
 233   case itable_call: kindstr = "itable"; break;
 234   }
 235   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 236                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 237 }
 238 #endif
 239 
 240 //------------------------------------------------------------------------------------------------------------------------
 241 // Implementation of LinkInfo
 242 
 243 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 244    // resolve klass
 245   Klass* result = pool->klass_ref_at(index, CHECK);
 246   _resolved_klass = KlassHandle(THREAD, result);
 247 
 248   // Get name, signature, and static klass
 249   _name          = pool->name_ref_at(index);
 250   _signature     = pool->signature_ref_at(index);
 251   _tag           = pool->tag_ref_at(index);
 252   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 253 
 254   // Coming from the constant pool always checks access
 255   _check_access  = true;
 256 }
 257 
 258 char* LinkInfo::method_string() const {
 259   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 260 }
 261 
 262 #ifndef PRODUCT
 263 void LinkInfo::print() {
 264   ResourceMark rm;
 265   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 266                 _resolved_klass->name()->as_C_string(),
 267                 _name->as_C_string(),
 268                 _signature->as_C_string(),
 269                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 270                 _check_access ? "true" : "false");
 271 }


 668                      failed_type_name);
 669     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
 670   }
 671 }
 672 
 673 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
 674                                           bool require_methodref, TRAPS) {
 675 
 676   Handle nested_exception;
 677   KlassHandle resolved_klass = link_info.resolved_klass();
 678 
 679   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 680   if (require_methodref && resolved_klass->is_interface()) {
 681     ResourceMark rm(THREAD);
 682     char buf[200];
 683     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 684         resolved_klass()->external_name());
 685     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 686   }
 687 
 688   // check tag at call is method
 689   if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
 690     ResourceMark rm(THREAD);
 691     char buf[200];
 692     jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string());
 693     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 694   }
 695 
 696 
 697   // 2. lookup method in resolved klass and its super klasses
 698   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
 699 
 700   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
 701     // 3. lookup method in all the interfaces implemented by the resolved klass
 702     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 703 
 704     if (resolved_method.is_null()) {
 705       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 706       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
 707       if (HAS_PENDING_EXCEPTION) {
 708         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 709         CLEAR_PENDING_EXCEPTION;
 710       }
 711     }
 712   }
 713 
 714   if (resolved_method.is_null()) {
 715     // 4. method lookup failed
 716     ResourceMark rm(THREAD);


 766   if (index != -1) {
 767     st->print("vtable_index:%d", index);
 768   }
 769   st->cr();
 770 #endif // PRODUCT
 771 }
 772 
 773 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 774                                                     bool nostatics, TRAPS) {
 775 
 776   KlassHandle resolved_klass = link_info.resolved_klass();
 777 
 778   // check if klass is interface
 779   if (!resolved_klass->is_interface()) {
 780     ResourceMark rm(THREAD);
 781     char buf[200];
 782     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 783     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 784   }
 785 
 786   // check tag at call is an interface method
 787   if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
 788     ResourceMark rm(THREAD);
 789     char buf[200];
 790     jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string());
 791     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 792   }
 793 
 794   // lookup method in this interface or its super, java.lang.Object
 795   // JDK8: also look for static methods
 796   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 797 
 798   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 799     // lookup method in all the super-interfaces
 800     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 801   }
 802 
 803   if (resolved_method.is_null()) {
 804     // no method found
 805     ResourceMark rm(THREAD);
 806     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
 807                    Method::name_and_sig_as_C_string(resolved_klass(),
 808                                                     link_info.name(),
 809                                                     link_info.signature()));
 810   }
 811 
 812   if (link_info.check_access()) {
 813     // JDK8 adds non-public interface methods, and accessability check requirement


 951 // resolved_method    the specified method (i.e., static receiver specified via constant pool index)
 952 // sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
 953 // resolved_klass     the specified klass  (i.e., specified via constant pool index)
 954 // recv_klass         the receiver klass
 955 
 956 
 957 void LinkResolver::resolve_static_call(CallInfo& result,
 958                                        const LinkInfo& link_info,
 959                                        bool initialize_class, TRAPS) {
 960   methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
 961 
 962   // The resolved class can change as a result of this resolution.
 963   KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
 964 
 965   Method* save_resolved_method = resolved_method();
 966   // Initialize klass (this should only happen if everything is ok)
 967   if (initialize_class && resolved_klass->should_be_initialized()) {
 968     resolved_klass->initialize(CHECK);
 969     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 970     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 971                       link_info.current_klass(),
 972                       link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
 973     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 974   }
 975 
 976   assert(save_resolved_method == resolved_method(), "does this change?");
 977   // setup result
 978   result.set_static(resolved_klass, resolved_method, CHECK);
 979 }
 980 
 981 // throws linktime exceptions
 982 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 983 
 984   KlassHandle resolved_klass = link_info.resolved_klass();
 985   methodHandle resolved_method;
 986   if (!resolved_klass->is_interface()) {
 987     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 988   } else {
 989     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
 990   }
 991   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
 992 


1493 // ConstantPool entries
1494 
1495 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1496   switch (byte) {
1497     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1498     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
1499     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1500     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1501     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1502     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1503   }
1504   return;
1505 }
1506 
1507 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1508                              const methodHandle& attached_method,
1509                              Bytecodes::Code byte, TRAPS) {
1510   KlassHandle defc = attached_method->method_holder();
1511   Symbol* name = attached_method->name();
1512   Symbol* type = attached_method->signature();
1513   LinkInfo link_info(defc, name, type, KlassHandle(), LinkInfo::skip_access_check);
1514   switch(byte) {
1515     case Bytecodes::_invokevirtual:
1516       resolve_virtual_call(result, recv, recv->klass(), link_info,
1517                            /*check_null_and_abstract=*/true, CHECK);
1518       break;
1519     case Bytecodes::_invokeinterface:
1520       resolve_interface_call(result, recv, recv->klass(), link_info,
1521                              /*check_null_and_abstract=*/true, CHECK);
1522       break;
1523     case Bytecodes::_invokestatic:
1524       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1525       break;
1526     case Bytecodes::_invokespecial:
1527       resolve_special_call(result, link_info, CHECK);
1528       break;
1529     default:
1530       fatal("bad call: %s", Bytecodes::name(byte));
1531   }
1532 }
1533 


< prev index next >