< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page

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

 949          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 950          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 951 
 952   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
 953   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);

 954   // Check if there's a resolved klass containing the field
 955   Klass* resolved_klass = link_info.resolved_klass();
 956   Symbol* field = link_info.name();
 957   Symbol* sig = link_info.signature();
 958 
 959   if (resolved_klass == NULL) {
 960     ResourceMark rm(THREAD);
 961     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
 962   }
 963 














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


 991     if (is_put && fd.access_flags().is_final()) {
 992 
 993       if (sel_klass != current_klass) {
 994         ResourceMark rm(THREAD);
 995         stringStream ss;
 996         ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
 997                  is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
 998                 current_klass->external_name());
 999         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());









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

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


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

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

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

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

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

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

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

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