< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

 973                        vmSymbols::java_lang_IllegalAccessError(),
 974                        "%s",
 975                        ss.as_string()
 976                        );
 977     return;
 978   }
 979 }
 980 
 981 void LinkResolver::resolve_field_access(fieldDescriptor& fd,
 982                                         const constantPoolHandle& pool,
 983                                         int index,
 984                                         const methodHandle& method,
 985                                         Bytecodes::Code byte,
 986                                         bool initialize_class, TRAPS) {
 987   LinkInfo link_info(pool, index, method, byte, CHECK);
 988   resolve_field(fd, link_info, byte, initialize_class, CHECK);
 989 }
 990 
 991 void LinkResolver::resolve_field(fieldDescriptor& fd,
 992                                  const LinkInfo& link_info,
 993                                  Bytecodes::Code byte, bool initialize_class,

 994                                  TRAPS) {
 995   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 996          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 997          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 998          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 999 
1000   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
1001   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
1002   // Check if there's a resolved klass containing the field
1003   Klass* resolved_klass = link_info.resolved_klass();
1004   Symbol* field = link_info.name();
1005   Symbol* sig = link_info.signature();
1006 
1007   // Resolve instance field
1008   Klass* sel_klass = resolved_klass->find_field(field, sig, &fd);
1009   // check if field exists; i.e., if a klass containing the field def has been selected
1010   if (sel_klass == nullptr) {
1011     ResourceMark rm(THREAD);
1012     stringStream ss;
1013     ss.print("Class %s does not have member field '", resolved_klass->external_name());

1106 
1107   // The resolved class can change as a result of this resolution.
1108   Klass* resolved_klass = resolved_method->method_holder();
1109 
1110   // Initialize klass (this should only happen if everything is ok)
1111   if (initialize_class && resolved_klass->should_be_initialized()) {
1112     resolved_klass->initialize(CHECK);
1113     // Use updated LinkInfo to reresolve with resolved method holder
1114     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
1115                       link_info.current_klass(),
1116                       link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
1117                       link_info.check_loader_constraints() ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
1118     resolved_method = linktime_resolve_static_method(new_info, CHECK);
1119   }
1120 
1121   // setup result
1122   result.set_static(resolved_klass, methodHandle(THREAD, resolved_method), CHECK);
1123   JFR_ONLY(Jfr::on_resolution(result, CHECK);)
1124 }
1125 




1126 // throws linktime exceptions
1127 Method* LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
1128 
1129   Klass* resolved_klass = link_info.resolved_klass();
1130   Method* resolved_method;
1131   if (!resolved_klass->is_interface()) {
1132     resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1133   } else {
1134     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1135   }
1136   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
1137 
1138   // check if static
1139   if (!resolved_method->is_static()) {
1140     ResourceMark rm(THREAD);
1141     stringStream ss;
1142     ss.print("Expected static method '");
1143     resolved_method->print_external_name(&ss);
1144     ss.print("'");
1145     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string());

1768   LinkInfo link_info(pool, index, Bytecodes::_invokeinterface, CHECK);
1769   Klass* recvrKlass = recv.is_null() ? (Klass*)nullptr : recv->klass();
1770   resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
1771 }
1772 
1773 bool LinkResolver::resolve_previously_linked_invokehandle(CallInfo& result, const LinkInfo& link_info, const constantPoolHandle& pool, int index, TRAPS) {
1774   ResolvedMethodEntry* method_entry = pool->cache()->resolved_method_entry_at(index);
1775   if (method_entry->method() != nullptr) {
1776     Klass* resolved_klass = link_info.resolved_klass();
1777     methodHandle method(THREAD, method_entry->method());
1778     Handle     appendix(THREAD, pool->cache()->appendix_if_resolved(method_entry));
1779     result.set_handle(resolved_klass, method, appendix, CHECK_false);
1780     JFR_ONLY(Jfr::on_resolution(result, CHECK_false);)
1781     return true;
1782   } else {
1783     return false;
1784   }
1785 }
1786 
1787 void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1788 
1789   PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokehandle_time(),
1790                             ClassLoader::perf_resolve_invokehandle_count());

1791 
1792   LinkInfo link_info(pool, index, Bytecodes::_invokehandle, CHECK);




