< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page




 928       fd.name()->as_C_string(),
 929       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 930       (same_module) ? "" : "; ",
 931       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 932     );
 933     return;
 934   }
 935 }
 936 
 937 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 938   LinkInfo link_info(pool, index, method, CHECK);
 939   resolve_field(fd, link_info, byte, true, CHECK);
 940 }
 941 
 942 void LinkResolver::resolve_field(fieldDescriptor& fd,
 943                                  const LinkInfo& link_info,
 944                                  Bytecodes::Code byte, bool initialize_class,
 945                                  TRAPS) {
 946   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 947          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||

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

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


 990     if (is_put && fd.access_flags().is_final()) {
 991       ResourceMark rm(THREAD);
 992       stringStream ss;
 993 
 994       if (sel_klass != current_klass) {









 995         ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
 996                  is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(),
 997                 current_klass->external_name());
 998         THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
 999       }

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


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


1127   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1128       resolved_method->method_holder() != resolved_klass) {
1129     ResourceMark rm(THREAD);
1130     stringStream ss;
1131     ss.print("%s: method '", resolved_klass->external_name());
1132     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1133     ss.print(" %s(", resolved_method->name()->as_C_string());
1134     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1135     ss.print(")' not found");
1136     Exceptions::fthrow(
1137       THREAD_AND_LOCATION,
1138       vmSymbols::java_lang_NoSuchMethodError(),
1139       "%s", ss.as_string());
1140     return NULL;
1141   }
1142 
1143   // ensure that invokespecial's interface method reference is in
1144   // a direct superinterface, not an indirect superinterface
1145   Klass* current_klass = link_info.current_klass();
1146   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       sel_method = lookup_instance_method_in_klasses(super_klass,
1214                                                      resolved_method->name(),
1215                                                      resolved_method->signature(),
1216                                                      Klass::find_private, CHECK);
1217       // check if found
1218       if (sel_method.is_null()) {
1219         ResourceMark rm(THREAD);
1220         stringStream ss;




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


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


1196   }
1197 
1198   return resolved_method;
1199 }
1200 
1201 // throws runtime exceptions
1202 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1203                                                   const LinkInfo& link_info,
1204                                                   const methodHandle& resolved_method,
1205                                                   Handle recv, TRAPS) {
1206 
1207   Klass* resolved_klass = link_info.resolved_klass();
1208 
1209   // resolved method is selected method unless we have an old-style lookup
1210   // for a superclass method
1211   // Invokespecial for a superinterface, resolved method is selected method,
1212   // no checks for shadowing
1213   methodHandle sel_method(THREAD, resolved_method());
1214 
1215   if (link_info.check_access() &&
1216       // check if the method is not <init>, which is never inherited
1217       resolved_method->name() != vmSymbols::object_initializer_name()) {
1218 
1219     Klass* current_klass = link_info.current_klass();
1220 
1221     // Check if the class of the resolved_klass is a superclass
1222     // (not supertype in order to exclude interface classes) of the current class.
1223     // This check is not performed for super.invoke for interface methods
1224     // in super interfaces.
1225     if (current_klass->is_subclass_of(resolved_klass) &&
1226         current_klass != resolved_klass) {
1227       // Lookup super method
1228       Klass* super_klass = current_klass->super();
1229       sel_method = lookup_instance_method_in_klasses(super_klass,
1230                                                      resolved_method->name(),
1231                                                      resolved_method->signature(),
1232                                                      Klass::find_private, CHECK);
1233       // check if found
1234       if (sel_method.is_null()) {
1235         ResourceMark rm(THREAD);
1236         stringStream ss;


< prev index next >