src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8073191-work Sdiff src/share/vm/interpreter

src/share/vm/interpreter/linkResolver.cpp

Print this page




 206 }
 207 #endif //ASSERT
 208 
 209 #ifndef PRODUCT
 210 void CallInfo::print() {
 211   ResourceMark rm;
 212   const char* kindstr = "unknown";
 213   switch (_call_kind) {
 214   case direct_call: kindstr = "direct"; break;
 215   case vtable_call: kindstr = "vtable"; break;
 216   case itable_call: kindstr = "itable"; break;
 217   }
 218   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 219                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 220 }
 221 #endif
 222 
 223 //------------------------------------------------------------------------------------------------------------------------
 224 // Implementation of LinkInfo
 225 
 226 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 227    // resolve klass
 228   Klass* result = pool->klass_ref_at(index, CHECK);
 229   _resolved_klass = KlassHandle(THREAD, result);
 230 
 231   // Get name, signature, and static klass
 232   _name          = pool->name_ref_at(index);
 233   _signature     = pool->signature_ref_at(index);
 234   _current_klass = KlassHandle(THREAD, pool->pool_holder());

 235 
 236   // Coming from the constant pool always checks access
 237   _check_access  = true;
 238 }
 239 
 240 char* LinkInfo::method_string() const {
 241   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 242 }
 243 
 244 #ifndef PRODUCT
 245 void LinkInfo::print() {
 246   ResourceMark rm;
 247   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 248                 _resolved_klass->name()->as_C_string(),
 249                 _name->as_C_string(),
 250                 _signature->as_C_string(),
 251                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 252                 _check_access ? "true" : "false");
 253 }
 254 #endif // PRODUCT


 555     );
 556     return;
 557   }
 558 }
 559 
 560 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
 561                                                      const constantPoolHandle& pool, int index, TRAPS) {
 562   // This method is used only
 563   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 564   // and
 565   // (2) in Bytecode_invoke::static_target
 566   // It appears to fail when applied to an invokeinterface call site.
 567   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 568   // resolve klass
 569   KlassHandle resolved_klass;
 570   if (code == Bytecodes::_invokedynamic) {
 571     resolved_klass = SystemDictionary::MethodHandle_klass();
 572     Symbol* method_name = vmSymbols::invoke_name();
 573     Symbol* method_signature = pool->signature_ref_at(index);
 574     KlassHandle  current_klass(THREAD, pool->pool_holder());
 575     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 576     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 577   }
 578 
 579   LinkInfo link_info(pool, index, CHECK_NULL);
 580   resolved_klass = link_info.resolved_klass();
 581 
 582   if (pool->has_preresolution()
 583       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
 584           MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
 585     Method* result = ConstantPool::method_at_if_loaded(pool, index);
 586     if (result != NULL) {
 587       return methodHandle(THREAD, result);
 588     }
 589   }
 590 
 591   if (code == Bytecodes::_invokeinterface) {
 592     return resolve_interface_method(link_info, code, THREAD);
 593   } else if (code == Bytecodes::_invokevirtual) {
 594     return resolve_method(link_info, /*require_methodref*/true, THREAD);
 595   } else if (!resolved_klass->is_interface()) {
 596     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 597   } else {
 598     return resolve_interface_method(link_info, code, THREAD);
 599   }


 840                                              const fieldDescriptor& fd,
 841                                              TRAPS) {
 842   if (!Reflection::verify_field_access(ref_klass(),
 843                                        resolved_klass(),
 844                                        sel_klass(),
 845                                        fd.access_flags(),
 846                                        true)) {
 847     ResourceMark rm(THREAD);
 848     Exceptions::fthrow(
 849       THREAD_AND_LOCATION,
 850       vmSymbols::java_lang_IllegalAccessError(),
 851       "tried to access field %s.%s from class %s",
 852       sel_klass->external_name(),
 853       fd.name()->as_C_string(),
 854       ref_klass->external_name()
 855     );
 856     return;
 857   }
 858 }
 859 
 860 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
 861   LinkInfo link_info(pool, index, CHECK);
 862   resolve_field(fd, link_info, byte, true, CHECK);
 863 }
 864 
 865 void LinkResolver::resolve_field(fieldDescriptor& fd,
 866                                  const LinkInfo& link_info,
 867                                  Bytecodes::Code byte, bool initialize_class,
 868                                  TRAPS) {
 869   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 870          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 871          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 872          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 873 
 874   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 875   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
 876   // Check if there's a resolved klass containing the field
 877   KlassHandle resolved_klass = link_info.resolved_klass();
 878   Symbol* field = link_info.name();
 879   Symbol* sig = link_info.signature();
 880 
 881   if (resolved_klass.is_null()) {


 890     ResourceMark rm(THREAD);
 891     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 892   }
 893 
 894   if (!link_info.check_access())
 895     // Access checking may be turned off when calling from within the VM.
 896     return;
 897 
 898   // check access
 899   KlassHandle current_klass = link_info.current_klass();
 900   check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
 901 
 902   // check for errors
 903   if (is_static != fd.is_static()) {
 904     ResourceMark rm(THREAD);
 905     char msg[200];
 906     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
 907     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 908   }
 909 
 910   // Final fields can only be accessed from its own class.
 911   if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {














 912     THROW(vmSymbols::java_lang_IllegalAccessError());
 913   }


 914 
 915   // initialize resolved_klass if necessary
 916   // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
 917   //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
 918   //
 919   // note 2: we don't want to force initialization if we are just checking
 920   //         if the field access is legal; e.g., during compilation
 921   if (is_static && initialize_class) {
 922     sel_klass->initialize(CHECK);
 923   }
 924 
 925   if (sel_klass() != current_klass()) {
 926     check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
 927   }
 928 
 929   // return information. note that the klass is set to the actual klass containing the
 930   // field, otherwise access of static fields in superclasses will not work.
 931 }
 932 
 933 


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