1793   if (log_is_enabled(Info, methodhandles)) {
1794     ResourceMark rm(THREAD);
1795     log_info(methodhandles)("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
1796                             link_info.signature()->as_C_string());
1797   }
1798   { // Check if the call site has been bound already, and short circuit:
1799     bool is_done = resolve_previously_linked_invokehandle(result, link_info, pool, index, CHECK);
1800     if (is_done) return;
1801   }
1802   resolve_handle_call(result, link_info, CHECK);
1803 }
1804 
1805 void LinkResolver::resolve_handle_call(CallInfo& result,
1806                                        const LinkInfo& link_info,
1807                                        TRAPS) {
1808   // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
1809   Klass* resolved_klass = link_info.resolved_klass();
1810   assert(resolved_klass == vmClasses::MethodHandle_klass() ||
1811          resolved_klass == vmClasses::VarHandle_klass(), "");
1812   assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
1813   Handle resolved_appendix;
1814   Method* m = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK);
1815   methodHandle resolved_method(THREAD, m);
1816 
1817   if (link_info.check_access()) {
1818     Symbol* name = link_info.name();
1819     vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
1820     if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
1821       // Check if method can be accessed by the referring class.

1824 
1825       Klass* current_klass = link_info.current_klass();
1826       assert(current_klass != nullptr , "current_klass should not be null");
1827       check_method_accessability(current_klass,
1828                                  resolved_klass,
1829                                  resolved_method->method_holder(),
1830                                  resolved_method,
1831                                  CHECK);
1832     } else {
1833       // Java code is free to arbitrarily link signature-polymorphic invokers.
1834       assert(iid == vmIntrinsics::_invokeGeneric, "not an invoker: %s", vmIntrinsics::name_at(iid));
1835       assert(MethodHandles::is_signature_polymorphic_public_name(resolved_klass, name), "not public");
1836     }
1837   }
1838   result.set_handle(resolved_klass, resolved_method, resolved_appendix, CHECK);
1839   JFR_ONLY(Jfr::on_resolution(result, CHECK);)
1840 }
1841 
1842 void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int indy_index, TRAPS) {
1843   PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokedynamic_time(),
1844                             ClassLoader::perf_resolve_invokedynamic_count());
1845 
1846   int pool_index = pool->resolved_indy_entry_at(indy_index)->constant_pool_index();
1847 
1848   // Resolve the bootstrap specifier (BSM + optional arguments).
1849   BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
1850 
1851   // Check if CallSite has been bound already or failed already, and short circuit:
1852   {
1853     bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(result, CHECK);
1854     if (is_done) return;
1855   }
1856 
1857   // The initial step in Call Site Specifier Resolution is to resolve the symbolic
1858   // reference to a method handle which will be the bootstrap method for a dynamic
1859   // call site.  If resolution for the java.lang.invoke.MethodHandle for the bootstrap
1860   // method fails, then a MethodHandleInError is stored at the corresponding bootstrap
1861   // method's CP index for the CONSTANT_MethodHandle_info.
1862   // Any subsequent invokedynamic instruction which shares
1863   // this bootstrap method will encounter the resolution of MethodHandleInError.
1864 
1865   resolve_dynamic_call(result, bootstrap_specifier, CHECK);

 973                        vmSymbols::java_lang_IllegalAccessError(),
 974                        "%s",
 975                        ss.as_string()
 976                        );
 977     return;
 978   }
 979 }
 980 
 981 void LinkResolver::resolve_field_access(fieldDescriptor& fd,
 982                                         const constantPoolHandle& pool,
 983                                         int index,
 984                                         const methodHandle& method,
 985                                         Bytecodes::Code byte,
 986                                         bool initialize_class, TRAPS) {
 987   LinkInfo link_info(pool, index, method, byte, CHECK);
 988   resolve_field(fd, link_info, byte, initialize_class, CHECK);
 989 }
 990 
 991 void LinkResolver::resolve_field(fieldDescriptor& fd,
 992                                  const LinkInfo& link_info,
 993                                  Bytecodes::Code byte,
 994                                  bool initialize_class,
 995                                  TRAPS) {
 996   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 997          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 998          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 999          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
1000 
1001   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
1002   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
1003   // Check if there's a resolved klass containing the field
1004   Klass* resolved_klass = link_info.resolved_klass();
1005   Symbol* field = link_info.name();
1006   Symbol* sig = link_info.signature();
1007 
1008   // Resolve instance field
1009   Klass* sel_klass = resolved_klass->find_field(field, sig, &fd);
1010   // check if field exists; i.e., if a klass containing the field def has been selected
1011   if (sel_klass == nullptr) {
1012     ResourceMark rm(THREAD);
1013     stringStream ss;
1014     ss.print("Class %s does not have member field '", resolved_klass->external_name());

1107 
1108   // The resolved class can change as a result of this resolution.
1109   Klass* resolved_klass = resolved_method->method_holder();
1110 
1111   // Initialize klass (this should only happen if everything is ok)
1112   if (initialize_class && resolved_klass->should_be_initialized()) {
1113     resolved_klass->initialize(CHECK);
1114     // Use updated LinkInfo to reresolve with resolved method holder
1115     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
1116                       link_info.current_klass(),
1117                       link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
1118                       link_info.check_loader_constraints() ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
1119     resolved_method = linktime_resolve_static_method(new_info, CHECK);
1120   }
1121 
1122   // setup result
1123   result.set_static(resolved_klass, methodHandle(THREAD, resolved_method), CHECK);
1124   JFR_ONLY(Jfr::on_resolution(result, CHECK);)
1125 }
1126 
1127 void LinkResolver::cds_resolve_static_call(CallInfo& result, const LinkInfo& link_info, TRAPS) {
1128   resolve_static_call(result, link_info, /*initialize_class*/false, CHECK);
1129 }
1130 
1131 // throws linktime exceptions
1132 Method* LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
1133 
1134   Klass* resolved_klass = link_info.resolved_klass();
1135   Method* resolved_method;
1136   if (!resolved_klass->is_interface()) {
1137     resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1138   } else {
1139     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1140   }
1141   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
1142 
1143   // check if static
1144   if (!resolved_method->is_static()) {
1145     ResourceMark rm(THREAD);
1146     stringStream ss;
1147     ss.print("Expected static method '");
1148     resolved_method->print_external_name(&ss);
1149     ss.print("'");
1150     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string());

1773   LinkInfo link_info(pool, index, Bytecodes::_invokeinterface, CHECK);
1774   Klass* recvrKlass = recv.is_null() ? (Klass*)nullptr : recv->klass();
1775   resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
1776 }
1777 
1778 bool LinkResolver::resolve_previously_linked_invokehandle(CallInfo& result, const LinkInfo& link_info, const constantPoolHandle& pool, int index, TRAPS) {
1779   ResolvedMethodEntry* method_entry = pool->cache()->resolved_method_entry_at(index);
1780   if (method_entry->method() != nullptr) {
1781     Klass* resolved_klass = link_info.resolved_klass();
1782     methodHandle method(THREAD, method_entry->method());
1783     Handle     appendix(THREAD, pool->cache()->appendix_if_resolved(method_entry));
1784     result.set_handle(resolved_klass, method, appendix, CHECK_false);
1785     JFR_ONLY(Jfr::on_resolution(result, CHECK_false);)
1786     return true;
1787   } else {
1788     return false;
1789   }
1790 }
1791 
1792 void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {

1793   PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokehandle_time(),
1794                             ClassLoader::perf_resolve_invokehandle_count(),
1795                             THREAD->class_being_initialized() == nullptr);
1796 
1797   LinkInfo link_info(pool, index, Bytecodes::_invokehandle, CHECK);
1798   { // Check if the call site has been bound already, and short circuit:
1799     bool is_done = resolve_previously_linked_invokehandle(result, link_info, pool, index, CHECK);
1800     if (is_done) return;
1801   }
1802   if (log_is_enabled(Info, methodhandles)) {
1803     ResourceMark rm(THREAD);
1804     log_info(methodhandles)("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
1805                             link_info.signature()->as_C_string());
1806   }




