< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

 977                        vmSymbols::java_lang_IllegalAccessError(),
 978                        "%s",
 979                        ss.as_string()
 980                        );
 981     return;
 982   }
 983 }
 984 
 985 void LinkResolver::resolve_field_access(fieldDescriptor& fd,
 986                                         const constantPoolHandle& pool,
 987                                         int index,
 988                                         const methodHandle& method,
 989                                         Bytecodes::Code byte,
 990                                         bool initialize_class, TRAPS) {
 991   LinkInfo link_info(pool, index, method, byte, CHECK);
 992   resolve_field(fd, link_info, byte, initialize_class, CHECK);
 993 }
 994 
 995 void LinkResolver::resolve_field(fieldDescriptor& fd,
 996                                  const LinkInfo& link_info,
 997                                  Bytecodes::Code byte, 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 // throws linktime exceptions
1131 Method* LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
1132 
1133   Klass* resolved_klass = link_info.resolved_klass();
1134   Method* resolved_method;
1135   if (!resolved_klass->is_interface()) {
1136     resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1137   } else {
1138     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
1139   }
1140   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
1141 
1142   // check if static
1143   if (!resolved_method->is_static()) {
1144     ResourceMark rm(THREAD);
1145     stringStream ss;
1146     ss.print("Expected static method '");
1147     resolved_method->print_external_name(&ss);
1148     ss.print("'");
1149     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string());

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

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




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

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

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

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

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

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




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

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