< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

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

1177 
1178 // throws linktime exceptions
1179 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1180 
1181   // Invokespecial is called for multiple special reasons:
1182   // <init>
1183   // local private method invocation, for classes and interfaces
1184   // superclass.method, which can also resolve to a default method
1185   // and the selected method is recalculated relative to the direct superclass
1186   // superinterface.method, which explicitly does not check shadowing
1187   Klass* resolved_klass = link_info.resolved_klass();
1188   Method* resolved_method = nullptr;
1189 
1190   if (!resolved_klass->is_interface()) {
1191     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1192   } else {
1193     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1194   }
1195 
1196   // check if method name is <init>, that it is found in same klass as static type


1197   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1198       resolved_method->method_holder() != resolved_klass) {
1199     ResourceMark rm(THREAD);
1200     stringStream ss;
1201     ss.print("%s: method '", resolved_klass->external_name());
1202     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1203     ss.print(" %s(", resolved_method->name()->as_C_string());
1204     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1205     ss.print(")' not found");
1206     // Names are all known to be < 64k so we know this formatted message is not excessively large.
1207     Exceptions::fthrow(
1208       THREAD_AND_LOCATION,
1209       vmSymbols::java_lang_NoSuchMethodError(),
1210       "%s", ss.as_string());
1211     return nullptr;
1212   }
1213 
1214   // ensure that invokespecial's interface method reference is in
1215   // a direct superinterface, not an indirect superinterface or unrelated interface
1216   Klass* current_klass = link_info.current_klass();

1708 
1709 
1710 //------------------------------------------------------------------------------------------------------------------------
1711 // ConstantPool entries
1712 
1713 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, ClassInitMode init_mode, TRAPS) {
1714   switch (byte) {
1715     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, init_mode, CHECK); break;
1716     case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index,            CHECK); break;
1717     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index,            CHECK); break;
1718     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index,            CHECK); break;
1719     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index,            CHECK); break;
1720     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index,            CHECK); break;
1721     default                         :                                                                       break;
1722   }
1723   return;
1724 }
1725 
1726 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1727                                   const methodHandle& attached_method,
1728                                   Bytecodes::Code byte, TRAPS) {
1729   Klass* defc = attached_method->method_holder();
1730   Symbol* name = attached_method->name();
1731   Symbol* type = attached_method->signature();
1732   LinkInfo link_info(defc, name, type);

1733   switch(byte) {
1734     case Bytecodes::_invokevirtual:
1735       resolve_virtual_call(result, recv, recv->klass(), link_info,
1736                            /*check_null_and_abstract=*/true, CHECK);
1737       break;
1738     case Bytecodes::_invokeinterface:
1739       resolve_interface_call(result, recv, recv->klass(), link_info,
1740                              /*check_null_and_abstract=*/true, CHECK);
1741       break;
1742     case Bytecodes::_invokestatic:
1743       resolve_static_call(result, link_info, ClassInitMode::dont_init, CHECK);
1744       break;
1745     case Bytecodes::_invokespecial:
1746       resolve_special_call(result, recv, link_info, CHECK);
1747       break;
1748     default:
1749       fatal("bad call: %s", Bytecodes::name(byte));
1750       break;
1751   }
1752 }
1753 
1754 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, ClassInitMode init_mode, TRAPS) {
1755   LinkInfo link_info(pool, index, Bytecodes::_invokestatic, CHECK);
1756   resolve_static_call(result, link_info, init_mode, CHECK);
1757 }
1758 
1759 
1760 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,

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

1177 
1178 // throws linktime exceptions
1179 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1180 
1181   // Invokespecial is called for multiple special reasons:
1182   // <init>
1183   // local private method invocation, for classes and interfaces
1184   // superclass.method, which can also resolve to a default method
1185   // and the selected method is recalculated relative to the direct superclass
1186   // superinterface.method, which explicitly does not check shadowing
1187   Klass* resolved_klass = link_info.resolved_klass();
1188   Method* resolved_method = nullptr;
1189 
1190   if (!resolved_klass->is_interface()) {
1191     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1192   } else {
1193     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1194   }
1195 
1196   // check if method name is <init>, that it is found in same klass as static type
1197   // Since this method is never inherited from a super, any appearance here under
1198   // the wrong class would be an error.
1199   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1200       resolved_method->method_holder() != resolved_klass) {
1201     ResourceMark rm(THREAD);
1202     stringStream ss;
1203     ss.print("%s: method '", resolved_klass->external_name());
1204     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1205     ss.print(" %s(", resolved_method->name()->as_C_string());
1206     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1207     ss.print(")' not found");
1208     // Names are all known to be < 64k so we know this formatted message is not excessively large.
1209     Exceptions::fthrow(
1210       THREAD_AND_LOCATION,
1211       vmSymbols::java_lang_NoSuchMethodError(),
1212       "%s", ss.as_string());
1213     return nullptr;
1214   }
1215 
1216   // ensure that invokespecial's interface method reference is in
1217   // a direct superinterface, not an indirect superinterface or unrelated interface
1218   Klass* current_klass = link_info.current_klass();

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