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   _tag           = pool->tag_ref_at(index);
 235   _current_klass = KlassHandle(THREAD, pool->pool_holder());

 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


 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);
 577     return resolve_method(link_info, code, THREAD);
 578   }
 579 
 580   LinkInfo link_info(pool, index, 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, code, THREAD);
 596   } else if (!resolved_klass->is_interface()) {
 597     return resolve_method(link_info, code, THREAD);
 598   } else {
 599     return resolve_interface_method(link_info, code, THREAD);
 600   }


 858                                              const fieldDescriptor& fd,
 859                                              TRAPS) {
 860   if (!Reflection::verify_field_access(ref_klass(),
 861                                        resolved_klass(),
 862                                        sel_klass(),
 863                                        fd.access_flags(),
 864                                        true)) {
 865     ResourceMark rm(THREAD);
 866     Exceptions::fthrow(
 867       THREAD_AND_LOCATION,
 868       vmSymbols::java_lang_IllegalAccessError(),
 869       "tried to access field %s.%s from class %s",
 870       sel_klass->external_name(),
 871       fd.name()->as_C_string(),
 872       ref_klass->external_name()
 873     );
 874     return;
 875   }
 876 }
 877 
 878 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
 879   LinkInfo link_info(pool, index, CHECK);
 880   resolve_field(fd, link_info, byte, true, CHECK);
 881 }
 882 
 883 void LinkResolver::resolve_field(fieldDescriptor& fd,
 884                                  const LinkInfo& link_info,
 885                                  Bytecodes::Code byte, bool initialize_class,
 886                                  TRAPS) {
 887   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 888          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 889          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 890          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 891 
 892   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 893   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
 894   // Check if there's a resolved klass containing the field
 895   KlassHandle resolved_klass = link_info.resolved_klass();
 896   Symbol* field = link_info.name();
 897   Symbol* sig = link_info.signature();
 898 
 899   if (resolved_klass.is_null()) {


 908     ResourceMark rm(THREAD);
 909     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 910   }
 911 
 912   if (!link_info.check_access())
 913     // Access checking may be turned off when calling from within the VM.
 914     return;
 915 
 916   // check access
 917   KlassHandle current_klass = link_info.current_klass();
 918   check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
 919 
 920   // check for errors
 921   if (is_static != fd.is_static()) {
 922     ResourceMark rm(THREAD);
 923     char msg[200];
 924     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
 925     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 926   }
 927 
 928   // Final fields can only be accessed from its own class.
 929   if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
 930     THROW(vmSymbols::java_lang_IllegalAccessError());































 931   }
 932 
 933   // initialize resolved_klass if necessary
 934   // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
 935   //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
 936   //
 937   // note 2: we don't want to force initialization if we are just checking
 938   //         if the field access is legal; e.g., during compilation
 939   if (is_static && initialize_class) {
 940     sel_klass->initialize(CHECK);
 941   }
 942 
 943   if (sel_klass() != current_klass()) {
 944     check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
 945   }
 946 
 947   // return information. note that the klass is set to the actual klass containing the
 948   // field, otherwise access of static fields in superclasses will not work.
 949 }
 950 




 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   _tag           = pool->tag_ref_at(index);
 235   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 236   _current_method = current_method;
 237 
 238   // Coming from the constant pool always checks access
 239   _check_access  = true;
 240 }
 241 
 242 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 243    // resolve klass
 244   Klass* result = pool->klass_ref_at(index, CHECK);
 245   _resolved_klass = KlassHandle(THREAD, result);
 246 
 247   // Get name, signature, and static klass
 248   _name          = pool->name_ref_at(index);
 249   _signature     = pool->signature_ref_at(index);
 250   _tag           = pool->tag_ref_at(index);
 251   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 252   _current_method = methodHandle();
 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 }
 272 #endif // PRODUCT


 577 
 578 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
 579                                                      const constantPoolHandle& pool, int index, TRAPS) {
 580   // This method is used only
 581   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 582   // and
 583   // (2) in Bytecode_invoke::static_target
 584   // It appears to fail when applied to an invokeinterface call site.
 585   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 586   // resolve klass
 587   KlassHandle resolved_klass;
 588   if (code == Bytecodes::_invokedynamic) {
 589     resolved_klass = SystemDictionary::MethodHandle_klass();
 590     Symbol* method_name = vmSymbols::invoke_name();
 591     Symbol* method_signature = pool->signature_ref_at(index);
 592     KlassHandle  current_klass(THREAD, pool->pool_holder());
 593     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 594     return resolve_method(link_info, code, THREAD);
 595   }
 596 
 597   LinkInfo link_info(pool, index, methodHandle(), CHECK_NULL);
 598   resolved_klass = link_info.resolved_klass();
 599 
 600   if (pool->has_preresolution()
 601       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
 602           MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
 603     Method* result = ConstantPool::method_at_if_loaded(pool, index);
 604     if (result != NULL) {
 605       return methodHandle(THREAD, result);
 606     }
 607   }
 608 
 609   if (code == Bytecodes::_invokeinterface) {
 610     return resolve_interface_method(link_info, code, THREAD);
 611   } else if (code == Bytecodes::_invokevirtual) {
 612     return resolve_method(link_info, code, THREAD);
 613   } else if (!resolved_klass->is_interface()) {
 614     return resolve_method(link_info, code, THREAD);
 615   } else {
 616     return resolve_interface_method(link_info, code, THREAD);
 617   }


 875                                              const fieldDescriptor& fd,
 876                                              TRAPS) {
 877   if (!Reflection::verify_field_access(ref_klass(),
 878                                        resolved_klass(),
 879                                        sel_klass(),
 880                                        fd.access_flags(),
 881                                        true)) {
 882     ResourceMark rm(THREAD);
 883     Exceptions::fthrow(
 884       THREAD_AND_LOCATION,
 885       vmSymbols::java_lang_IllegalAccessError(),
 886       "tried to access field %s.%s from class %s",
 887       sel_klass->external_name(),
 888       fd.name()->as_C_string(),
 889       ref_klass->external_name()
 890     );
 891     return;
 892   }
 893 }
 894 
 895 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 896   LinkInfo link_info(pool, index, method, CHECK);
 897   resolve_field(fd, link_info, byte, true, CHECK);
 898 }
 899 
 900 void LinkResolver::resolve_field(fieldDescriptor& fd,
 901                                  const LinkInfo& link_info,
 902                                  Bytecodes::Code byte, bool initialize_class,
 903                                  TRAPS) {
 904   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 905          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 906          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 907          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 908 
 909   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 910   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
 911   // Check if there's a resolved klass containing the field
 912   KlassHandle resolved_klass = link_info.resolved_klass();
 913   Symbol* field = link_info.name();
 914   Symbol* sig = link_info.signature();
 915 
 916   if (resolved_klass.is_null()) {


 925     ResourceMark rm(THREAD);
 926     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 927   }
 928 
 929   if (!link_info.check_access())
 930     // Access checking may be turned off when calling from within the VM.
 931     return;
 932 
 933   // check access
 934   KlassHandle current_klass = link_info.current_klass();
 935   check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
 936 
 937   // check for errors
 938   if (is_static != fd.is_static()) {
 939     ResourceMark rm(THREAD);
 940     char msg[200];
 941     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
 942     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 943   }
 944 
 945   // A final field can be modified only
 946   // (1) by methods declared in the class declaring the field and
 947   // (2) by the <clinit> method (in case of a static field)
 948   //     or by the <init> method (in case of an instance field).
 949   if (is_put && fd.access_flags().is_final()) {
 950     ResourceMark rm(THREAD);
 951     stringStream ss;
 952 
 953     if (sel_klass() != current_klass()) {
 954       ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
 955                 is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string(),
 956                 current_klass()->external_name());
 957       THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
 958     }
 959 
 960     if (CheckFinalFieldModifications &&
 961         fd.constants()->pool_holder()->major_version() >= 53) {
 962       methodHandle m = link_info.current_method();
 963       assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes");
 964       bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
 965                                                  fd.is_static() &&
 966                                                  !m()->is_static_initializer());
 967       bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
 968                                                    !fd.is_static() &&
 969                                                    !m->is_object_initializer());
 970 
 971       if (is_initialized_static_final_update || is_initialized_instance_final_update) {
 972         ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
 973                  is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string(),
 974                  current_klass()->external_name(),
 975                  is_static ? "<clinit>" : "<init>");
 976         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
 977       }
 978     }
 979   }
 980 
 981   // initialize resolved_klass if necessary
 982   // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
 983   //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
 984   //
 985   // note 2: we don't want to force initialization if we are just checking
 986   //         if the field access is legal; e.g., during compilation
 987   if (is_static && initialize_class) {
 988     sel_klass->initialize(CHECK);
 989   }
 990 
 991   if (sel_klass() != current_klass()) {
 992     check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
 993   }
 994 
 995   // return information. note that the klass is set to the actual klass containing the
 996   // field, otherwise access of static fields in superclasses will not work.
 997 }
 998 


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