< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

 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());
1014     sig->print_as_field_external_type(&ss);
1015     ss.print(" %s'", field->as_C_string());
1016     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), ss.as_string());
1017   }
1018 
1019   // Access checking may be turned off when calling from within the VM.
1020   Klass* current_klass = link_info.current_klass();
1021   if (link_info.check_access()) {

1024     check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
1025 
1026     // check for errors
1027     if (is_static != fd.is_static()) {
1028       ResourceMark rm(THREAD);
1029       char msg[200];
1030       jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string());
1031       THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
1032     }
1033 
1034     // A final field can be modified only
1035     // (1) by methods declared in the class declaring the field and
1036     // (2) by the <clinit> method (in case of a static field)
1037     //     or by the <init> method (in case of an instance field).
1038     if (is_put && fd.access_flags().is_final()) {
1039 
1040       if (sel_klass != current_klass) {
1041         ResourceMark rm(THREAD);
1042         stringStream ss;
1043         ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
1044                  is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1045                 current_klass->external_name());
1046         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1047       }
1048 
1049       if (fd.constants()->pool_holder()->major_version() >= 53) {
1050         Method* m = link_info.current_method();
1051         assert(m != nullptr, "information about the current method must be available for 'put' bytecodes");
1052         bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
1053                                                    fd.is_static() &&
1054                                                    !m->is_static_initializer());
1055         bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
1056                                                      !fd.is_static() &&
1057                                                      !m->is_object_initializer());
1058 
1059         if (is_initialized_static_final_update || is_initialized_instance_final_update) {
1060           ResourceMark rm(THREAD);
1061           stringStream ss;
1062           ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
1063                    is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1064                    m->name()->as_C_string(),
1065                    is_static ? "<clinit>" : "<init>");
1066           THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1067         }
1068       }
1069     }
1070 
1071     // initialize resolved_klass if necessary
1072     // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
1073     //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
1074     //
1075     // note 2: we don't want to force initialization if we are just checking
1076     //         if the field access is legal; e.g., during compilation
1077     if (is_static && initialize_class) {

1162 
1163 // throws linktime exceptions
1164 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1165 
1166   // Invokespecial is called for multiple special reasons:
1167   // <init>
1168   // local private method invocation, for classes and interfaces
1169   // superclass.method, which can also resolve to a default method
1170   // and the selected method is recalculated relative to the direct superclass
1171   // superinterface.method, which explicitly does not check shadowing
1172   Klass* resolved_klass = link_info.resolved_klass();
1173   Method* resolved_method = nullptr;
1174 
1175   if (!resolved_klass->is_interface()) {
1176     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1177   } else {
1178     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1179   }
1180 
1181   // check if method name is <init>, that it is found in same klass as static type


1182   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1183       resolved_method->method_holder() != resolved_klass) {
1184     ResourceMark rm(THREAD);
1185     stringStream ss;
1186     ss.print("%s: method '", resolved_klass->external_name());
1187     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1188     ss.print(" %s(", resolved_method->name()->as_C_string());
1189     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1190     ss.print(")' not found");
1191     Exceptions::fthrow(
1192       THREAD_AND_LOCATION,
1193       vmSymbols::java_lang_NoSuchMethodError(),
1194       "%s", ss.as_string());
1195     return nullptr;
1196   }
1197 
1198   // ensure that invokespecial's interface method reference is in
1199   // a direct superinterface, not an indirect superinterface
1200   Klass* current_klass = link_info.current_klass();
1201   if (current_klass != nullptr && resolved_klass->is_interface()) {

1233   }
1234 
1235   return resolved_method;
1236 }
1237 
1238 // throws runtime exceptions
1239 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1240                                                   const LinkInfo& link_info,
1241                                                   const methodHandle& resolved_method,
1242                                                   Handle recv, TRAPS) {
1243 
1244   Klass* resolved_klass = link_info.resolved_klass();
1245 
1246   // resolved method is selected method unless we have an old-style lookup
1247   // for a superclass method
1248   // Invokespecial for a superinterface, resolved method is selected method,
1249   // no checks for shadowing
1250   methodHandle sel_method(THREAD, resolved_method());
1251 
1252   if (link_info.check_access() &&
1253       // check if the method is not <init>
1254       resolved_method->name() != vmSymbols::object_initializer_name()) {
1255 
1256     Klass* current_klass = link_info.current_klass();
1257 
1258     // Check if the class of the resolved_klass is a superclass
1259     // (not supertype in order to exclude interface classes) of the current class.
1260     // This check is not performed for super.invoke for interface methods
1261     // in super interfaces.
1262     if (current_klass->is_subclass_of(resolved_klass) &&
1263         current_klass != resolved_klass) {
1264       // Lookup super method
1265       Klass* super_klass = current_klass->super();
1266       Method* instance_method = lookup_instance_method_in_klasses(super_klass,
1267                                                      resolved_method->name(),
1268                                                      resolved_method->signature(),
1269                                                      Klass::PrivateLookupMode::find);
1270       sel_method = methodHandle(THREAD, instance_method);
1271 
1272       // check if found
1273       if (sel_method.is_null()) {

1697 
1698 
1699 
1700 //------------------------------------------------------------------------------------------------------------------------
1701 // ConstantPool entries
1702 
1703 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1704   switch (byte) {
1705     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1706     case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
1707     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1708     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1709     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1710     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1711     default                         :                                                            break;
1712   }
1713   return;
1714 }
1715 
1716 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1717                              const methodHandle& attached_method,
1718                              Bytecodes::Code byte, TRAPS) {
1719   Klass* defc = attached_method->method_holder();
1720   Symbol* name = attached_method->name();
1721   Symbol* type = attached_method->signature();
1722   LinkInfo link_info(defc, name, type);

1723   switch(byte) {
1724     case Bytecodes::_invokevirtual:
1725       resolve_virtual_call(result, recv, recv->klass(), link_info,
1726                            /*check_null_and_abstract=*/true, CHECK);
1727       break;
1728     case Bytecodes::_invokeinterface:
1729       resolve_interface_call(result, recv, recv->klass(), link_info,
1730                              /*check_null_and_abstract=*/true, CHECK);
1731       break;
1732     case Bytecodes::_invokestatic:
1733       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1734       break;
1735     case Bytecodes::_invokespecial:
1736       resolve_special_call(result, recv, link_info, CHECK);
1737       break;
1738     default:
1739       fatal("bad call: %s", Bytecodes::name(byte));
1740       break;
1741   }
1742 }
1743 
1744 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1745   LinkInfo link_info(pool, index, Bytecodes::_invokestatic, CHECK);
1746   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1747 }
1748 
1749 
1750 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,

 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 ||
1002                     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());
1015     sig->print_as_field_external_type(&ss);
1016     ss.print(" %s'", field->as_C_string());
1017     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), ss.as_string());
1018   }
1019 
1020   // Access checking may be turned off when calling from within the VM.
1021   Klass* current_klass = link_info.current_klass();
1022   if (link_info.check_access()) {

1025     check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
1026 
1027     // check for errors
1028     if (is_static != fd.is_static()) {
1029       ResourceMark rm(THREAD);
1030       char msg[200];
1031       jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string());
1032       THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
1033     }
1034 
1035     // A final field can be modified only
1036     // (1) by methods declared in the class declaring the field and
1037     // (2) by the <clinit> method (in case of a static field)
1038     //     or by the <init> method (in case of an instance field).
1039     if (is_put && fd.access_flags().is_final()) {
1040 
1041       if (sel_klass != current_klass) {
1042         ResourceMark rm(THREAD);
1043         stringStream ss;
1044         ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
1045                   is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1046                   current_klass->external_name());
1047         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1048       }
1049 
1050       if (fd.constants()->pool_holder()->major_version() >= 53) {
1051         Method* m = link_info.current_method();
1052         assert(m != nullptr, "information about the current method must be available for 'put' bytecodes");
1053         bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
1054                                                    fd.is_static() &&
1055                                                    !m->is_class_initializer());
1056         bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
1057                                                      !fd.is_static() &&
1058                                                      !m->is_object_constructor());
1059 
1060         if (is_initialized_static_final_update || is_initialized_instance_final_update) {
1061           ResourceMark rm(THREAD);
1062           stringStream ss;
1063           ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
1064                    is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1065                    m->name()->as_C_string(),
1066                    is_static ? "<clinit>" : "<init>");
1067           THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1068         }
1069       }
1070     }
1071 
1072     // initialize resolved_klass if necessary
1073     // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
1074     //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
1075     //
1076     // note 2: we don't want to force initialization if we are just checking
1077     //         if the field access is legal; e.g., during compilation
1078     if (is_static && initialize_class) {

1163 
1164 // throws linktime exceptions
1165 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1166 
1167   // Invokespecial is called for multiple special reasons:
1168   // <init>
1169   // local private method invocation, for classes and interfaces
1170   // superclass.method, which can also resolve to a default method
1171   // and the selected method is recalculated relative to the direct superclass
1172   // superinterface.method, which explicitly does not check shadowing
1173   Klass* resolved_klass = link_info.resolved_klass();
1174   Method* resolved_method = nullptr;
1175 
1176   if (!resolved_klass->is_interface()) {
1177     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1178   } else {
1179     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1180   }
1181 
1182   // check if method name is <init>, that it is found in same klass as static type
1183   // Since this method is never inherited from a super, any appearance here under
1184   // the wrong class would be an error.
1185   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1186       resolved_method->method_holder() != resolved_klass) {
1187     ResourceMark rm(THREAD);
1188     stringStream ss;
1189     ss.print("%s: method '", resolved_klass->external_name());
1190     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1191     ss.print(" %s(", resolved_method->name()->as_C_string());
1192     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1193     ss.print(")' not found");
1194     Exceptions::fthrow(
1195       THREAD_AND_LOCATION,
1196       vmSymbols::java_lang_NoSuchMethodError(),
1197       "%s", ss.as_string());
1198     return nullptr;
1199   }
1200 
1201   // ensure that invokespecial's interface method reference is in
1202   // a direct superinterface, not an indirect superinterface
1203   Klass* current_klass = link_info.current_klass();
1204   if (current_klass != nullptr && resolved_klass->is_interface()) {

1236   }
1237 
1238   return resolved_method;
1239 }
1240 
1241 // throws runtime exceptions
1242 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1243                                                   const LinkInfo& link_info,
1244                                                   const methodHandle& resolved_method,
1245                                                   Handle recv, TRAPS) {
1246 
1247   Klass* resolved_klass = link_info.resolved_klass();
1248 
1249   // resolved method is selected method unless we have an old-style lookup
1250   // for a superclass method
1251   // Invokespecial for a superinterface, resolved method is selected method,
1252   // no checks for shadowing
1253   methodHandle sel_method(THREAD, resolved_method());
1254 
1255   if (link_info.check_access() &&
1256       // check if the method is not <init>, which is never inherited
1257       resolved_method->name() != vmSymbols::object_initializer_name()) {
1258 
1259     Klass* current_klass = link_info.current_klass();
1260 
1261     // Check if the class of the resolved_klass is a superclass
1262     // (not supertype in order to exclude interface classes) of the current class.
1263     // This check is not performed for super.invoke for interface methods
1264     // in super interfaces.
1265     if (current_klass->is_subclass_of(resolved_klass) &&
1266         current_klass != resolved_klass) {
1267       // Lookup super method
1268       Klass* super_klass = current_klass->super();
1269       Method* instance_method = lookup_instance_method_in_klasses(super_klass,
1270                                                      resolved_method->name(),
1271                                                      resolved_method->signature(),
1272                                                      Klass::PrivateLookupMode::find);
1273       sel_method = methodHandle(THREAD, instance_method);
1274 
1275       // check if found
1276       if (sel_method.is_null()) {

1700 
1701 
1702 
1703 //------------------------------------------------------------------------------------------------------------------------
1704 // ConstantPool entries
1705 
1706 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1707   switch (byte) {
1708     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1709     case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
1710     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1711     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1712     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1713     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1714     default                         :                                                            break;
1715   }
1716   return;
1717 }
1718 
1719 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1720                                   const methodHandle& attached_method,
1721                                   Bytecodes::Code byte, bool check_null_and_abstract, TRAPS) {
1722   Klass* defc = attached_method->method_holder();
1723   Symbol* name = attached_method->name();
1724   Symbol* type = attached_method->signature();
1725   LinkInfo link_info(defc, name, type);
1726   Klass* recv_klass = recv.is_null() ? defc : recv->klass();
1727   switch(byte) {
1728     case Bytecodes::_invokevirtual:
1729       resolve_virtual_call(result, recv, recv_klass, link_info,
1730                            check_null_and_abstract, CHECK);
1731       break;
1732     case Bytecodes::_invokeinterface:
1733       resolve_interface_call(result, recv, recv_klass, link_info,
1734                              check_null_and_abstract, CHECK);
1735       break;
1736     case Bytecodes::_invokestatic:
1737       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1738       break;
1739     case Bytecodes::_invokespecial:
1740       resolve_special_call(result, recv, link_info, CHECK);
1741       break;
1742     default:
1743       fatal("bad call: %s", Bytecodes::name(byte));
1744       break;
1745   }
1746 }
1747 
1748 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1749   LinkInfo link_info(pool, index, Bytecodes::_invokestatic, CHECK);
1750   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1751 }
1752 
1753 
1754 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,
< prev index next >