1807   resolve_handle_call(result, link_info, CHECK);
1808 }
1809 
1810 void LinkResolver::resolve_handle_call(CallInfo& result,
1811                                        const LinkInfo& link_info,
1812                                        TRAPS) {
1813   // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
1814   Klass* resolved_klass = link_info.resolved_klass();
1815   assert(resolved_klass == vmClasses::MethodHandle_klass() ||
1816          resolved_klass == vmClasses::VarHandle_klass(), "");
1817   assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
1818   Handle resolved_appendix;
1819   Method* m = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK);
1820   methodHandle resolved_method(THREAD, m);
1821 
1822   if (link_info.check_access()) {
1823     Symbol* name = link_info.name();
1824     vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
1825     if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
1826       // Check if method can be accessed by the referring class.

1829 
1830       Klass* current_klass = link_info.current_klass();
1831       assert(current_klass != nullptr , "current_klass should not be null");
1832       check_method_accessability(current_klass,
1833                                  resolved_klass,
1834                                  resolved_method->method_holder(),
1835                                  resolved_method,
1836                                  CHECK);
1837     } else {
1838       // Java code is free to arbitrarily link signature-polymorphic invokers.
1839       assert(iid == vmIntrinsics::_invokeGeneric, "not an invoker: %s", vmIntrinsics::name_at(iid));
1840       assert(MethodHandles::is_signature_polymorphic_public_name(resolved_klass, name), "not public");
1841     }
1842   }
1843   result.set_handle(resolved_klass, resolved_method, resolved_appendix, CHECK);
1844   JFR_ONLY(Jfr::on_resolution(result, CHECK);)
1845 }
1846 
1847 void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int indy_index, TRAPS) {
1848   PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokedynamic_time(),
1849                             ClassLoader::perf_resolve_invokedynamic_count(),
1850                             THREAD->class_being_initialized() == nullptr);
1851   int pool_index = pool->resolved_indy_entry_at(indy_index)->constant_pool_index();
1852 
1853   // Resolve the bootstrap specifier (BSM + optional arguments).
1854   BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
1855 
1856   // Check if CallSite has been bound already or failed already, and short circuit:
1857   {
1858     bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(result, CHECK);
1859     if (is_done) return;
1860   }
1861 
1862   // The initial step in Call Site Specifier Resolution is to resolve the symbolic
1863   // reference to a method handle which will be the bootstrap method for a dynamic
1864   // call site.  If resolution for the java.lang.invoke.MethodHandle for the bootstrap
1865   // method fails, then a MethodHandleInError is stored at the corresponding bootstrap
1866   // method's CP index for the CONSTANT_MethodHandle_info.
1867   // Any subsequent invokedynamic instruction which shares
1868   // this bootstrap method will encounter the resolution of MethodHandleInError.
1869 
1870   resolve_dynamic_call(result, bootstrap_specifier, CHECK);
< prev index next >