1465 // ConstantPool entries
1466 
1467 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1468   switch (byte) {
1469     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1470     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
1471     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1472     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1473     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1474     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1475   }
1476   return;
1477 }
1478 
1479 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1480                              const methodHandle& attached_method,
1481                              Bytecodes::Code byte, TRAPS) {
1482   KlassHandle defc = attached_method->method_holder();
1483   Symbol* name = attached_method->name();
1484   Symbol* type = attached_method->signature();
1485   LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false);
1486   switch(byte) {
1487     case Bytecodes::_invokevirtual:
1488       resolve_virtual_call(result, recv, recv->klass(), link_info,
1489                            /*check_null_and_abstract=*/true, CHECK);
1490       break;
1491     case Bytecodes::_invokeinterface:
1492       resolve_interface_call(result, recv, recv->klass(), link_info,
1493                              /*check_null_and_abstract=*/true, CHECK);
1494       break;
1495     case Bytecodes::_invokestatic:
1496       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1497       break;
1498     case Bytecodes::_invokespecial:
1499       resolve_special_call(result, link_info, CHECK);
1500       break;
1501     default:
1502       fatal("bad call: %s", Bytecodes::name(byte));
1503   }
1504 }
1505 
1506 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1507   LinkInfo link_info(pool, index, CHECK);
1508   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1509 }
1510 
1511 
1512 void LinkResolver::resolve_invokespecial(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1513   LinkInfo link_info(pool, index, CHECK);
1514   resolve_special_call(result, link_info, CHECK);
1515 }
1516 
1517 
1518 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
1519                                           const constantPoolHandle& pool, int index,
1520                                           TRAPS) {
1521 
1522   LinkInfo link_info(pool, index, CHECK);
1523   KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
1524   resolve_virtual_call(result, recv, recvrKlass, link_info, /*check_null_or_abstract*/true, CHECK);
1525 }
1526 
1527 
1528 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) {
1529   LinkInfo link_info(pool, index, CHECK);
1530   KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
1531   resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
1532 }
1533 
1534 
1535 void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1536   // This guy is reached from InterpreterRuntime::resolve_invokehandle.
1537   LinkInfo link_info(pool, index, CHECK);
1538   if (TraceMethodHandles) {
1539     ResourceMark rm(THREAD);
1540     tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
1541                   link_info.signature()->as_C_string());
1542   }
1543   resolve_handle_call(result, link_info, CHECK);
1544 }
1545 
1546 void LinkResolver::resolve_handle_call(CallInfo& result,
1547                                        const LinkInfo& link_info,
1548                                        TRAPS) {
1549   // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
1550   KlassHandle resolved_klass = link_info.resolved_klass();
1551   assert(resolved_klass() == SystemDictionary::MethodHandle_klass() ||
1552          resolved_klass() == SystemDictionary::VarHandle_klass(), "");
1553   assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
1554   Handle       resolved_appendix;
1555   Handle       resolved_method_type;
1556   methodHandle resolved_method = lookup_polymorphic_method(link_info,
1557                                        &resolved_appendix, &resolved_method_type, CHECK);




 206 }
 207 #endif //ASSERT
 208 
 209 #ifndef PRODUCT
 210 void CallInfo::print() {
 211   ResourceMark rm;
 212   const char* kindstr = "unknown";
 213   switch (_call_kind) {
 214   case direct_call: kindstr = "direct"; break;
 215   case vtable_call: kindstr = "vtable"; break;
 216   case itable_call: kindstr = "itable"; break;
 217   }
 218   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 219                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 220 }
 221 #endif
 222 
 223 //------------------------------------------------------------------------------------------------------------------------
 224 // Implementation of LinkInfo
 225 
 226 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS) {
 227    // resolve klass
 228   Klass* result = pool->klass_ref_at(index, CHECK);
 229   _resolved_klass = KlassHandle(THREAD, result);
 230 
 231   // Get name, signature, and static klass
 232   _name          = pool->name_ref_at(index);
 233   _signature     = pool->signature_ref_at(index);
 234   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 235   _current_method = current_method;
 236 
 237   // Coming from the constant pool always checks access
 238   _check_access  = true;
 239 }
 240 
 241 char* LinkInfo::method_string() const {
 242   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 243 }
 244 
 245 #ifndef PRODUCT
 246 void LinkInfo::print() {
 247   ResourceMark rm;
 248   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 249                 _resolved_klass->name()->as_C_string(),
 250                 _name->as_C_string(),
 251                 _signature->as_C_string(),
 252                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 253                 _check_access ? "true" : "false");
 254 }
 255 #endif // PRODUCT


 556     );
 557     return;
 558   }
 559 }
 560 
 561 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
 562                                                      const constantPoolHandle& pool, int index, TRAPS) {
 563   // This method is used only
 564   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 565   // and
 566   // (2) in Bytecode_invoke::static_target
 567   // It appears to fail when applied to an invokeinterface call site.
 568   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 569   // resolve klass
 570   KlassHandle resolved_klass;
 571   if (code == Bytecodes::_invokedynamic) {
 572     resolved_klass = SystemDictionary::MethodHandle_klass();
 573     Symbol* method_name = vmSymbols::invoke_name();
 574     Symbol* method_signature = pool->signature_ref_at(index);
 575     KlassHandle  current_klass(THREAD, pool->pool_holder());
 576     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass, NULL);
 577     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 578   }
 579 
 580   LinkInfo link_info(pool, index, NULL, CHECK_NULL);
 581   resolved_klass = link_info.resolved_klass();
 582 
 583   if (pool->has_preresolution()
 584       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
 585           MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
 586     Method* result = ConstantPool::method_at_if_loaded(pool, index);
 587     if (result != NULL) {
 588       return methodHandle(THREAD, result);
 589     }
 590   }
 591 
 592   if (code == Bytecodes::_invokeinterface) {
 593     return resolve_interface_method(link_info, code, THREAD);
 594   } else if (code == Bytecodes::_invokevirtual) {
 595     return resolve_method(link_info, /*require_methodref*/true, THREAD);
 596   } else if (!resolved_klass->is_interface()) {
 597     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 598   } else {
 599     return resolve_interface_method(link_info, code, THREAD);
 600   }


 841                                              const fieldDescriptor& fd,
 842                                              TRAPS) {
 843   if (!Reflection::verify_field_access(ref_klass(),
 844                                        resolved_klass(),
 845                                        sel_klass(),
 846                                        fd.access_flags(),
 847                                        true)) {
 848     ResourceMark rm(THREAD);
 849     Exceptions::fthrow(
 850       THREAD_AND_LOCATION,
 851       vmSymbols::java_lang_IllegalAccessError(),
 852       "tried to access field %s.%s from class %s",
 853       sel_klass->external_name(),
 854       fd.name()->as_C_string(),
 855       ref_klass->external_name()
 856     );
 857     return;
 858   }
 859 }
 860 
 861 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 862   LinkInfo link_info(pool, index, method, CHECK);
 863   resolve_field(fd, link_info, byte, true, CHECK);
 864 }
 865 
 866 void LinkResolver::resolve_field(fieldDescriptor& fd,
 867                                  const LinkInfo& link_info,
 868                                  Bytecodes::Code byte, bool initialize_class,
 869                                  TRAPS) {
 870   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 871          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 872          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 873          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 874 
 875   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 876   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
 877   // Check if there's a resolved klass containing the field
 878   KlassHandle resolved_klass = link_info.resolved_klass();
 879   Symbol* field = link_info.name();
 880   Symbol* sig = link_info.signature();
 881 
 882   if (resolved_klass.is_null()) {


 891     ResourceMark rm(THREAD);
 892     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 893   }
 894 
 895   if (!link_info.check_access())
 896     // Access checking may be turned off when calling from within the VM.
 897     return;
 898 
 899   // check access
 900   KlassHandle current_klass = link_info.current_klass();
 901   check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
 902 
 903   // check for errors
 904   if (is_static != fd.is_static()) {
 905     ResourceMark rm(THREAD);
 906     char msg[200];
 907     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
 908     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 909   }
 910 
 911   // A final field can be modified only
 912   // (1) by methods declared in the class declaring the field and
 913   // (2) by the <clinit> method (in case of a static field)
 914   //     or by the <init> method (in case of an instance field).
 915   if (is_put && fd.access_flags().is_final()) {
 916     if (sel_klass() != current_klass()) {
 917       THROW(vmSymbols::java_lang_IllegalAccessError());
 918     }
 919 
 920     if (CheckFinalFieldModifications &&
 921         fd.constants()->pool_holder()->major_version() >= 52) {
 922       methodHandle m = link_info.current_method();
 923       assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes");
 924       Symbol* method_name = m->name();
 925       if ((byte == Bytecodes::_putstatic && fd.is_static() && method_name != vmSymbols::class_initializer_name()) ||
 926           ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && !fd.is_static() && method_name != vmSymbols::object_initializer_name())) {
 927         THROW(vmSymbols::java_lang_IllegalAccessError());
 928       }
 929     }
 930   }
 931 
 932   // initialize resolved_klass if necessary
 933   // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
 934   //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
 935   //
 936   // note 2: we don't want to force initialization if we are just checking
 937   //         if the field access is legal; e.g., during compilation
 938   if (is_static && initialize_class) {
 939     sel_klass->initialize(CHECK);
 940   }
 941 
 942   if (sel_klass() != current_klass()) {
 943     check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
 944   }
 945 
 946   // return information. note that the klass is set to the actual klass containing the
 947   // field, otherwise access of static fields in superclasses will not work.
 948 }
 949 
 950 


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


