< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

 936     Exceptions::fthrow(THREAD_AND_LOCATION,
 937                        vmSymbols::java_lang_IllegalAccessError(),
 938                        "%s",
 939                        ss.as_string()
 940                        );
 941     return;
 942   }
 943 }
 944 
 945 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 946   LinkInfo link_info(pool, index, method, CHECK);
 947   resolve_field(fd, link_info, byte, true, CHECK);
 948 }
 949 
 950 void LinkResolver::resolve_field(fieldDescriptor& fd,
 951                                  const LinkInfo& link_info,
 952                                  Bytecodes::Code byte, bool initialize_class,
 953                                  TRAPS) {
 954   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 955          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||

 956          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 957          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 958 
 959   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 960   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);

 961   // Check if there's a resolved klass containing the field
 962   Klass* resolved_klass = link_info.resolved_klass();
 963   Symbol* field = link_info.name();
 964   Symbol* sig = link_info.signature();
 965 
 966   if (resolved_klass == NULL) {
 967     ResourceMark rm(THREAD);
 968     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 969   }
 970 














 971   // Resolve instance field
 972   Klass* sel_klass = resolved_klass->find_field(field, sig, &fd);
 973   // check if field exists; i.e., if a klass containing the field def has been selected
 974   if (sel_klass == NULL) {
 975     ResourceMark rm(THREAD);
 976     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 977   }
 978 
 979   // Access checking may be turned off when calling from within the VM.
 980   Klass* current_klass = link_info.current_klass();
 981   if (link_info.check_access()) {
 982 
 983     // check access
 984     check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
 985 
 986     // check for errors
 987     if (is_static != fd.is_static()) {
 988       ResourceMark rm(THREAD);
 989       char msg[200];
 990       jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string());
 991       THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 992     }
 993 
 994     // A final field can be modified only
 995     // (1) by methods declared in the class declaring the field and
 996     // (2) by the <clinit> method (in case of a static field)
 997     //     or by the <init> method (in case of an instance field).


 998     if (is_put && fd.access_flags().is_final()) {
 999 
1000       if (sel_klass != current_klass) {
1001         ResourceMark rm(THREAD);
1002         stringStream ss;
1003         ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
1004                  is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1005                 current_klass->external_name());
1006         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());









