< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page
rev 58760 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: alanb, cjplummer, coleenp, dholmes, dlong, forax, jlahoda, psandoz, plevart, vromero
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com, jan.lahoda@oracle.com, amy.lu@oracle.com


 523         if (!MethodHandles::is_signature_polymorphic_static(iid))  expected_size_of_params += 1;
 524         if (appendix.not_null())                                   expected_size_of_params += 1;
 525         if (actual_size_of_params != expected_size_of_params) {
 526           tty->print_cr("*** basic_signature=%s", basic_signature->as_C_string());
 527           tty->print_cr("*** result for %s: ", vmIntrinsics::name_at(iid));
 528           result->print();
 529         }
 530         assert(actual_size_of_params == expected_size_of_params,
 531                "%d != %d", actual_size_of_params, expected_size_of_params);
 532 #endif //ASSERT
 533 
 534         assert(appendix_result_or_null != NULL, "");
 535         (*appendix_result_or_null) = appendix;
 536       }
 537       return result;
 538     }
 539   }
 540   return NULL;
 541 }
 542 















 543 void LinkResolver::check_method_accessability(Klass* ref_klass,
 544                                               Klass* resolved_klass,
 545                                               Klass* sel_klass,
 546                                               const methodHandle& sel_method,
 547                                               TRAPS) {
 548 
 549   AccessFlags flags = sel_method->access_flags();
 550 
 551   // Special case:  arrays always override "clone". JVMS 2.15.
 552   // If the resolved klass is an array class, and the declaring class
 553   // is java.lang.Object and the method is "clone", set the flags
 554   // to public.
 555   //
 556   // We'll check for the method name first, as that's most likely
 557   // to be false (so we'll short-circuit out of these tests).
 558   if (sel_method->name() == vmSymbols::clone_name() &&
 559       sel_klass == SystemDictionary::Object_klass() &&
 560       resolved_klass->is_array_klass()) {
 561     // We need to change "protected" to "public".
 562     assert(flags.is_protected(), "clone not protected?");
 563     jint new_flags = flags.as_int();
 564     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 565     new_flags = new_flags | JVM_ACC_PUBLIC;
 566     flags.set_flags(new_flags);
 567   }
 568 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 569 
 570   bool can_access = Reflection::verify_member_access(ref_klass,
 571                                                      resolved_klass,
 572                                                      sel_klass,
 573                                                      flags,
 574                                                      true, false, CHECK);
 575   // Any existing exceptions that may have been thrown, for example LinkageErrors
 576   // from nest-host resolution, have been allowed to propagate.
 577   if (!can_access) {
 578     ResourceMark rm(THREAD);

 579     bool same_module = (sel_klass->module() == ref_klass->module());
 580     Exceptions::fthrow(
 581       THREAD_AND_LOCATION,
 582       vmSymbols::java_lang_IllegalAccessError(),
 583       "class %s tried to access %s%s%smethod '%s' (%s%s%s)",
 584       ref_klass->external_name(),
 585       sel_method->is_abstract()  ? "abstract "  : "",
 586       sel_method->is_protected() ? "protected " : "",
 587       sel_method->is_private()   ? "private "   : "",
 588       sel_method->external_name(),
 589       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 590       (same_module) ? "" : "; ",
 591       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 592     );












 593     return;
 594   }
 595 }
 596 
 597 Method* LinkResolver::resolve_method_statically(Bytecodes::Code code,
 598                                                 const constantPoolHandle& pool, int index, TRAPS) {
 599   // This method is used only
 600   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 601   // and
 602   // (2) in Bytecode_invoke::static_target
 603   // It appears to fail when applied to an invokeinterface call site.
 604   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 605   // resolve klass
 606   if (code == Bytecodes::_invokedynamic) {
 607     Klass* resolved_klass = SystemDictionary::MethodHandle_klass();
 608     Symbol* method_name = vmSymbols::invoke_name();
 609     Symbol* method_signature = pool->signature_ref_at(index);
 610     Klass*  current_klass = pool->pool_holder();
 611     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 612     return resolve_method(link_info, code, THREAD);


 891 }
 892 
 893 //------------------------------------------------------------------------------------------------------------------------
 894 // Field resolution
 895 
 896 void LinkResolver::check_field_accessability(Klass* ref_klass,
 897                                              Klass* resolved_klass,
 898                                              Klass* sel_klass,
 899                                              const fieldDescriptor& fd,
 900                                              TRAPS) {
 901   bool can_access = Reflection::verify_member_access(ref_klass,
 902                                                      resolved_klass,
 903                                                      sel_klass,
 904                                                      fd.access_flags(),
 905                                                      true, false, CHECK);
 906   // Any existing exceptions that may have been thrown, for example LinkageErrors
 907   // from nest-host resolution, have been allowed to propagate.
 908   if (!can_access) {
 909     bool same_module = (sel_klass->module() == ref_klass->module());
 910     ResourceMark rm(THREAD);
 911     Exceptions::fthrow(
 912       THREAD_AND_LOCATION,
 913       vmSymbols::java_lang_IllegalAccessError(),
 914       "class %s tried to access %s%sfield %s.%s (%s%s%s)",
 915       ref_klass->external_name(),
 916       fd.is_protected() ? "protected " : "",
 917       fd.is_private()   ? "private "   : "",
 918       sel_klass->external_name(),
 919       fd.name()->as_C_string(),
 920       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 921       (same_module) ? "" : "; ",
 922       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 923     );










 924     return;
 925   }
 926 }
 927 
 928 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 929   LinkInfo link_info(pool, index, method, CHECK);
 930   resolve_field(fd, link_info, byte, true, CHECK);
 931 }
 932 
 933 void LinkResolver::resolve_field(fieldDescriptor& fd,
 934                                  const LinkInfo& link_info,
 935                                  Bytecodes::Code byte, bool initialize_class,
 936                                  TRAPS) {
 937   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 938          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 939          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 940          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 941 
 942   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 943   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);




 523         if (!MethodHandles::is_signature_polymorphic_static(iid))  expected_size_of_params += 1;
 524         if (appendix.not_null())                                   expected_size_of_params += 1;
 525         if (actual_size_of_params != expected_size_of_params) {
 526           tty->print_cr("*** basic_signature=%s", basic_signature->as_C_string());
 527           tty->print_cr("*** result for %s: ", vmIntrinsics::name_at(iid));
 528           result->print();
 529         }
 530         assert(actual_size_of_params == expected_size_of_params,
 531                "%d != %d", actual_size_of_params, expected_size_of_params);
 532 #endif //ASSERT
 533 
 534         assert(appendix_result_or_null != NULL, "");
 535         (*appendix_result_or_null) = appendix;
 536       }
 537       return result;
 538     }
 539   }
 540   return NULL;
 541 }
 542 
 543 static void print_nest_host_error_on(stringStream* ss, Klass* ref_klass, Klass* sel_klass, TRAPS) {
 544   assert(ref_klass->is_instance_klass(), "must be");
 545   assert(sel_klass->is_instance_klass(), "must be");
 546   InstanceKlass* ref_ik = InstanceKlass::cast(ref_klass);
 547   InstanceKlass* sel_ik = InstanceKlass::cast(sel_klass);
 548   const char* nest_host_error_1 = ref_ik->nest_host_error(THREAD);
 549   const char* nest_host_error_2 = sel_ik->nest_host_error(THREAD);
 550   if (nest_host_error_1 != NULL || nest_host_error_2 != NULL) {
 551     ss->print(", (%s%s%s)",
 552               (nest_host_error_1 != NULL) ? nest_host_error_1 : "",
 553               (nest_host_error_1 != NULL && nest_host_error_2 != NULL) ? ", " : "",
 554               (nest_host_error_2 != NULL) ? nest_host_error_2 : "");
 555   }
 556 }
 557 
 558 void LinkResolver::check_method_accessability(Klass* ref_klass,
 559                                               Klass* resolved_klass,
 560                                               Klass* sel_klass,
 561                                               const methodHandle& sel_method,
 562                                               TRAPS) {
 563 
 564   AccessFlags flags = sel_method->access_flags();
 565 
 566   // Special case:  arrays always override "clone". JVMS 2.15.
 567   // If the resolved klass is an array class, and the declaring class
 568   // is java.lang.Object and the method is "clone", set the flags
 569   // to public.
 570   //
 571   // We'll check for the method name first, as that's most likely
 572   // to be false (so we'll short-circuit out of these tests).
 573   if (sel_method->name() == vmSymbols::clone_name() &&
 574       sel_klass == SystemDictionary::Object_klass() &&
 575       resolved_klass->is_array_klass()) {
 576     // We need to change "protected" to "public".
 577     assert(flags.is_protected(), "clone not protected?");
 578     jint new_flags = flags.as_int();
 579     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 580     new_flags = new_flags | JVM_ACC_PUBLIC;
 581     flags.set_flags(new_flags);
 582   }
 583 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 584 
 585   bool can_access = Reflection::verify_member_access(ref_klass,
 586                                                      resolved_klass,
 587                                                      sel_klass,
 588                                                      flags,
 589                                                      true, false, CHECK);
 590   // Any existing exceptions that may have been thrown
 591   // have been allowed to propagate.
 592   if (!can_access) {
 593     ResourceMark rm(THREAD);
 594     stringStream ss;
 595     bool same_module = (sel_klass->module() == ref_klass->module());
 596     ss.print("class %s tried to access %s%s%smethod '%s' (%s%s%s)",



 597              ref_klass->external_name(),
 598              sel_method->is_abstract()  ? "abstract "  : "",
 599              sel_method->is_protected() ? "protected " : "",
 600              sel_method->is_private()   ? "private "   : "",
 601              sel_method->external_name(),
 602              (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 603              (same_module) ? "" : "; ",
 604              (same_module) ? "" : sel_klass->class_in_module_of_loader()
 605              );
 606 
 607     // For private access see if there was a problem with nest host
 608     // resolution, and if so report that as part of the message.
 609     if (sel_method->is_private()) {
 610       print_nest_host_error_on(&ss, ref_klass, sel_klass, THREAD);
 611     }
 612 
 613     Exceptions::fthrow(THREAD_AND_LOCATION,
 614                        vmSymbols::java_lang_IllegalAccessError(),
 615                        "%s",
 616                        ss.as_string()
 617                        );
 618     return;
 619   }
 620 }
 621 
 622 Method* LinkResolver::resolve_method_statically(Bytecodes::Code code,
 623                                                 const constantPoolHandle& pool, int index, TRAPS) {
 624   // This method is used only
 625   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 626   // and
 627   // (2) in Bytecode_invoke::static_target
 628   // It appears to fail when applied to an invokeinterface call site.
 629   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 630   // resolve klass
 631   if (code == Bytecodes::_invokedynamic) {
 632     Klass* resolved_klass = SystemDictionary::MethodHandle_klass();
 633     Symbol* method_name = vmSymbols::invoke_name();
 634     Symbol* method_signature = pool->signature_ref_at(index);
 635     Klass*  current_klass = pool->pool_holder();
 636     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 637     return resolve_method(link_info, code, THREAD);


 916 }
 917 
 918 //------------------------------------------------------------------------------------------------------------------------
 919 // Field resolution
 920 
 921 void LinkResolver::check_field_accessability(Klass* ref_klass,
 922                                              Klass* resolved_klass,
 923                                              Klass* sel_klass,
 924                                              const fieldDescriptor& fd,
 925                                              TRAPS) {
 926   bool can_access = Reflection::verify_member_access(ref_klass,
 927                                                      resolved_klass,
 928                                                      sel_klass,
 929                                                      fd.access_flags(),
 930                                                      true, false, CHECK);
 931   // Any existing exceptions that may have been thrown, for example LinkageErrors
 932   // from nest-host resolution, have been allowed to propagate.
 933   if (!can_access) {
 934     bool same_module = (sel_klass->module() == ref_klass->module());
 935     ResourceMark rm(THREAD);
 936     stringStream ss;
 937     ss.print("class %s tried to access %s%sfield %s.%s (%s%s%s)",


 938              ref_klass->external_name(),
 939              fd.is_protected() ? "protected " : "",
 940              fd.is_private()   ? "private "   : "",
 941              sel_klass->external_name(),
 942              fd.name()->as_C_string(),
 943              (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 944              (same_module) ? "" : "; ",
 945              (same_module) ? "" : sel_klass->class_in_module_of_loader()
 946              );
 947     // For private access see if there was a problem with nest host
 948     // resolution, and if so report that as part of the message.
 949     if (fd.is_private()) {
 950       print_nest_host_error_on(&ss, ref_klass, sel_klass, THREAD);
 951     }
 952     Exceptions::fthrow(THREAD_AND_LOCATION,
 953                        vmSymbols::java_lang_IllegalAccessError(),
 954                        "%s",
 955                        ss.as_string()
 956                        );
 957     return;
 958   }
 959 }
 960 
 961 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 962   LinkInfo link_info(pool, index, method, CHECK);
 963   resolve_field(fd, link_info, byte, true, CHECK);
 964 }
 965 
 966 void LinkResolver::resolve_field(fieldDescriptor& fd,
 967                                  const LinkInfo& link_info,
 968                                  Bytecodes::Code byte, bool initialize_class,
 969                                  TRAPS) {
 970   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 971          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 972          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 973          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 974 
 975   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 976   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);


< prev index next >