1482 // ConstantPool entries
1483 
1484 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1485   switch (byte) {
1486     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1487     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
1488     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1489     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1490     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1491     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1492   }
1493   return;
1494 }
1495 
1496 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1497                              const methodHandle& attached_method,
1498                              Bytecodes::Code byte, TRAPS) {
1499   KlassHandle defc = attached_method->method_holder();
1500   Symbol* name = attached_method->name();
1501   Symbol* type = attached_method->signature();
1502   LinkInfo link_info(defc, name, type, KlassHandle(), NULL, /*check_access=*/false);
1503   switch(byte) {
1504     case Bytecodes::_invokevirtual:
1505       resolve_virtual_call(result, recv, recv->klass(), link_info,
1506                            /*check_null_and_abstract=*/true, CHECK);
1507       break;
1508     case Bytecodes::_invokeinterface:
1509       resolve_interface_call(result, recv, recv->klass(), link_info,
1510                              /*check_null_and_abstract=*/true, CHECK);
1511       break;
1512     case Bytecodes::_invokestatic:
1513       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1514       break;
1515     case Bytecodes::_invokespecial:
1516       resolve_special_call(result, link_info, CHECK);
1517       break;
1518     default:
1519       fatal("bad call: %s", Bytecodes::name(byte));
1520   }
1521 }
1522 
1523 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1524   LinkInfo link_info(pool, index, NULL, CHECK);
1525   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1526 }
1527 
1528 
1529 void LinkResolver::resolve_invokespecial(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1530   LinkInfo link_info(pool, index, NULL, CHECK);
1531   resolve_special_call(result, link_info, CHECK);
1532 }
1533 
1534 
1535 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
1536                                           const constantPoolHandle& pool, int index,
1537                                           TRAPS) {
1538 
1539   LinkInfo link_info(pool, index, NULL, CHECK);
1540   KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
1541   resolve_virtual_call(result, recv, recvrKlass, link_info, /*check_null_or_abstract*/true, CHECK);
1542 }
1543 
1544 
1545 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) {
1546   LinkInfo link_info(pool, index, NULL, CHECK);
1547   KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
1548   resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
1549 }
1550 
1551 
1552 void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1553   // This guy is reached from InterpreterRuntime::resolve_invokehandle.
1554   LinkInfo link_info(pool, index, NULL, CHECK);
1555   if (TraceMethodHandles) {
1556     ResourceMark rm(THREAD);
1557     tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
1558                   link_info.signature()->as_C_string());
1559   }
1560   resolve_handle_call(result, link_info, CHECK);
1561 }
1562 
1563 void LinkResolver::resolve_handle_call(CallInfo& result,
1564                                        const LinkInfo& link_info,
1565                                        TRAPS) {
1566   // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
1567   KlassHandle resolved_klass = link_info.resolved_klass();
1568   assert(resolved_klass() == SystemDictionary::MethodHandle_klass() ||
1569          resolved_klass() == SystemDictionary::VarHandle_klass(), "");
1570   assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
1571   Handle       resolved_appendix;
1572   Handle       resolved_method_type;
1573   methodHandle resolved_method = lookup_polymorphic_method(link_info,
1574                                        &resolved_appendix, &resolved_method_type, CHECK);


src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File