1007       }
1008 
1009       if (fd.constants()->pool_holder()->major_version() >= 53) {
1010         Method* m = link_info.current_method();
1011         assert(m != NULL, "information about the current method must be available for 'put' bytecodes");
1012         bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
1013                                                    fd.is_static() &&
1014                                                    !m->is_static_initializer());
1015         bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
1016                                                      !fd.is_static() &&
1017                                                      !m->is_object_initializer());
1018 
1019         if (is_initialized_static_final_update || is_initialized_instance_final_update) {
1020           ResourceMark rm(THREAD);
1021           stringStream ss;
1022           ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
1023                    is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1024                    m->name()->as_C_string(),
1025                    is_static ? "<clinit>" : "<init>");
1026           THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1027         }
1028       }
1029     }
1030 
1031     // initialize resolved_klass if necessary
1032     // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
1033     //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
1034     //
1035     // note 2: we don't want to force initialization if we are just checking
1036     //         if the field access is legal; e.g., during compilation
1037     if (is_static && initialize_class) {

1117 
1118 // throws linktime exceptions
1119 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1120 
1121   // Invokespecial is called for multiple special reasons:
1122   // <init>
1123   // local private method invocation, for classes and interfaces
1124   // superclass.method, which can also resolve to a default method
1125   // and the selected method is recalculated relative to the direct superclass
1126   // superinterface.method, which explicitly does not check shadowing
1127   Klass* resolved_klass = link_info.resolved_klass();
1128   Method* resolved_method = NULL;
1129 
1130   if (!resolved_klass->is_interface()) {
1131     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1132   } else {
1133     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1134   }
1135 
1136   // check if method name is <init>, that it is found in same klass as static type


1137   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1138       resolved_method->method_holder() != resolved_klass) {
1139     ResourceMark rm(THREAD);
1140     stringStream ss;
1141     ss.print("%s: method '", resolved_klass->external_name());
1142     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1143     ss.print(" %s(", resolved_method->name()->as_C_string());
1144     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1145     ss.print(")' not found");
1146     Exceptions::fthrow(
1147       THREAD_AND_LOCATION,
1148       vmSymbols::java_lang_NoSuchMethodError(),
1149       "%s", ss.as_string());
1150     return NULL;
1151   }
1152 
1153   // ensure that invokespecial's interface method reference is in
1154   // a direct superinterface, not an indirect superinterface
1155   Klass* current_klass = link_info.current_klass();
1156   if (current_klass != NULL && resolved_klass->is_interface()) {

1187   }
1188 
1189   return resolved_method;
1190 }
1191 
1192 // throws runtime exceptions
1193 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1194                                                   const LinkInfo& link_info,
1195                                                   const methodHandle& resolved_method,
1196                                                   Handle recv, TRAPS) {
1197 
1198   Klass* resolved_klass = link_info.resolved_klass();
1199 
1200   // resolved method is selected method unless we have an old-style lookup
1201   // for a superclass method
1202   // Invokespecial for a superinterface, resolved method is selected method,
1203   // no checks for shadowing
1204   methodHandle sel_method(THREAD, resolved_method());
1205 
1206   if (link_info.check_access() &&
1207       // check if the method is not <init>
1208       resolved_method->name() != vmSymbols::object_initializer_name()) {
1209 
1210     Klass* current_klass = link_info.current_klass();
1211 
1212     // Check if the class of the resolved_klass is a superclass
1213     // (not supertype in order to exclude interface classes) of the current class.
1214     // This check is not performed for super.invoke for interface methods
1215     // in super interfaces.
1216     if (current_klass->is_subclass_of(resolved_klass) &&
1217         current_klass != resolved_klass) {
1218       // Lookup super method
1219       Klass* super_klass = current_klass->super();
1220       Method* instance_method = lookup_instance_method_in_klasses(super_klass,
1221                                                      resolved_method->name(),
1222                                                      resolved_method->signature(),
1223                                                      Klass::PrivateLookupMode::find);
1224       sel_method = methodHandle(THREAD, instance_method);
1225 
1226       // check if found
1227       if (sel_method.is_null()) {

1606 
1607 
1608 
1609 //------------------------------------------------------------------------------------------------------------------------
1610 // ConstantPool entries
1611 
1612 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1613   switch (byte) {
1614     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1615     case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
1616     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1617     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1618     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1619     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1620     default                         :                                                            break;
1621   }
1622   return;
1623 }
1624 
1625 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1626                              const methodHandle& attached_method,
1627                              Bytecodes::Code byte, TRAPS) {
1628   Klass* defc = attached_method->method_holder();
1629   Symbol* name = attached_method->name();
1630   Symbol* type = attached_method->signature();
1631   LinkInfo link_info(defc, name, type);

1632   switch(byte) {
1633     case Bytecodes::_invokevirtual:
1634       resolve_virtual_call(result, recv, recv->klass(), link_info,
1635                            /*check_null_and_abstract=*/true, CHECK);
1636       break;
1637     case Bytecodes::_invokeinterface:
1638       resolve_interface_call(result, recv, recv->klass(), link_info,
1639                              /*check_null_and_abstract=*/true, CHECK);
1640       break;
1641     case Bytecodes::_invokestatic:
1642       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1643       break;
1644     case Bytecodes::_invokespecial:
1645       resolve_special_call(result, recv, link_info, CHECK);
1646       break;
1647     default:
1648       fatal("bad call: %s", Bytecodes::name(byte));
1649       break;
1650   }
1651 }
1652 
1653 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1654   LinkInfo link_info(pool, index, CHECK);
1655   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1656 }
1657 
1658 
1659 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,

 936     Exceptions::fthrow(THREAD_AND_LOCATION,
 937                        vmSymbols::java_lang_IllegalAccessError(),
 938                        "%s",
 939                        ss.as_string()
 940                        );
 941     return;
 942   }
 943 }
 944 
 945 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 946   LinkInfo link_info(pool, index, method, CHECK);
 947   resolve_field(fd, link_info, byte, true, CHECK);
 948 }
 949 
 950 void LinkResolver::resolve_field(fieldDescriptor& fd,
 951                                  const LinkInfo& link_info,
 952                                  Bytecodes::Code byte, bool initialize_class,
 953                                  TRAPS) {
 954   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 955          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 956          byte == Bytecodes::_withfield ||
 957          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 958          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 959 
 960   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 961   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic ||
 962                     byte == Bytecodes::_nofast_putfield || byte == Bytecodes::_withfield);
 963   // Check if there's a resolved klass containing the field
 964   Klass* resolved_klass = link_info.resolved_klass();
 965   Symbol* field = link_info.name();
 966   Symbol* sig = link_info.signature();
 967 
 968   if (resolved_klass == NULL) {
 969     ResourceMark rm(THREAD);
 970     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 971   }
 972 
 973   if (byte == Bytecodes::_withfield && !resolved_klass->is_inline_klass()) {
 974     ResourceMark rm(THREAD);
 975     char msg[200];
 976     jio_snprintf(msg, sizeof(msg), "Bytecode withfield cannot be used on identity class %s", resolved_klass->external_name());
 977     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 978   }
 979 
 980   if (is_put && !is_static && byte != Bytecodes::_withfield && resolved_klass->is_inline_klass()) {
 981     ResourceMark rm(THREAD);
 982     char msg[200];
 983     jio_snprintf(msg, sizeof(msg), "Bytecode putfield cannot be used on primitive class %s", resolved_klass->external_name());
 984     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
 985   }
 986 
 987   // Resolve instance field
 988   Klass* sel_klass = resolved_klass->find_field(field, sig, &fd);
 989   // check if field exists; i.e., if a klass containing the field def has been selected
 990   if (sel_klass == NULL) {
 991     ResourceMark rm(THREAD);
 992     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 993   }
 994 
 995   // Access checking may be turned off when calling from within the VM.
 996   Klass* current_klass = link_info.current_klass();
 997   if (link_info.check_access()) {
 998 
 999     // check access
1000     check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
1001 
1002     // check for errors
1003     if (is_static != fd.is_static()) {
1004       ResourceMark rm(THREAD);
1005       char msg[200];
1006       jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string());
1007       THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
1008     }
1009 
1010     // A final field can be modified only
1011     // (1) by methods declared in the class declaring the field and
1012     // (2) by the <clinit> method (in case of a static field)
1013     //     or by the <init> method (in case of an instance field).
1014     // (3) by withfield when field is in a value type and the
1015     //     selected class and current class are nest mates.
1016     if (is_put && fd.access_flags().is_final()) {
1017 
1018       if (sel_klass != current_klass) {
1019         // If byte code is a withfield check if they are nestmates.
1020         bool are_nestmates = false;
1021         if (sel_klass->is_instance_klass() &&
1022             InstanceKlass::cast(sel_klass)->is_inline_klass() &&
1023             current_klass->is_instance_klass()) {
1024           are_nestmates = InstanceKlass::cast(current_klass)->has_nestmate_access_to(InstanceKlass::cast(sel_klass), THREAD);
1025         }
1026         if (!are_nestmates) {
1027           ResourceMark rm(THREAD);
1028           stringStream ss;
1029           ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
1030                    is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1031                     current_klass->external_name());
1032           THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1033         }
1034       }
1035 
1036       if (fd.constants()->pool_holder()->major_version() >= 53) {
1037         Method* m = link_info.current_method();
1038         assert(m != NULL, "information about the current method must be available for 'put' bytecodes");
1039         bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
1040                                                    fd.is_static() &&
1041                                                    !m->is_class_initializer());
1042         bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
1043                                                      !fd.is_static() &&
1044                                                      !m->is_object_constructor());
1045 
1046         if (is_initialized_static_final_update || is_initialized_instance_final_update) {
1047           ResourceMark rm(THREAD);
1048           stringStream ss;
1049           ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
1050                    is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
1051                    m->name()->as_C_string(),
1052                    is_static ? "<clinit>" : "<init>");
1053           THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
1054         }
1055       }
1056     }
1057 
1058     // initialize resolved_klass if necessary
1059     // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
1060     //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
1061     //
1062     // note 2: we don't want to force initialization if we are just checking
1063     //         if the field access is legal; e.g., during compilation
1064     if (is_static && initialize_class) {

1144 
1145 // throws linktime exceptions
1146 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) {
1147 
1148   // Invokespecial is called for multiple special reasons:
1149   // <init>
1150   // local private method invocation, for classes and interfaces
1151   // superclass.method, which can also resolve to a default method
1152   // and the selected method is recalculated relative to the direct superclass
1153   // superinterface.method, which explicitly does not check shadowing
1154   Klass* resolved_klass = link_info.resolved_klass();
1155   Method* resolved_method = NULL;
1156 
1157   if (!resolved_klass->is_interface()) {
1158     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1159   } else {
1160     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1161   }
1162 
1163   // check if method name is <init>, that it is found in same klass as static type
1164   // Since this method is never inherited from a super, any appearance here under
1165   // the wrong class would be an error.
1166   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1167       resolved_method->method_holder() != resolved_klass) {
1168     ResourceMark rm(THREAD);
1169     stringStream ss;
1170     ss.print("%s: method '", resolved_klass->external_name());
1171     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1172     ss.print(" %s(", resolved_method->name()->as_C_string());
1173     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1174     ss.print(")' not found");
1175     Exceptions::fthrow(
1176       THREAD_AND_LOCATION,
1177       vmSymbols::java_lang_NoSuchMethodError(),
1178       "%s", ss.as_string());
1179     return NULL;
1180   }
1181 
1182   // ensure that invokespecial's interface method reference is in
1183   // a direct superinterface, not an indirect superinterface
1184   Klass* current_klass = link_info.current_klass();
1185   if (current_klass != NULL && resolved_klass->is_interface()) {

1216   }
1217 
1218   return resolved_method;
1219 }
1220 
1221 // throws runtime exceptions
1222 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1223                                                   const LinkInfo& link_info,
1224                                                   const methodHandle& resolved_method,
1225                                                   Handle recv, TRAPS) {
1226 
1227   Klass* resolved_klass = link_info.resolved_klass();
1228 
1229   // resolved method is selected method unless we have an old-style lookup
1230   // for a superclass method
1231   // Invokespecial for a superinterface, resolved method is selected method,
1232   // no checks for shadowing
1233   methodHandle sel_method(THREAD, resolved_method());
1234 
1235   if (link_info.check_access() &&
1236       // check if the method is not <init>, which is never inherited
1237       resolved_method->name() != vmSymbols::object_initializer_name()) {
1238 
1239     Klass* current_klass = link_info.current_klass();
1240 
1241     // Check if the class of the resolved_klass is a superclass
1242     // (not supertype in order to exclude interface classes) of the current class.
1243     // This check is not performed for super.invoke for interface methods
1244     // in super interfaces.
1245     if (current_klass->is_subclass_of(resolved_klass) &&
1246         current_klass != resolved_klass) {
1247       // Lookup super method
1248       Klass* super_klass = current_klass->super();
1249       Method* instance_method = lookup_instance_method_in_klasses(super_klass,
1250                                                      resolved_method->name(),
1251                                                      resolved_method->signature(),
1252                                                      Klass::PrivateLookupMode::find);
1253       sel_method = methodHandle(THREAD, instance_method);
1254 
1255       // check if found
1256       if (sel_method.is_null()) {

1635 
1636 
1637 
1638 //------------------------------------------------------------------------------------------------------------------------
1639 // ConstantPool entries
1640 
1641 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1642   switch (byte) {
1643     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
1644     case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
1645     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
1646     case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
1647     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
1648     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1649     default                         :                                                            break;
1650   }
1651   return;
1652 }
1653 
1654 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1655                                   const methodHandle& attached_method,
1656                                   Bytecodes::Code byte, bool check_null_and_abstract, TRAPS) {
1657   Klass* defc = attached_method->method_holder();
1658   Symbol* name = attached_method->name();
1659   Symbol* type = attached_method->signature();
1660   LinkInfo link_info(defc, name, type);
1661   Klass* recv_klass = recv.is_null() ? defc : recv->klass();
1662   switch(byte) {
1663     case Bytecodes::_invokevirtual:
1664       resolve_virtual_call(result, recv, recv_klass, link_info,
1665                            check_null_and_abstract, CHECK);
1666       break;
1667     case Bytecodes::_invokeinterface:
1668       resolve_interface_call(result, recv, recv_klass, link_info,
1669                              check_null_and_abstract, CHECK);
1670       break;
1671     case Bytecodes::_invokestatic:
1672       resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1673       break;
1674     case Bytecodes::_invokespecial:
1675       resolve_special_call(result, recv, link_info, CHECK);
1676       break;
1677     default:
1678       fatal("bad call: %s", Bytecodes::name(byte));
1679       break;
1680   }
1681 }
1682 
1683 void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1684   LinkInfo link_info(pool, index, CHECK);
1685   resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
1686 }
1687 
1688 
1689 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,
< prev index next >