206 }
207 #endif //ASSERT
208
209 #ifndef PRODUCT
210 void CallInfo::print() {
211 ResourceMark rm;
212 const char* kindstr = "unknown";
213 switch (_call_kind) {
214 case direct_call: kindstr = "direct"; break;
215 case vtable_call: kindstr = "vtable"; break;
216 case itable_call: kindstr = "itable"; break;
217 }
218 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
219 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
220 }
221 #endif
222
223 //------------------------------------------------------------------------------------------------------------------------
224 // Implementation of LinkInfo
225
226 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
227 // resolve klass
228 Klass* result = pool->klass_ref_at(index, CHECK);
229 _resolved_klass = KlassHandle(THREAD, result);
230
231 // Get name, signature, and static klass
232 _name = pool->name_ref_at(index);
233 _signature = pool->signature_ref_at(index);
234 _tag = pool->tag_ref_at(index);
235 _current_klass = KlassHandle(THREAD, pool->pool_holder());
236
237 // Coming from the constant pool always checks access
238 _check_access = true;
239 }
240
241 char* LinkInfo::method_string() const {
242 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
243 }
244
245 #ifndef PRODUCT
246 void LinkInfo::print() {
247 ResourceMark rm;
248 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
249 _resolved_klass->name()->as_C_string(),
250 _name->as_C_string(),
251 _signature->as_C_string(),
252 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
253 _check_access ? "true" : "false");
254 }
255 #endif // PRODUCT
560
561 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
562 const constantPoolHandle& pool, int index, TRAPS) {
563 // This method is used only
564 // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
565 // and
566 // (2) in Bytecode_invoke::static_target
567 // It appears to fail when applied to an invokeinterface call site.
568 // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
569 // resolve klass
570 KlassHandle resolved_klass;
571 if (code == Bytecodes::_invokedynamic) {
572 resolved_klass = SystemDictionary::MethodHandle_klass();
573 Symbol* method_name = vmSymbols::invoke_name();
574 Symbol* method_signature = pool->signature_ref_at(index);
575 KlassHandle current_klass(THREAD, pool->pool_holder());
576 LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
577 return resolve_method(link_info, code, THREAD);
578 }
579
580 LinkInfo link_info(pool, index, CHECK_NULL);
581 resolved_klass = link_info.resolved_klass();
582
583 if (pool->has_preresolution()
584 || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
585 MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
586 Method* result = ConstantPool::method_at_if_loaded(pool, index);
587 if (result != NULL) {
588 return methodHandle(THREAD, result);
589 }
590 }
591
592 if (code == Bytecodes::_invokeinterface) {
593 return resolve_interface_method(link_info, code, THREAD);
594 } else if (code == Bytecodes::_invokevirtual) {
595 return resolve_method(link_info, code, THREAD);
596 } else if (!resolved_klass->is_interface()) {
597 return resolve_method(link_info, code, THREAD);
598 } else {
599 return resolve_interface_method(link_info, code, THREAD);
600 }
858 const fieldDescriptor& fd,
859 TRAPS) {
860 if (!Reflection::verify_field_access(ref_klass(),
861 resolved_klass(),
862 sel_klass(),
863 fd.access_flags(),
864 true)) {
865 ResourceMark rm(THREAD);
866 Exceptions::fthrow(
867 THREAD_AND_LOCATION,
868 vmSymbols::java_lang_IllegalAccessError(),
869 "tried to access field %s.%s from class %s",
870 sel_klass->external_name(),
871 fd.name()->as_C_string(),
872 ref_klass->external_name()
873 );
874 return;
875 }
876 }
877
878 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
879 LinkInfo link_info(pool, index, CHECK);
880 resolve_field(fd, link_info, byte, true, CHECK);
881 }
882
883 void LinkResolver::resolve_field(fieldDescriptor& fd,
884 const LinkInfo& link_info,
885 Bytecodes::Code byte, bool initialize_class,
886 TRAPS) {
887 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
888 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
889 byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
890 (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
891
892 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
893 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
894 // Check if there's a resolved klass containing the field
895 KlassHandle resolved_klass = link_info.resolved_klass();
896 Symbol* field = link_info.name();
897 Symbol* sig = link_info.signature();
898
899 if (resolved_klass.is_null()) {
908 ResourceMark rm(THREAD);
909 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
910 }
911
912 if (!link_info.check_access())
913 // Access checking may be turned off when calling from within the VM.
914 return;
915
916 // check access
917 KlassHandle current_klass = link_info.current_klass();
918 check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
919
920 // check for errors
921 if (is_static != fd.is_static()) {
922 ResourceMark rm(THREAD);
923 char msg[200];
924 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
925 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
926 }
927
928 // Final fields can only be accessed from its own class.
929 if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
930 THROW(vmSymbols::java_lang_IllegalAccessError());
931 }
932
933 // initialize resolved_klass if necessary
934 // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
935 // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
936 //
937 // note 2: we don't want to force initialization if we are just checking
938 // if the field access is legal; e.g., during compilation
939 if (is_static && initialize_class) {
940 sel_klass->initialize(CHECK);
941 }
942
943 if (sel_klass() != current_klass()) {
944 check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
945 }
946
947 // return information. note that the klass is set to the actual klass containing the
948 // field, otherwise access of static fields in superclasses will not work.
949 }
950
|
206 }
207 #endif //ASSERT
208
209 #ifndef PRODUCT
210 void CallInfo::print() {
211 ResourceMark rm;
212 const char* kindstr = "unknown";
213 switch (_call_kind) {
214 case direct_call: kindstr = "direct"; break;
215 case vtable_call: kindstr = "vtable"; break;
216 case itable_call: kindstr = "itable"; break;
217 }
218 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
219 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
220 }
221 #endif
222
223 //------------------------------------------------------------------------------------------------------------------------
224 // Implementation of LinkInfo
225
226 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS) {
227 // resolve klass
228 Klass* result = pool->klass_ref_at(index, CHECK);
229 _resolved_klass = KlassHandle(THREAD, result);
230
231 // Get name, signature, and static klass
232 _name = pool->name_ref_at(index);
233 _signature = pool->signature_ref_at(index);
234 _tag = pool->tag_ref_at(index);
235 _current_klass = KlassHandle(THREAD, pool->pool_holder());
236 _current_method = current_method;
237
238 // Coming from the constant pool always checks access
239 _check_access = true;
240 }
241
242 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
243 // resolve klass
244 Klass* result = pool->klass_ref_at(index, CHECK);
245 _resolved_klass = KlassHandle(THREAD, result);
246
247 // Get name, signature, and static klass
248 _name = pool->name_ref_at(index);
249 _signature = pool->signature_ref_at(index);
250 _tag = pool->tag_ref_at(index);
251 _current_klass = KlassHandle(THREAD, pool->pool_holder());
252 _current_method = methodHandle();
253
254 // Coming from the constant pool always checks access
255 _check_access = true;
256 }
257
258 char* LinkInfo::method_string() const {
259 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
260 }
261
262 #ifndef PRODUCT
263 void LinkInfo::print() {
264 ResourceMark rm;
265 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
266 _resolved_klass->name()->as_C_string(),
267 _name->as_C_string(),
268 _signature->as_C_string(),
269 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
270 _check_access ? "true" : "false");
271 }
272 #endif // PRODUCT
577
578 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
579 const constantPoolHandle& pool, int index, TRAPS) {
580 // This method is used only
581 // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
582 // and
583 // (2) in Bytecode_invoke::static_target
584 // It appears to fail when applied to an invokeinterface call site.
585 // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
586 // resolve klass
587 KlassHandle resolved_klass;
588 if (code == Bytecodes::_invokedynamic) {
589 resolved_klass = SystemDictionary::MethodHandle_klass();
590 Symbol* method_name = vmSymbols::invoke_name();
591 Symbol* method_signature = pool->signature_ref_at(index);
592 KlassHandle current_klass(THREAD, pool->pool_holder());
593 LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
594 return resolve_method(link_info, code, THREAD);
595 }
596
597 LinkInfo link_info(pool, index, methodHandle(), CHECK_NULL);
598 resolved_klass = link_info.resolved_klass();
599
600 if (pool->has_preresolution()
601 || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
602 MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
603 Method* result = ConstantPool::method_at_if_loaded(pool, index);
604 if (result != NULL) {
605 return methodHandle(THREAD, result);
606 }
607 }
608
609 if (code == Bytecodes::_invokeinterface) {
610 return resolve_interface_method(link_info, code, THREAD);
611 } else if (code == Bytecodes::_invokevirtual) {
612 return resolve_method(link_info, code, THREAD);
613 } else if (!resolved_klass->is_interface()) {
614 return resolve_method(link_info, code, THREAD);
615 } else {
616 return resolve_interface_method(link_info, code, THREAD);
617 }
875 const fieldDescriptor& fd,
876 TRAPS) {
877 if (!Reflection::verify_field_access(ref_klass(),
878 resolved_klass(),
879 sel_klass(),
880 fd.access_flags(),
881 true)) {
882 ResourceMark rm(THREAD);
883 Exceptions::fthrow(
884 THREAD_AND_LOCATION,
885 vmSymbols::java_lang_IllegalAccessError(),
886 "tried to access field %s.%s from class %s",
887 sel_klass->external_name(),
888 fd.name()->as_C_string(),
889 ref_klass->external_name()
890 );
891 return;
892 }
893 }
894
895 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
896 LinkInfo link_info(pool, index, method, CHECK);
897 resolve_field(fd, link_info, byte, true, CHECK);
898 }
899
900 void LinkResolver::resolve_field(fieldDescriptor& fd,
901 const LinkInfo& link_info,
902 Bytecodes::Code byte, bool initialize_class,
903 TRAPS) {
904 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
905 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
906 byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
907 (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
908
909 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
910 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
911 // Check if there's a resolved klass containing the field
912 KlassHandle resolved_klass = link_info.resolved_klass();
913 Symbol* field = link_info.name();
914 Symbol* sig = link_info.signature();
915
916 if (resolved_klass.is_null()) {
925 ResourceMark rm(THREAD);
926 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
927 }
928
929 if (!link_info.check_access())
930 // Access checking may be turned off when calling from within the VM.
931 return;
932
933 // check access
934 KlassHandle current_klass = link_info.current_klass();
935 check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
936
937 // check for errors
938 if (is_static != fd.is_static()) {
939 ResourceMark rm(THREAD);
940 char msg[200];
941 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
942 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
943 }
944
945 // A final field can be modified only
946 // (1) by methods declared in the class declaring the field and
947 // (2) by the <clinit> method (in case of a static field)
948 // or by the <init> method (in case of an instance field).
949 if (is_put && fd.access_flags().is_final()) {
950 ResourceMark rm(THREAD);
951 stringStream ss;
952
953 if (sel_klass() != current_klass()) {
954 ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
955 is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string(),
956 current_klass()->external_name());
957 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
958 }
959
960 if (fd.constants()->pool_holder()->major_version() >= 53) {
961 methodHandle m = link_info.current_method();
962 assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes");
963 bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
964 fd.is_static() &&
965 !m()->is_static_initializer());
966 bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
967 !fd.is_static() &&
968 !m->is_object_initializer());
969
970 if (is_initialized_static_final_update || is_initialized_instance_final_update) {
971 ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
972 is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string(),
973 current_klass()->external_name(),
974 is_static ? "<clinit>" : "<init>");
975 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
976 }
977 }
978 }
979
980 // initialize resolved_klass if necessary
981 // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
982 // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
983 //
984 // note 2: we don't want to force initialization if we are just checking
985 // if the field access is legal; e.g., during compilation
986 if (is_static && initialize_class) {
987 sel_klass->initialize(CHECK);
988 }
989
990 if (sel_klass() != current_klass()) {
991 check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
992 }
993
994 // return information. note that the klass is set to the actual klass containing the
995 // field, otherwise access of static fields in superclasses will not work.
996 }
997
|