< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page
rev 55090 : secret-sfac


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_static_initializer());
1021         bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
1022                                                      !fd.is_static() &&
1023                                                      !m->is_object_initializer());
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   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1142       resolved_method->method_holder() != resolved_klass) {
1143     ResourceMark rm(THREAD);
1144     stringStream ss;
1145     ss.print("%s: method '", resolved_klass->external_name());
1146     resolved_method->signature()->print_as_signature_external_return_type(&ss);
1147     ss.print(" %s(", resolved_method->name()->as_C_string());
1148     resolved_method->signature()->print_as_signature_external_parameters(&ss);
1149     ss.print(")' not found");
1150     Exceptions::fthrow(
1151       THREAD_AND_LOCATION,
1152       vmSymbols::java_lang_NoSuchMethodError(),
1153       "%s", ss.as_string());
1154     return NULL;
1155   }
1156 
1157   // ensure that invokespecial's interface method reference is in
1158   // a direct superinterface, not an indirect superinterface
1159   Klass* current_klass = link_info.current_klass();
1160   if (current_klass != NULL && resolved_klass->is_interface()) {


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




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 >