< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

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

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

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




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

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

1789 
1790   LinkInfo link_info(pool, index, Bytecodes::_invokehandle, CHECK);




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

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

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

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

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

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




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

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